Skip to main content
友田 陽大
Generative AI, LLMs & RAG
PostgreSQL
RAG
Supabase
AWS
パフォーマンス

Getting started with pgvector: from installation to your first vector search (Docker, Supabase, AWS RDS/Aurora, Neon, Cloud SQL, Azure)

A getting-started guide to pgvector for beginning vector search in PostgreSQL. With real code faithful to the official documentation, it explains in the shortest path the enable procedure on each of Docker, Supabase, AWS RDS/Aurora, Neon, Google Cloud SQL/AlloyDB, and Azure, the permissions and common errors of `CREATE EXTENSION vector`, and your first table creation, INSERT, distance operators, kNN search, and HNSW index.

Published
Reading time
10 min read
Author
友田 陽大
Share

"I want to do vector search (semantic search) in PostgreSQL" — the entrance to that is pgvector. Without adding a dedicated vector DB, just add one vector type to the Postgres you already use, and you can store AI embedding vectors and search them "in order of closest meaning."

This article is a getting-started guide to take that first stepenabling it on each platform and your first vector search — in the shortest path. "The overall RAG design" and "index tuning" are left to other articles; this article guides you up to "getting it running," faithful to the official documentation and crushing the stumble points.

Rules for this article: extension names, SQL syntax, and each platform's enable procedure are based on the pgvector official README and each cloud's official documentation (as of June 2026). A managed service's pgvector version is tied to the engine's minor and lags behind upstream. Before use, always check pg_available_extensions on your instance. This article's versions and procedures may change.


1. Understand pgvector in 30 seconds

pgvector is a PostgreSQL extension. Enable it and the following three become usable.

  1. The vector type: a column type to store embedding vectors (numeric arrays like [0.1, -0.3, ...]).
  2. Distance operators: operators that measure "closeness" between vectors, such as <=> (cosine distance).
  3. ANN indexes: HNSW / IVFFlat. Approximate-nearest-neighbor indexes that return neighbors fast even at millions of rows.

The most important caution first. The extension's name is vector (not pgvector). pgvector is the project name. When enabling in SQL, always write it like this on any platform.

CREATE EXTENSION vector;        -- ✅ 正しい(拡張名は vector)
-- CREATE EXTENSION pgvector;   -- ❌ これは存在しないのでエラーになる

2. Per platform: enable pgvector

"Run CREATE EXTENSION vector;" is common, but its prerequisites (installing the binary / allow-list / permissions) differ by platform. Reading only your environment's section is enough.

Docker / self-host

The shortest is the official Docker image. The image name is pgvector/pgvector, and the tag is the form "Postgres major + Debian base" (e.g., pg17).

# 公式イメージ(pgvector がプリインストール済みの Postgres)
docker pull pgvector/pgvector:pg17
docker run -d --name pg -e POSTGRES_PASSWORD="$PGPASSWORD" -p 5432:5432 pgvector/pgvector:pg17

To install into existing Postgres from source (pg_config must be on PATH):

cd /tmp
git clone --branch v0.8.3 https://github.com/pgvector/pgvector.git
cd pgvector && make && sudo make install

It also installs via OS packages (NN is the Postgres major).

sudo apt install postgresql-17-pgvector     # Debian/Ubuntu(PGDG apt)
sudo dnf install pgvector_17                 # RHEL/Fedora(PGDG yum)
brew install pgvector                        # macOS

Finally, run once on the target database.

CREATE EXTENSION vector;

Supabase

In the dashboard's Database → Extensions, search "vector" and turn the toggle ON, or run it in the SQL editor. By Supabase convention, put it in the extensions schema.

create extension vector with schema extensions;

AWS RDS for PostgreSQL / Aurora PostgreSQL

pgvector is provided as a trusted extension of RDS / Aurora. The binary is already installed, so you just enable it.

-- まず使えるバージョンを確認(マネージドは本家より遅れることがある)
SELECT * FROM pg_available_extensions WHERE name = 'vector';

CREATE EXTENSION IF NOT EXISTS vector;
  • Permissions: on PostgreSQL 13 or later, if you have CREATE privilege on the database you can install a trusted extension even without being rds_superuser (12 or earlier needs rds_superuser).
  • To use an HNSW index, pgvector 0.5.0 or later is required. Older minors may not support it, so check with the pg_available_extensions above.

