Managed stores: Astra DB and Pinecone
- Source
- From the RAG & Agents Engineering course
- By
- Sourav Banerjee
- Last updated
- 9 Nov 2026
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:
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:
- Keep the public handbook in its own collection or namespace, so re-indexing it never touches customer data.
- Give each customer's runbooks their own namespace, chosen by the service that builds the query, never by the caller.
- Use one record-manager namespace per collection (lesson 5 of T5.5), so a cleanup run cannot reach another collection's keys.
- 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.