# pgvector Max Vector Size: Dimension Limits, Index Constraints, and Storage Solutions

The pgvector max vector size establishes strict limits on vector dimensions in PostgreSQL: a ceiling of 16,000 dimensions for unindexed columns and 2,000 dimensions for HNSW and IVFFlat indexes. This constraint breaks high-dimensional embedding models like OpenAI text-embedding-3-large unless teams use dimension truncation, 16-bit halfvec compression, or managed indexing architectures. Understanding these boundaries prevents index failures and preserves fast similarity search.

Source: https://fast.io/resources/pgvector-max-vector-size/
Author: [Derek Labian](https://fast.io/authors/derek-labian/)
Last reviewed: 2026-10-07

## What Are pgvector Dimension Limits and Vector Size Ceilings?

Attempting to build an HNSW or IVFFlat index on a standard PostgreSQL vector column that exceeds 2,000 dimensions halts execution with an immediate error: `ERROR: column cannot have more than 2000 dimensions for hnsw index`. While PostgreSQL permits unindexed vector storage reaching 16,000 dimensions, storing high-dimensional vectors without an index forces the database to perform an exhaustive sequential scan across every row. This behavior makes real-time similarity search impractical for production workloads.

The quotable definition of pgvector max vector size is the hard limit on vector dimensions supported by the PostgreSQL pgvector extension: a ceiling of 16,000 dimensions for unindexed columns and 2,000 dimensions for indexed (HNSW/IVFFlat) columns.

The distinction between raw storage capacity and indexing capacity stems directly from PostgreSQL storage architecture documented in the [official pgvector repository](https://github.com/pgvector/pgvector). The `vector` data type in pgvector stores single-precision, 32-bit IEEE floating-point numbers. In PostgreSQL, table data resides in eight-kilobyte disk pages. When an unindexed table row exceeds the physical page threshold, PostgreSQL uses TOAST (The Oversized-Attribute Storage Technique) to compress and split out-of-line data across secondary storage pages. This out-of-line mechanism allows unindexed columns to accommodate a maximum of 16,000 dimensions, defined by the `VECTOR_MAX_DIM` constant in the pgvector source code.

Index structures cannot rely on TOAST in the same manner. Approximate nearest neighbor (ANN) indexes, such as HNSW (Hierarchical Navigable Small World) and IVFFlat (Inverted File Flat), require vector representations and graph connection pointers to fit directly inside individual index tuple records. Because an individual page contains page headers, item identifiers, and index tuple overhead, pgvector caps indexable 32-bit float vector columns at 2,000 dimensions.

The following table outlines the dimension limits, indexing support, and storage characteristics across all native pgvector data types:

| Data Type | Precision | Max Dimensions (Unindexed) | Max Dimensions (HNSW Index) | Max Dimensions (IVFFlat Index) | Storage Footprint (1,536 dims) |
|---|---|---|---|---|---|
| `vector` | 32-bit float | 16,000 | 2,000 | 2,000 | 6,144 bytes |
| `halfvec` | 16-bit float | 16,000 | 4,000 | 4,000 | 3,072 bytes |
| `bit` | 1-bit binary | 64,000 | 64,000 | 64,000 | 192 bytes |
| `sparsevec` | 32-bit float | 16,000 | 1,000 non-zero | 1,000 non-zero | Variable |

When planning vector storage in PostgreSQL, developers must evaluate whether their target embedding model fits within index boundaries before writing schema migrations.

## Why High-Dimensional Embeddings Break pgvector Indexes

Modern retrieval-augmented generation (RAG) pipelines frequently rely on dense embedding models designed for expressive semantic representations. While older models such as `text-embedding-ada-002` produce 1,536 dimensions, newer models frequently output vectors that exceed the default 2,000-dimension indexing limit of pgvector.

For example, OpenAI's `text-embedding-3-large` outputs 3,072 dimensions by default. Other dense embedding architectures, including certain configurations of E5-mistral and custom fine-tuned transformer encoders, produce embeddings with 2,048, 3,072, or 4,096 dimensions to capture complex semantic relationships across specialized technical corpora.

This creates a silent trap in application development. A developer sets up a PostgreSQL table with a vector column matching the model's native dimension size:

```sql
-- Creating a table for 3,072-dimensional embeddings succeeds:
CREATE TABLE document_embeddings (
    id bigserial PRIMARY KEY,
    document_id text NOT NULL,
    chunk_content text NOT NULL,
    embedding vector(3072)
);
```

The application successfully inserts thousands of document embeddings during ingestion. Because unindexed columns accommodate a maximum of 16,000 dimensions, no errors are raised during the ingestion phase. The failure occurs later, when creating an approximate index to accelerate query speeds:

```sql
-- Creating the HNSW index fails immediately:
CREATE INDEX idx_document_embeddings_hnsw 
ON document_embeddings 
USING hnsw (embedding vector_cosine_ops);
-- ERROR: column cannot have more than 2000 dimensions for hnsw index
```

If an engineering team leaves the column unindexed to bypass this error, similarity queries using `<=>` (cosine distance) or `<->` (Euclidean L2 distance) execute via a full table sequential scan. On a collection of many thousands of chunks, each query reads multiple gigabytes of raw vector floats from disk, consuming entire CPU cores to calculate vector distances one row at a time. Latency climbs from tens of milliseconds to multiple seconds per query, degrading application responsiveness.

## How to Index Embeddings Above 2,000 Dimensions in PostgreSQL

Engineering teams facing the 2,000-dimension ceiling have three distinct options within PostgreSQL to enable fast indexing: dimensionality reduction, half-precision vectors, and binary quantization.

### 1. Dimension Truncation with Matryoshka Embeddings

The most straightforward solution for modern models is dimension truncation. Models trained with Matryoshka Representation Learning (MRL), such as `text-embedding-3-large`, structure vector representations so that the most critical semantic variance resides in the earliest vector coordinates.

Instead of generating 3,072 dimensions and attempting to store them directly, developers can instruct the embedding API to produce a 1,536-dimension or 1,024-dimension vector. In Python with the official OpenAI client:

```python
response = client.embeddings.create(
    model="text-embedding-3-large",
    input="Architecture overview of PostgreSQL vector indexing.",
    dimensions=1536
)
vector_data = response.data[0].embedding
```

Because the output vector contains 1,536 dimensions, it remains well within the 2,000-dimension HNSW threshold while preserving high retrieval accuracy across standard benchmarks.

### 2. Using Half-Precision Vectors with halfvec

If preserving the full 3,072 dimensions is required, pgvector provides the `halfvec` data type. Introduced in pgvector 0.7.0, `halfvec` stores numbers as 16-bit half-precision floats (`FP16`) instead of standard 32-bit floats (`FP32`). 

Half-precision vectors consume half the disk space and memory footprint of standard vectors. More importantly, pgvector raises the HNSW and IVFFlat index cap for `halfvec` from 2,000 dimensions to 4,000 dimensions.

To implement `halfvec`, define the column directly using the `halfvec` type and index it with the corresponding operator class:

```sql
-- Define table with half-precision vectors
CREATE TABLE document_chunks (
    id bigserial PRIMARY KEY,
    content text NOT NULL,
    embedding halfvec(3072)
);

-- Build an HNSW index using halfvec cosine operator class
CREATE INDEX idx_document_chunks_hnsw 
ON document_chunks 
USING hnsw (embedding halfvec_cosine_ops);
```

Developers with an existing table storing `vector(3072)` can create an index by casting the column expression without modifying the underlying table schema:

```sql
-- Build index with an on-the-fly cast to halfvec
CREATE INDEX idx_document_embeddings_halfvec 
ON document_embeddings 
USING hnsw ((embedding::halfvec(3072)) halfvec_cosine_ops);
```

### 3. Binary Quantization with bit

For massive corpora where memory constraints are paramount, binary quantization converts floating-point dimensions into 1-bit values based on whether the coordinate is greater than zero. pgvector supports binary vectors via the `bit` data type reaching 64,000 dimensions.

Binary quantization drastically reduces index size, allowing millions of vectors to fit into system memory. Because bit vectors use Hamming distance (`bit_hamming_ops`) or Jaccard distance (`bit_jaccard_ops`), binary indexes often serve as a preliminary filter before reranking top candidates with higher-precision vectors.

## Index Tradeoffs: HNSW vs IVFFlat for High-Dimensional Vectors

Choosing between HNSW and IVFFlat indexes in pgvector requires balancing memory allocation, index build duration, and query latency, especially when handling vectors near dimension ceilings.

### HNSW Performance and Memory Requirements

HNSW constructs a multi-layer proximity graph where each node connects to adjacent vectors. It provides excellent search speed and recall because queries traverse graph edges toward the nearest cluster rather than scanning flat lists.

However, HNSW demands significant system memory during both index construction and query execution. Index creation speed depends on keeping the dynamic construction graph inside `maintenance_work_mem`. If `maintenance_work_mem` is too small, PostgreSQL writes intermediate graph structures to temporary disk files, increasing build times.

Before building an HNSW index on a large dataset with 1,536 or 3,072 dimensions, tune the memory parameters in your session:

```sql
-- Allocate sufficient maintenance memory for graph construction
SET maintenance_work_mem = '8GB';

-- Increase maintenance workers for parallel indexing
SET max_parallel_maintenance_workers = 4;

-- Build index with explicit graph parameters
CREATE INDEX idx_chunks_hnsw_perf 
ON document_chunks 
USING hnsw (embedding halfvec_cosine_ops) 
WITH (m = 16, ef_construction = 64);
```

In this configuration, `m` sets the maximum number of bidirectional connection links per vector (default is 16), while `ef_construction` controls the size of the dynamic candidate list evaluated during graph construction (default is 64). Higher values improve search recall but increase memory consumption and build duration.

At query time, adjust `hnsw.ef_search` to balance throughput and accuracy:

```sql
-- Set search candidate list size for the current session
SET hnsw.ef_search = 100;

SELECT id, content 
FROM document_chunks 
ORDER BY embedding <=> '[0.012, -0.045, ...]'::halfvec(3072) 
LIMIT 10;
```

### IVFFlat Partitioning and Probe Tradeoffs

IVFFlat divides vector space into Voronoi cells using k-means clustering. Unlike HNSW, IVFFlat requires an initial population of vectors to calculate centroid clusters during index creation.

IVFFlat indexes build faster and occupy less disk space than HNSW graphs. However, query performance degrades when vectors have thousands of dimensions because high-dimensional spaces suffer from the curse of dimensionality, where distance metrics become less distinct across cluster boundaries.

```sql
-- Build IVFFlat index with 1,000 centroid lists
CREATE INDEX idx_chunks_ivfflat 
ON document_chunks 
USING ivfflat (embedding halfvec_cosine_ops) 
WITH (lists = 1000);

-- Increase probes at query time to improve recall
SET ivfflat.probes = 10;
```

Setting `ivfflat.probes` higher evaluates more lists per query, improving search recall at the expense of query latency. If `ivfflat.probes` equals the total number of lists, PostgreSQL performs an exact sequential scan, bypassing index acceleration entirely.

## How Managed Workspaces Replace Manual Vector Infrastructure

Engineering teams frequently select pgvector because PostgreSQL is already familiar and integrated into their application stack. As document corpora expand, maintaining self-hosted vector infrastructure introduces ongoing operational complexity.

Teams must configure dedicated database servers, calculate page memory allocations, monitor index bloat, handle schema migrations when embedding models change, and manage the complex pipeline required to extract text, generate chunked embeddings, and insert vector records.

Architecturally, teams evaluating retrieval systems face three main pathways:

1. **Self-Hosted PostgreSQL with pgvector:** Provides direct SQL access and transactional integrity. However, developers must manage dimension limits, tune HNSW memory settings, manage chunking pipelines manually, and scale database hardware to keep index graphs resident in RAM.
2. **Standalone Vector Databases:** Dedicated engines such as Pinecone, Qdrant, or Milvus handle high-dimensional vectors natively. However, they introduce separate infrastructure silos, requiring custom sync scripts to mirror files and metadata between primary object storage and the vector database.
3. **Intelligent Workspaces with Native Retrieval:** Combines file storage, document processing, and vector search into a unified workspace.

[Fast.io workspaces](/product/workspaces/) provide an intelligent workspace platform designed for teams and autonomous AI agents. Rather than requiring developers to configure database extensions, tune `maintenance_work_mem`, or resolve vector dimension caps, Fast.io includes [Intelligence Mode](/product/ai/) directly in the workspace.

When Intelligence Mode is enabled on a Fast.io workspace, uploaded documents (including PDFs, Office documents, presentations, and plain text files) are automatically indexed for hybrid search, combining full-text search and semantic understanding. Content in [Fast.io AI storage](/product/ai-storage/) is searchable immediately without running custom embedding workers or managing PostgreSQL index limits.

AI agents and client applications connect directly to Fast.io workspaces through the Model Context Protocol (MCP) using Streamable HTTP:

* For Claude and general agent runtimes, connect to `https://mcp.fast.io/mcp/tools`.
* For coding agents such as Claude Code, Cursor, and VS Code, connect to `https://mcp.fast.io/mcp/code`.

Fast.io workspaces also provide granular access controls, a detailed activity log, and per-file version history, allowing people and agents to collaborate on shared knowledge bases safely. Monthly plans start with a 14-day free trial that requires a credit card. Review complete plan details and tier specifications on the [Fast.io pricing](/pricing/) page.

## Troubleshooting pgvector Dimension and Index Errors

When operating pgvector in production, developers frequently encounter dimension mismatches, index failures, and performance bottlenecks. The following procedures resolve the most common issues:

### 1. Resolving the 2,000-Dimension HNSW Index Failure

**Symptom:**
`ERROR: column cannot have more than 2000 dimensions for hnsw index`

**Resolution:**
This error occurs when attempting to create an HNSW index on a 32-bit `vector` column exceeding 2,000 dimensions. If using an embedding model like `text-embedding-3-large` (3,072 dimensions), convert the column or index to `halfvec(3072)` using `halfvec_cosine_ops`, or configure your embedding API client to truncate dimensions to 1,536 using Matryoshka representation learning before inserting vectors.

### 2. Resolving Memory Warnings During Graph Construction

**Symptom:**
`NOTICE: hnsw graph no longer fits into maintenance_work_mem after 100000 tuples`

**Resolution:**
This notice indicates that the HNSW graph has exceeded allocated construction memory, causing PostgreSQL to spill graph nodes to disk. While index creation completes, build time increases substantially. Increase the session memory before executing `CREATE INDEX`:

```sql
SET maintenance_work_mem = '4GB';
SET max_parallel_maintenance_workers = 4;
```

Ensure that `maintenance_work_mem` does not exceed available system RAM, especially when multiple maintenance workers run concurrently.

### 3. Fixing Vector Dimension Mismatch on Insertion

**Symptom:**
`ERROR: different vector dimensions 1536 and 3072`

**Resolution:**
PostgreSQL enforces strict dimension consistency. This error occurs when the vector payload provided in an `INSERT` statement has a different coordinate count than the column definition. Inspect your embedding generation pipeline to confirm that all ingestion workers use identical model parameters and dimension settings.

### 4. Diagnosing Silent Sequential Scans

**Symptom:**
Queries execute with high latency despite the presence of an HNSW or IVFFlat index.

**Resolution:**
PostgreSQL query planner will bypass an ANN index if the query operator does not match the index operator class. Verify your query syntax:

* For cosine distance (`vector_cosine_ops` or `halfvec_cosine_ops`), use `<=>`.
* For Euclidean distance (`vector_l2_ops` or `halfvec_l2_ops`), use `<->`.
* For inner product (`vector_ip_ops` or `halfvec_ip_ops`), use `<#>`.

Additionally, ensure the query includes an `ORDER BY` clause using the appropriate distance operator alongside a `LIMIT` clause. Without `LIMIT`, the planner assumes all rows must be sorted and defaults to a sequential scan. Inspect query execution plans with `EXPLAIN ANALYZE` to verify index scan usage.

## Frequently asked questions

### What is the maximum dimension size in pgvector?

The maximum dimension size in pgvector depends on the data type and whether an index is applied. For unindexed columns, the standard vector type supports a maximum of 16,000 dimensions. For indexed columns using HNSW or IVFFlat, the standard 32-bit vector type is capped at 2,000 dimensions, while the 16-bit halfvec type accommodates 4,000 dimensions. Binary bit vectors accommodate 64,000 dimensions.

### Can pgvector index 3072 dimension embeddings?

Yes, pgvector can index 3,072-dimension embeddings by using the halfvec data type instead of standard vector. The halfvec type uses 16-bit floating-point numbers, raising the HNSW and IVFFlat index ceiling to 4,000 dimensions. Alternatively, developers can truncate embeddings from models like text-embedding-3-large to 1,536 dimensions using Matryoshka representation learning.

### What is the difference between vector and halfvec limits in pgvector?

The vector type stores 32-bit single-precision floats, capping HNSW and IVFFlat indexes at 2,000 dimensions with roughly 6 KB of storage per 1,536-dimension vector. The halfvec type stores 16-bit half-precision floats, cutting storage and memory requirements in half while doubling the index ceiling to 4,000 dimensions. Both types accommodate 16,000 dimensions in unindexed table columns.

### Why does pgvector cap HNSW indexes at 2,000 dimensions?

pgvector caps standard HNSW indexes at 2,000 dimensions due to PostgreSQL page size constraints. PostgreSQL stores data in eight-kilobyte disk pages. Unlike table rows, which can split wide columns across secondary pages using TOAST, HNSW index tuples must fit within a single index page along with graph connection links and page metadata.

### How does Fast.io handle document indexing compared to self-managed pgvector?

Fast.io workspaces manage vector search automatically through Intelligence Mode. Instead of requiring manual schema definitions, dimension tuning, and PostgreSQL memory configuration, Fast.io automatically extracts text, chunks content, and builds hybrid search indexes for uploaded documents. Applications and agents can query the workspace directly via the Model Context Protocol without managing database infrastructure.

## Sources

- [pgvector: Open-source vector similarity search for Postgres](https://github.com/pgvector/pgvector): pgvector performs exact nearest neighbor search by default and provides approximate nearest neighbor indexing with HNSW and IVFFlat capped at 2,000 dimensions for vector columns.

## About Fast.io

Fast.io provides shared workspaces where people and AI agents work on the same files, with built-in semantic search and citation-backed chat over what they hold. Agents reach it through a remote MCP server, a REST API at https://api.fast.io/current/, and a command line client published on npm as @vividengine/fastio-cli. MCP setup is at https://mcp.fast.io/docs: Claude and most MCP clients connect to https://mcp.fast.io/mcp/tools, ChatGPT to https://mcp.fast.io/mcp/operations, and coding agents to https://mcp.fast.io/mcp/code.
