---
title: How to Create a Vector Index
description: Create and configure vector indexes for PostgreSQL vector search.
product: Vector Databases
url: https://docs.digitalocean.com/products/vector-databases/postgresql/how-to/create-vector-index/
last_updated: "2026-07-13"
---

> **For AI agents:** The documentation index is at [https://docs.digitalocean.com/llms.txt](https://docs.digitalocean.com/llms.txt). Markdown versions of pages use the same URL with `index.html.md` in place of the HTML page (for example, append `index.html.md` to the directory path instead of opening the HTML document).

# How to Create a Vector Index

DigitalOcean Managed PostgreSQL for vector search uses the same managed PostgreSQL engine available under Managed Databases, with the pgvector and pgvectorscale extensions for storing and querying vector embeddings alongside relational data.

A vector index is a PostgreSQL index on a `vector` column. PostgreSQL uses the `pgvector` extension to build indexes over vector embeddings so similarity queries can return nearest-neighbor results more quickly.

Before you create a vector index, [create a PostgreSQL vector database cluster and configure its connection details](https://docs.digitalocean.com/products/vector-databases/postgresql/how-to/create/index.html.md).

You also need a table with a `vector` column that matches the number of dimensions your embedding model uses. Common values include 384 for MiniLM, 768 for BERT-family models, 1024 for `bge-large` and `gte-large`, and 1536 for OpenAI `text-embedding-3-small`.

## Create a Vector Index

Create a vector index by connecting to your PostgreSQL cluster from a trusted source. Before you create the index, make sure you have [enabled the `vector` extension and created a table with a vector column](https://docs.digitalocean.com/products/vector-databases/postgresql/how-to/create/index.html.md).

To create a vector index, first go to the [**Vector Databases page**](https://cloud.digitalocean.com/vectordatabases) and select the cluster you want to use.

![Vector Databases overview page listing OpenSearch and PostgreSQL vector database clusters.](https://docs.digitalocean.com/screenshots/databases/vector-databases-overview.066d5347a1c4b8690b3436a2acc17338e90d24ed9fb432884659cb6c04f409e6.png)

Then, go to the **Network Access** tab, find the trusted source you want to connect to, and then open a terminal session.

![Network Access tab showing trusted source entries and an Add Trusted Sources button.](https://docs.digitalocean.com/screenshots/databases/network-access-tab.293ba16d15e569c5997b41f2f6faca01c909e49087e75459983cec0ac7a31582.png)

### Create an HNSW Index

HNSW is the best default index type for most PostgreSQL vector search workloads. It provides high recall and fast queries, but uses more memory and takes longer to build than IVFFlat.

To create an HNSW index, run `CREATE INDEX` on the vector column:

```sql
CREATE INDEX documents_embedding_hnsw
    ON documents
    USING hnsw (embedding vector_cosine_ops)
    WITH (m = 16, ef_construction = 64);
```

This creates an HNSW index named `documents_embedding_hnsw` on the `embedding` column using cosine distance.

Use the operator class that matches your distance operator:

- Use `<=>` with `vector_cosine_ops` for cosine distance.
- Use `<#>` with `vector_ip_ops` for inner product distance.
- Use `<->` with `vector_l2_ops` for L2 distance.

The operator class must match the operator in your `ORDER BY` clause. For example, use `vector_cosine_ops` with `ORDER BY embedding <=> $1`.

After you create the index, [query vectors](https://docs.digitalocean.com/products/vector-databases/postgresql/how-to/use-vector-search/index.html.md#hnsw).

### Create an IVFFlat Index

Use IVFFlat when you need faster index builds or lower memory usage and can accept lower recall.

For IVFFlat, load data into the table before creating the index. IVFFlat uses the data present at build time to choose list centroids.

To create an IVFFlat index, run `CREATE INDEX` with the `ivfflat` index type:

```sql
CREATE INDEX documents_embedding_ivfflat
    ON documents
    USING ivfflat (embedding vector_cosine_ops)
    WITH (lists = 100);
```

This creates an IVFFlat index named `documents_embedding_ivfflat` on the `embedding` column using cosine distance and 100 lists.

Use the same operator-class matching rules as HNSW. For example, use `vector_cosine_ops` with `ORDER BY embedding <=> $1`.

After you create the index, [query vectors](https://docs.digitalocean.com/products/vector-databases/postgresql/how-to/use-vector-search/index.html.md#ivfflat).

### Create a Partial Vector Index

Use a partial index when a specific tenant, category, or segment receives heavy search traffic.

To create a partial vector index, add a `WHERE` clause to the index definition:

```sql
CREATE INDEX documents_tenant_hot_hnsw
    ON documents
    USING hnsw (embedding vector_cosine_ops)
    WHERE tenant_id = '11111111-1111-1111-1111-111111111111';
```

Partial indexes are smaller and faster because PostgreSQL only maintains the index for rows that match the predicate.

Queries must include a matching filter before PostgreSQL can use the partial index. For example:

```sql
SELECT id, content
FROM documents
WHERE tenant_id = '11111111-1111-1111-1111-111111111111'
ORDER BY embedding <=> $1
LIMIT 10;
```

## Verify Vector Index Usage

Use `EXPLAIN (ANALYZE, BUFFERS)` to confirm PostgreSQL uses the vector index:

```sql
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, content
FROM documents
ORDER BY embedding <=> $1
LIMIT 10;
```

If the plan shows a sequential scan, check that:

- The query uses `ORDER BY embedding <operator> $1`.
- The operator matches the index operator class.
- The query includes a `LIMIT`.
- The table has enough rows for PostgreSQL to prefer the index.
- You have run `ANALYZE` after large inserts.

For partial indexes, also check that the query includes the same predicate used in the index definition.

## Change or Rebuild a Vector Index

Some vector index changes require a new index. You can create additional vector indexes on the same column, but you can’t change an existing index from HNSW to IVFFlat or change its operator class in place.

### Add Another Vector Index

If you need to support another distance metric, create a new index with the matching operator class.

For example, if your existing index uses cosine distance but you also need L2 distance, create another index:

```sql
CREATE INDEX documents_embedding_l2_hnsw
    ON documents
    USING hnsw (embedding vector_l2_ops)
    WITH (m = 16, ef_construction = 64);
```

Use the matching distance operator when querying this index:

```sql
SELECT id, content
FROM documents
ORDER BY embedding <-> $1
LIMIT 10;
```

### Rebuild a Vector Index

After large inserts, run `ANALYZE` so PostgreSQL has current table statistics:

```sql
ANALYZE documents;
```

Rebuild the index if you change embedding models, change vector dimensions, or notice degraded recall after major data distribution changes:

```sql
REINDEX INDEX documents_embedding_hnsw;
```

Changing embedding models also requires you to recompute embeddings before rebuilding or recreating indexes.

Vector indexes can use significant memory. If searches become slow because the index no longer fits comfortably in memory, resize the cluster or use a lower-dimensional embedding model.