Neon

Available on all plans. No extra configuration or special privilege needed.

CREATE EXTENSION IF NOT EXISTS vector;
-- 一つ前のバージョンに固定したいとき
-- CREATE EXTENSION vector VERSION '0.7.4';

Google Cloud SQL for PostgreSQL / AlloyDB

Cloud SQL enables without flags. It can be created by members of the cloudsqlsuperuser role (the default postgres user holds it).

CREATE EXTENSION vector;                  -- 名前は vector(pgvector ではない)

AlloyDB can use, in addition to pgvector, Google's own ScaNN index. With CASCADE, vector is installed at the same time.

CREATE EXTENSION IF NOT EXISTS alloydb_scann CASCADE;  -- alloydb_scann + vector

Azure Database for PostgreSQL — Flexible Server

Only Azure is two-step. First register in the allow-list (azure.extensions), then CREATE EXTENSION. In the allow-list too, the name is vector.

# 1) サーバーパラメータ azure.extensions に VECTOR を許可(CLIの例)
az postgres flexible-server parameter set \
  --resource-group <rg> --server-name <server> \
  --name azure.extensions --value vector
-- 2) 対象DBで有効化(権限: azure_pg_admin)
CREATE EXTENSION vector;

Quick reference: enable command and required privilege

PlatformPrepEnableRequired privilege
Docker / self-hostimage or make installCREATE EXTENSION vector;superuser
Supabase(preinstalled)create extension vector with schema extensions;(UI/SQL)
RDS / Aurora(preinstalled, trusted)CREATE EXTENSION vector;CREATE on DB (PG13+) / rds_superuser (PG≤12)
NeonnoneCREATE EXTENSION vector;no special privilege
Cloud SQL / AlloyDB(preinstalled)CREATE EXTENSION vector;cloudsqlsuperuser
Azure Flexible Serverregister in azure.extensionsCREATE EXTENSION vector;azure_pg_admin

3. Verification and common errors

Whether it enabled can be checked with the same SQL in any environment.

SELECT extversion FROM pg_extension WHERE extname = 'vector';   -- 入っていればバージョンが返る
SELECT * FROM pg_available_extensions WHERE name = 'vector';    -- 入れられるバージョン

In psql, list with \dx and details with \dx vector. Most stumbles are the following two. Know the meaning and you can isolate them instantly.

ErrorWhat it really meansRemedy
could not open extension control file ".../vector.control": No such file or directorythe binary isn't installed (not a permission problem)use make install / the package for the correct PG major / a Docker image with pgvector
permission denied to create extension "vector"insufficient role privilegegrant superuser / rds_superuser / cloudsqlsuperuser / azure_pg_admin, or CREATE privilege on the DB
extension "vector" is not allow-listed for "azure.extensions" settingon Azure, not registered in the allow-listadd vector to azure.extensions and rerun

Once enabled, finally the search. Go through the minimal flow of create table → insert → kNN search.

-- 1) 埋め込みを格納するテーブル。vector(3) の 3 は次元数(実際は埋め込みモデルの出力次元に合わせる)
CREATE TABLE items (
    id        bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    content   text NOT NULL,
    embedding vector(3) NOT NULL
);

-- 2) 投入。ベクトルは '[...]' のテキストリテラルで渡す
INSERT INTO items (content, embedding) VALUES
    ('りんご', '[1, 2, 3]'),
    ('みかん', '[1, 2, 4]'),
    ('自動車', '[9, 8, 1]');

-- 3) クエリベクトルに「意味が近い順」で上位2件(kNN検索)
SELECT id, content, embedding <=> '[1, 2, 3]' AS distance
FROM items
ORDER BY embedding <=> '[1, 2, 3]'   -- 小さいほど近い
LIMIT 2;

Distance operators: choose by use

How to measure vector "closeness" is chosen by operator. The iron rule is to match the distance the embedding model assumes.

OperatorDistanceMain use
<=>cosine distancethe standard for text embeddings (measures meaning by direction)
<->L2 (Euclidean) distancegeneral unnormalized vectors
<#>negative inner productinner-product-based models
<+>L1 (Manhattan) distanceL1 space
<~> / <%>Hamming / Jaccard distancebit type (binary vectors)

