Skip to main content
CoreWeave Database (CWDB) runs managed PostgreSQL inside your CoreWeave Kubernetes Service (CKS) cluster. With the pgvector extension, you can store embeddings alongside application data and query them with SQL. In this tutorial, you create a CWDB database with pgvector, connect from a client Pod, and run cosine similarity searches. You then add a hierarchical navigable small world (HNSW) index for approximate nearest-neighbor search. CoreWeave manages the database operator, replication, and backups.

Before you begin

Before you begin, make sure you have the following:
  • A CKS cluster with CWDB enabled. To request access, contact CoreWeave through your customer Slack channel with the CKS cluster name and the Namespace you plan to use.
  • CPU capacity for three database instances. This example requests 1 CPU and 2 GiB of memory per instance, plus capacity for the managed supporting Pods and a client Pod.
  • A default CoreWeave Distributed File Storage (DFS) StorageClass with capacity for three 25 GiB volumes. These are provisioned volume sizes, not the amount of data stored by this example.
  • kubectl configured for the target CKS cluster, with permission to create a Namespace, a CWDBCluster, and a client Pod. You also need permission to execute commands in the client Pod.
Confirm the target context and CWDB API before creating resources:
The API resource list must include cwdbclusters. If it doesn’t, confirm CWDB enablement with CoreWeave. If access is forbidden, ask your cluster administrator to check your permissions. See Create a database for CPU capacity requirements. The commands use a new Namespace named cwdb-pgvector-tutorial and a database resource named vector-db. Use these names throughout the walkthrough. The resource sizes are for learning, not production sizing guidance.

Deploy CoreWeave Database with pgvector

Create a dedicated Namespace:
Save the following manifest as the cwdb-pgvector.yaml file:
cwdb-pgvector.yaml
The extension.name: pgvector setting selects the pgvector-enabled PostgreSQL image. CWDB creates the SQL extension named vector in the initial database, vectors. You don’t need to run CREATE EXTENSION in this database. The owner field creates the application role, app. This manifest creates three PostgreSQL instances and leaves managed backups enabled. For supported PostgreSQL versions and other options, see Configure database. Validate and apply the manifest, then wait for CWDB to report readiness:
The wait command returns the following output:
If the wait times out, inspect the resource and its events before continuing:
See Troubleshoot CWDB for provisioning failures.

Connect with application credentials

CWDB creates a Secret containing the application connection URI. For this manifest, the Secret is vector-db-vectors-credentials: the resource name followed by the initial database name and -credentials. Its uri key points to the read-write pooler Service, vector-db-pooler-rw. Use a client Pod in the same Namespace to resolve that Service name. Save the following manifest as the pgvector-client.yaml file. Kubernetes injects the URI directly from the Secret, so you don’t need to print or copy a password.
pgvector-client.yaml
Create the client and open psql:
A successful connection displays the vectors=> prompt. Run the remaining SQL commands in this psql session. Application traffic should use the pooler Services. See Connect to a database for other connection methods and cross-Namespace DNS names.

Verify pgvector

Check the connected database, role, and installed extension:
The first query must return vectors and app. The second must return one row for vector. Its version depends on the CWDB image deployed in your cluster. If the extension query returns no rows, confirm that you’re connected to vectors, that the manifest specifies extension.name: pgvector, and that CWDB reports Ready. This tutorial uses the initial database that CWDB manages. It doesn’t configure extensions in additional databases you create yourself.

Store and search vectors

Create a table with text, a category, and a three-dimensional vector:
These vectors are hand-written examples to make the results reproducible. They aren’t embeddings generated from the text. In an application, generate document and query embeddings with the same embedding model and use its output dimension in place of 3. pgvector stores and searches vectors. It doesn’t generate embeddings. The <=> operator calculates cosine distance. Order by distance in ascending order to retrieve the nearest vectors. Subtract the distance from 1 to display cosine similarity:
The query returns the following output:
No vector index exists yet, so this is an exact nearest-neighbor search. You can also combine vector search with a SQL filter:
This query returns rows 1 and 2. In your application, send query vectors as bound parameters through your PostgreSQL driver instead of interpolating them into SQL strings.

Add an approximate nearest-neighbor index

HNSW indexes on the vector type support up to 2,000 dimensions. Check your embedding model’s dimensions before using this index. For larger datasets, an HNSW index can speed up nearest-neighbor queries by trading some recall for speed. Create an index with the operator class that matches cosine distance:
Run the same nearest-neighbor query:
For this example, the result is still rows 1 and 2. Keep the distance operator directly in ORDER BY, with ascending order and a LIMIT, so the query can use the vector index. Inspect the query plan:
PostgreSQL may choose a sequential scan for this four-row table. That’s expected and doesn’t mean index creation failed. Test latency and recall with representative data before choosing index settings for production.
When a query uses an approximate vector index, SQL filters can reduce the number of returned rows below LIMIT. See the pgvector filtering guidance for indexing and iterative-scan options supported by your installed version.

Clean up

Exit psql:
The following commands delete the tutorial database and its Kubernetes resources. Only run them when you no longer need the example data. Storage retained by the StorageClass reclaim policy and managed backups can outlive the database. See Delete a database before deleting resources that contain data you need.

Next steps

Explore the following resources to adapt this tutorial to your workload:
Last modified on September 16, 2026