native index, which runs the search engine Pinecone uses at scale inside Postgres. You can bring your own vectors, with no API key or network access, or have Pinecone generate embeddings. To compare native with the other engines, see Storage engines.
If you already have a table with a pgvector index, complete steps 1 and 2 to install pg_pinecone, then switch from pgvector to native.
Prerequisites
- A PostgreSQL 17 or 18 server and a superuser role on it.
- pgvector installed on that server, because pg_pinecone uses its
vectorcolumn type and distance operators. If you don’t have it, runsudo apt install postgresql-17-pgvectoron Debian or Ubuntu, orbrew install pgvectorwith Homebrew on macOS. For other Linux distributions, see the pgvector installation guide. If you install with Docker, the image includes Postgres and pgvector, so you need only Docker. - Optional: a Pinecone API key, if you want Pinecone to generate the embeddings. A key from the free Starter plan is enough.
The
native engine never calls Pinecone. Steps 3 and 4 each have two tabs, so pick the same one in both. Your own vectors runs entirely in your database with no API key or network access, and Pinecone embeddings generates embeddings with a Pinecone-hosted model.1. Install pg_pinecone
- Release archive
- Docker
- Download the release archive for your platform and Postgres version from the releases page. Archives are published for PostgreSQL 17 and 18 on Linux x86_64, Linux arm64, and macOS arm64. The Linux x86_64 build needs a CPU that supports x86-64-v3 (Intel Haswell or newer, which covers current cloud instances), and the Linux builds need glibc 2.39 or later, such as Ubuntu 24.04 or Debian 13.
-
Extract the archive and copy its files into your Postgres installation.
The commands use
PG=17. If your server runs PostgreSQL 18, change it toPG=18. To check your version, runpg_config --version.pg_configalso reports where your Postgres installation keeps extension files:
linux-arm64 archive. If more than one Postgres version is installed, use the pg_config that belongs to the server you’re installing into. On other platforms, including Debian 12, Ubuntu 22.04, RHEL 9, and older x86_64 CPUs, build from source.2. Connect and create the extensions
-
Connect to your database as a superuser with
psql:On Linux, thepostgressystem user is the superuser that the package creates. With Homebrew on macOS, your own user is the superuser. In the Docker image, the superuser ispostgres. To connect to a different database or a remote server, add-d your_database,-h your_host, and-U your_superuser. -
Create the extensions. Create pgvector first, because pg_pinecone builds on its
vectortype and operators:SQL
3. Add sample data
- Your own vectors
- Pinecone embeddings
-
Create the table. These vectors have three dimensions:
SQL
-
Insert a few short documents with their vectors. In a real application, you’d generate the vectors with an embedding model of your choice. To skip that step here, each document gets a hand-made vector whose values stand for food, nature, and places:
SQL
4. Search inside Postgres
Create a native index
Create a With Pinecone embeddings,
native index on the vector column. native is the default engine, so engine => 'native' is optional:SQL
pinecone.create_index() prints an informational message, labeled NOTICE, that suggests SET STORAGE PLAIN on the vector column, which speeds up searches on large tables. You can ignore it for this sample.Run a search
Search with an ordinary pgvector query, the same query you’d run without pg_pinecone.
<=> is pgvector’s cosine distance operator:- Your own vectors
- Pinecone embeddings
Query with The two closest documents are the two about food:
[1, 0, 0], a vector that points entirely toward food, with no nature or places:SQL
Output
SET enable_seqscan = off makes Postgres use the index on this eight-row table. On a table this small, the planner would otherwise read every row directly, because that’s cheaper than using any index. Once a table is large enough that reading every row costs more, the planner chooses the index on its own, and you don’t need this setting. It lasts until you disconnect.Check which index served the query
EXPLAIN shows the plan Postgres uses to run a query, including which index it reads. To confirm the native index served the search, check the plan:SQL
Index Scan using docs_embedding_pinecone_idx, the native index you created in step 4.1. If Postgres read every row instead, the plan would show Seq Scan.5. Clean up
If you don’t need the sample table anymore, delete it.DROP TABLE permanently deletes the table, its rows, and its indexes, including the native index. To try switching from native to remote next, skip this step, because that guide uses the same table.
SQL
Next steps
- Choose a storage engine for your workload.
- Switch from pgvector to native on an existing table.
- Switch from native to remote when a table outgrows one server.
- Search a table with full-text search.