For text embeddings like OpenAI's text-embedding-3-*, choosing <=> (cosine distance) first is foolproof.

What about real data?: the '[1,2,3]' above is a hand-written vector for explanation. In reality you INSERT a several-hundred-to-thousand-dimensional vector obtained by passing text to an embedding model (OpenAI, Cohere, your own model, etc.). How to pass it from the app side is handled in detail in the type-safe implementation with TypeScript × Drizzle.


5. The four vector types and the dimension cap

pgvector has four types by use. Start with vector and consider others when needed is enough (YAGNI).

TypeSize per elementIndexable dimensionsWhere to use
vector(n)4 bytes (float32)up to 2,000standard. this first
halfvec(n)2 bytes (float16)up to 4,000half the memory, high dimensions
bit(n)1 bitup to 64,000binary quantization (Hamming distance)
sparsevec(n)stores only non-zeroup to 16,000 non-zerosparse representation (SPLADE, etc.)

The n of vector(n) must match the embedding model's output dimensions (a mismatch is a dimension-mismatch error on INSERT = the benefit of being protected by the type). OpenAI's text-embedding-3-large is 3072 dimensions, but it can be shortened with the dimensions parameter, and in my projects I operate at 1024 dimensions (the reason is detailed in the RAG-design article).


6. Your first index (HNSW)

For a few rows, a full scan is enough, but at millions of rows the full scan every time breaks down. So add an approximate-nearest-neighbor (ANN) index. When in doubt, HNSW (strong for continuous additions and can be created in advance on an empty table).

-- コサイン距離で検索するなら vector_cosine_ops(距離演算子と演算子クラスを必ず揃える)
CREATE INDEX ON items USING hnsw (embedding vector_cosine_ops);

-- 検索精度↔速度は、インデックス再構築なしでランタイムに調整できる
SET hnsw.ef_search = 100;   -- 既定40。大きいほど高再現率・低速

Whether the index is working is confirmed with EXPLAIN (OK if Index Scan using ..._hnsw_... appears).

EXPLAIN ANALYZE
SELECT id FROM items ORDER BY embedding <=> '[1,2,3]' LIMIT 5;

Important: the index works only for the form "ORDER BY embedding <operator> ... LIMIT k." The meaning of parameters like m / ef_construction / ef_search, how to choose between HNSW and IVFFlat, and how to measure recall are systematized in the dedicated article the complete pgvector tuning guide.


After "it ran," digging in this order by purpose is the shortest.


Conclusion: the shortest checklist

  • The extension name is vector. Enabling is the one line CREATE EXTENSION vector; in any environment.
  • The platform difference is only the "prerequisite": for Docker, the official image pgvector/pgvector:pg17; only Azure needs azure.extensions permission first. Check the managed version with pg_available_extensions.
  • Errors are two lines: control file not found = binary not installed; permission denied = insufficient privilege.
  • The first search: a vector(n) column → INSERT '[...]'ORDER BY embedding <=> $1 LIMIT k. Text uses <=>.
  • Add HNSW once it scales: USING hnsw (embedding vector_cosine_ops), tune accuracy with hnsw.ef_search.

The goodness of pgvector is that you can begin vector search inside the PostgreSQL you already use, with the SQL, permissions, and backups you're used to. In the generative-AI voice chatbot, I consolidated business data and embeddings into pgvector on RDS without adding a dedicated vector DB, and carried production RAG through design, implementation, and operation with one person × generative AI (Claude Code).

"I want to start AI semantic search on my own company's data but don't know where and how to host it" — I can accompany you end-to-end from that entrance through production operation. Feel free to reach out.


References (official documentation)

友田

友田 陽大

Developer of a METI Minister's Award–winning product. With TypeScript + Python + AWS, I deliver SaaS, industry DX, and production-grade generative AI (RAG) end to end — from requirements to infrastructure and operations — single-handedly.

Got a challenge?

From design to implementation and operations — solo × generative AI

Implementation like this article's, end to end from requirements to production. Start with a free 30-minute technical consult and tell me about your situation.

Available for both project-based (contract) and advisory engagements. Start with a free 30-minute consult.

Also worth reading