{"id":60,"library":"pgvector","title":"pgvector","description":"Open-source PostgreSQL extension for vector similarity search. Two components: (1) the server-side Postgres extension (C, compiled and installed into Postgres), and (2) the Python client package 'pgvector' on PyPI which provides ORM/adapter integrations for psycopg2, psycopg3, asyncpg, SQLAlchemy, Django, SQLModel, and Peewee. The extension name in SQL is 'vector' (CREATE EXTENSION vector), not 'pgvector'. Maintained by Andrew Kane. Current extension version: 0.8.2 (CVE security fix). Python client: 0.4.2.","status":"active","version":"0.8.2","language":"python","source_language":"en","source_url":"https://github.com/pgvector/pgvector","tags":["pgvector","postgres","postgresql","vector-search","similarity-search","embeddings","hnsw","ivfflat","rag","sql"],"install":[{"cmd":"pip install pgvector","lang":"bash","label":"Python client (ORM integrations)"},{"cmd":"sudo apt install postgresql-17-pgvector","lang":"bash","label":"Ubuntu/Debian (APT, replace 17 with your PG version)"},{"cmd":"brew install pgvector","lang":"bash","label":"macOS via Homebrew"},{"cmd":"docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=pass pgvector/pgvector:pg17","lang":"bash","label":"Docker (official image)"},{"cmd":"git clone --branch v0.8.2 https://github.com/pgvector/pgvector.git && cd pgvector && make && make install","lang":"bash","label":"Build from source (requires pg dev headers)"}],"dependencies":[{"reason":"Required. pgvector Python package is adapter-only — you must separately install a Postgres driver. psycopg2-binary for sync, psycopg (psycopg3) for async/LangChain.","package":"psycopg2 or psycopg3 or asyncpg","optional":false},{"reason":"Required when passing vectors as arrays. pgvector accepts Python lists or numpy float32 arrays.","package":"numpy","optional":false}],"imports":[{"note":"Top-level 'import pgvector' does nothing useful. Must import from the submodule matching your driver.","wrong":"import pgvector","symbol":"register_vector (psycopg2)","correct":"from pgvector.psycopg2 import register_vector"},{"note":"psycopg2 and psycopg3 use different submodules. Mixing them causes AttributeError.","wrong":"from pgvector.psycopg2 import register_vector","symbol":"register_vector (psycopg3)","correct":"from pgvector.psycopg import register_vector"},{"note":"Use HALFVEC, BIT, SPARSEVEC from the same module for other vector types.","symbol":"Vector (SQLAlchemy)","correct":"from pgvector.sqlalchemy import Vector"}],"quickstart":{"code":"# Step 1: Enable extension in Postgres (run once per database)\n# CREATE EXTENSION IF NOT EXISTS vector;\n\nimport psycopg2\nfrom pgvector.psycopg2 import register_vector\nimport numpy as np\n\nconn = psycopg2.connect(\"dbname=mydb user=postgres\")\nregister_vector(conn)  # REQUIRED: registers the vector type\n\ncur = conn.cursor()\ncur.execute(\"CREATE TABLE IF NOT EXISTS items (id bigserial PRIMARY KEY, embedding vector(3))\")\n\n# Insert vectors\ncur.execute(\"INSERT INTO items (embedding) VALUES (%s)\", (np.array([1.0, 2.0, 3.0], dtype='float32'),))\nconn.commit()\n\n# L2 distance search (<->)\ncur.execute(\"SELECT id FROM items ORDER BY embedding <-> %s LIMIT 5\", (np.array([1.0, 1.0, 1.0], dtype='float32'),))\nprint(cur.fetchall())\n\ncur.close()\nconn.close()","lang":"python","description":"register_vector(conn) must be called after connecting — it registers the custom 'vector' type with psycopg2. Without it, vectors are returned as strings. Extension must be enabled server-side first with CREATE EXTENSION vector."},"warnings":[{"fix":"Upgrade to pgvector 0.8.2 immediately.","message":"CVE-2026-3172: Buffer overflow with parallel HNSW index builds in versions 0.6.0–0.8.1. Can leak sensitive data from other relations or crash the database server. Fixed in 0.8.2.","severity":"breaking","affected_versions":"0.6.0 to 0.8.1"},{"fix":"Report to your cloud provider. If self-hosting, compile on the same CPU architecture as the runtime. Cannot be worked around from the client side.","message":"Illegal instruction crashes (SIGILL) when pgvector is compiled with -march=native on one CPU architecture and run on another. Occurs on managed cloud Postgres (Azure Flexible Server, some GCP instances) after upgrading to 0.8.0+.","severity":"breaking","affected_versions":"0.8.0+"},{"fix":"pip install psycopg[binary]. Use connection string postgresql+psycopg://user:pass@host/db.","message":"LangChain's langchain-postgres package requires psycopg3 (package name: psycopg). Connection strings must use postgresql+psycopg:// not postgresql+psycopg2://. Mixing drivers causes driver-not-found errors.","severity":"breaking","affected_versions":"all"},{"fix":"Upgrade to Postgres 17.3+.","message":"Postgres 17.0–17.2 causes link error: 'unresolved external symbol float_to_shortest_decimal_bufn' when building pgvector from source.","severity":"breaking","affected_versions":"all source builds against PG 17.0-17.2"},{"fix":"Always use: CREATE EXTENSION IF NOT EXISTS vector;","message":"The SQL extension name is 'vector', not 'pgvector'. CREATE EXTENSION pgvector raises 'extension not found'. This is a consistent source of confusion.","severity":"gotcha","affected_versions":"all"},{"fix":"Call register_vector(conn) immediately after psycopg2.connect(). For connection pools, call it in the connection setup callback.","message":"register_vector(conn) must be called after every new connection. It is not persistent. Failing to call it means vector columns are returned as raw strings, not numpy arrays. No error is raised — silent wrong behavior.","severity":"gotcha","affected_versions":"all (psycopg2)"},{"fix":"Always include ORDER BY embedding <-> $1 LIMIT k in vector search queries. Without LIMIT, the index is not used.","message":"HNSW and IVFFlat indexes without ORDER BY + LIMIT do not use the ANN index — Postgres falls back to sequential scan. Queries without LIMIT return exact results but at O(n) cost.","severity":"gotcha","affected_versions":"all"},{"fix":"Use pgvector cosine thresholds in [0, 2]. Equivalent: pgvector_threshold = 1 - cosine_similarity.","message":"COSINE distance in pgvector uses the range [0, 2], not [0, 1]. 0 = identical, 2 = opposite. Thresholds from other libraries (which use [0,1]) must be remapped.","severity":"gotcha","affected_versions":"all"},{"fix":"Load all or most data first, then run CREATE INDEX. For ongoing ingestion, rebuild or use HNSW which handles incremental inserts better.","message":"IVFFlat index must be built AFTER data is loaded. Creating the index on an empty table and then inserting data results in a near-useless index (lists are not representative of the data distribution).","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T06:16:52.675Z","next_check":"2026-05-28T00:00:00.000Z","problems":[{"fix":"Install the pgvector Python package using pip: `pip install pgvector`","cause":"The Python client package 'pgvector' is not installed in the environment where the code is being run.","error":"ModuleNotFoundError: No module named 'pgvector'"},{"fix":"Connect to your PostgreSQL database and execute the SQL command: `CREATE EXTENSION IF NOT EXISTS vector;` Ensure you are connected to the correct database and have sufficient permissions.","cause":"The PostgreSQL 'vector' extension has not been created in the database or the current user does not have access to it, preventing the use of the `vector` data type.","error":"ERROR: type \"vector\" does not exist"},{"fix":"Ensure the input array is explicitly cast to `vector` in your SQL query, for example: `SELECT * FROM items ORDER BY embedding <-> %s::vector LIMIT 1;`. If using a Python client, ensure you are passing a compatible type or register the vector type with the driver (e.g., `pgvector.psycopg.register_vector(conn)` for psycopg).","cause":"This error typically occurs when trying to use pgvector operators (like `<->` for L2 distance) with an incompatible data type or when the vector extension is not in the active search path. It can also happen if the input vector is not explicitly cast to the `vector` type.","error":"operator does not exist: vector <-> double precision[]"},{"fix":"For SQLAlchemy integration, import the `Vector` type directly from `pgvector` (e.g., `from pgvector.sqlalchemy import Vector` might be incorrect, try `from pgvector.sqlalchemy import VectorColumn` or depending on the library version, the `Vector` type might be directly available after importing `pgvector` or used as a type annotation if `pgvector` is registered as a dialect). If using LangChain, ensure you have the correct `langchain-postgres` package and its compatible `pgvector` version installed.","cause":"This specific error indicates an incorrect import path for SQLAlchemy integration with pgvector, particularly in applications using `langchain_postgres`. The `Vector` type for SQLAlchemy is often directly available from the `pgvector` top-level package or an older/different `langchain` integration might be attempting a non-existent sub-module import.","error":"ModuleNotFoundError: No module named 'pgvector.sqlalchemy'; 'pgvector' is not a package"}],"ecosystem":"pypi","meta_description":null,"install_score":0,"install_tag":"stale","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null}]},"quickstart_checks":{"last_tested":"2026-05-12","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}