Skip to content
Forward Deployed

Forward Deployed
Lessons and contents
Vector Stores & Index OperationsLesson 4 of 7
7 lessons
Learn

Managed stores: Astra DB and Pinecone

Source
From the RAG & Agents Engineering course
By
Sourav Banerjee
Last updated
9 Nov 2026

Report an issue

Collections and namespaces

What you'll learn

  • Explain collections, indexes and namespaces across four stores, and what each fixes at creation.
  • Compare a namespace boundary with a metadata filter as a way to isolate tenants.
  • Diagnose a cleanup run that deletes another collection's keys.
  • Choose when a managed store earns its cost over an embedded one.

Lesson 2 of T5.5 kept the index on one machine. Managed stores run it as a service, and they make you decide up front how entries are grouped.

Larkspur adds customer-specific runbooks to the same collection as the public handbook, tagged with a tenant field. One support tool builds its query without the tenant filter, and a customer's question can now retrieve another customer's runbook. Nothing raises an error. We call this a leaky filter boundary.

Every store groups its entries, and the grouping decides what one query can see. The names differ:

Store Container you create Partition inside it What is fixed when you create it
Chroma Collection (collection_name) none Distance space and HNSW settings
PGVector A row in langchain_pg_collection (collection_name) none; entries in langchain_pg_embedding carry its collection_id Nothing, unless you pass embedding_length, which fixes the vector column's dimension
Pinecone Index (pc.create_index(name, dimension, metric, spec)) Namespace Dimension and metric
Astra DB Collection (collection_name) inside a namespace, also called a keyspace none Vector dimension and metric

Table 1: Containers and partitions in four stores.

In Pinecone, namespaces sit inside an index:

Diagram: Pinecone project; Index: rag dimension 1024, cosine; Namespace: handbook; Namespace: tenant-acme; Records id + vector + metadataDiagram: Pinecone project; Index: rag dimension 1024, cosine; Namespace: handbook; Namespace: tenant-acme; Records id + vector + metadata

Figure 1: A Pinecone index with two namespaces. Every read and write targets one namespace.

The Pinecone notebook creates a serverless index named rag with dimension=1024 and metric="cosine", and asks OpenAI's text-embedding-3-small for 1,024 dimensions to match. The index's dimension cannot change, so the embedding model and its output size are part of the index's identity. The Astra DB notebook does the same with dimensions=1024 and passes namespace=None, so the store falls back to the ASTRA_DB_KEYSPACE environment variable or the database's default namespace.

Pinecone's indexing overview says reads and writes "always target one namespace", that namespaces are created on first upsert, and that you can isolate customers with "one namespace per customer". A query in one namespace cannot return another namespace's records, which is a stronger boundary than a metadata filter that a caller can leave out. In LangChain, PineconeVectorStore takes the namespace as an argument.

The record manager in lesson 5 of T5.5 has a namespace too: SQLRecordManager("pgvector/vectordb", db_url=...). It scopes the record manager's keys, not the vectors. Keep one record-manager namespace per collection. If two collections share one, a full cleanup run on either deletes the other's keys. We call that a shared record-manager namespace.

For Larkspur, the public handbook goes in one collection or namespace. Customer-specific runbooks, if they arrive, go in their own namespaces. Re-indexing the handbook then never touches customer data, and a customer's query cannot reach another customer's text.

When a managed store earns its cost

The managed stores take the same LangChain calls as Chroma: add_documents, similarity_search(query, k, filter=...), as_retriever(...). The Pinecone notebook filters with {"source": "tweet"} and runs a retriever with search_type="similarity_score_threshold" and score_threshold=0.4, a threshold that only means something on that index's cosine scale. Switching stores changes the setup and the bill; the calls stay the same.

Lesson 1 of T5.5's notebook gives the rule: move to a hosted store when you need concurrent writers, horizontal scale or managed availability, and not before. The move is a re-index, so the embedding model goes with you, and the IDs you derived in lesson 1 of T5.5 make the second load as idempotent as the first. Until then an embedded store, or pgvector in a Postgres you already run (lesson 4 of T5.5), has no API key to manage, no network hop and no bill per query.

In practice: separating the handbook from customer data

For Larkspur, the containers follow the boundaries the business needs:

  1. Keep the public handbook in its own collection or namespace, so re-indexing it never touches customer data.
  2. Give each customer's runbooks their own namespace, chosen by the service that builds the query, never by the caller.
  3. Use one record-manager namespace per collection (lesson 5 of T5.5), so a cleanup run cannot reach another collection's keys.
  4. Stay on an embedded store or pgvector until concurrent writers, horizontal scale or managed availability are needed.

Next: lesson 4 of T5.5 filters inside one container, with Postgres and pgvector.

Run the notebooks

The code for this lesson is in these notebooks. Colab runs one in your browser: install the packages its first cell imports and set the API keys it reads. To run every notebook as written, clone the repository and use its uv environment.

Notebook GitHub Colab
Pinecone Open on GitHub Open in Colab
Astra db (optional) Open on GitHub Open in Colab

Key Takeaways

  • A Pinecone index fixes its dimension and metric at creation, so the embedding model and output size are part of its identity. Changing either means a new index.
  • A namespace per customer is a stronger boundary than a metadata filter, because a query cannot reach another namespace. Keep one record-manager namespace per collection.
  • Move to a managed store for concurrent writers, horizontal scale or managed availability, and not before. The LangChain calls stay the same; the move is a re-index.

Check yourself

1. Why is one Pinecone namespace per customer a stronger boundary than a metadata filter on the customer id?

Pinecone reads and writes always target one namespace, so a query in one namespace cannot return another namespace's records. A metadata filter is something a caller can leave out. For Larkspur, this also means re-indexing the handbook never touches customer data.

2. The Pinecone notebook asks text-embedding-3-small for 1,024 dimensions. Why, and what happens if you later want 1,536?

The index was created with dimension=1024 and metric="cosine", and the embedding output must match it. An index's dimension cannot change, so the embedding model and its output size are part of the index's identity. Moving to 1,536 means a new index and a re-index into it.

3. Your Larkspur index runs fine on Chroma with one writer. When should you move it to a managed store?

When you need concurrent writers, horizontal scale or managed availability, and not before. Until then an embedded store, or pgvector in a Postgres you already run, has no API key to manage, no network hop and no bill per query. The move is a re-index, and the stable IDs from lesson 1 of T5.5 keep the second load idempotent.

Rate your confidence and keep notes on the module page.