Migration from VectorDB
beginnerMove from Pinecone, Weaviate, or ChromaDB to Engramma. Map concepts, export data, and start using cognitive memory in under an hour.
What you'll build
A migration script that moves your vectors and metadata from your current vector database to Engramma — plus a concept mapping to understand what you gain.
Prerequisites
| Requirement | Details |
|---|---|
| Account | Starter tier or above (for bulk import) |
| API key | From your dashboard |
| HTTP client | curl, Python requests, or JavaScript fetch |
| Existing data | An active Pinecone, Weaviate, or ChromaDB instance |
| Time | ~30-60 minutes (depends on data volume) |
Concept mapping
Your existing knowledge translates directly:
| Vector DB concept | Engramma equivalent | What changes |
|---|---|---|
| Vector/Embedding | Pattern | Engramma also stores text, not just vectors |
| Index/Collection | Memory Space | One per API key (or use metadata for namespaces) |
| Namespace | Metadata tags | Use metadata fields to segment data |
| Cosine similarity | similarity score | Returned on each result (0-1 range) |
| Upsert | Store | Returns pattern_id plus usage stats |
| Query | Retrieve | Returns similarity + text + metadata |
| Metadata | Metadata | Carries over directly |
| — | Consolidation | New: memory quality improves over time |
| — | Duplicate merging | New: automatic deduplication via threshold |
Migration strategies
There are two paths depending on what data you have:
| Strategy | Endpoint | When to use |
|---|---|---|
| Text-based (preferred) | /v1/memory/text/store | You have the original text — let Engramma re-embed with its own 384-dim model |
| Embedding-based (fallback) | /v1/memory/store | You only have pre-computed embeddings and no source text |
Prefer text-based migration whenever possible. Engramma uses a 384-dimension embedding model internally. Re-embedding your text ensures optimal retrieval quality.
Steps
Export from your current database
Choose a migration strategy
Import into Engramma
Consolidate
Validate
Text-based migration (preferred)
Use this when you have the original text content. Engramma will re-embed each item with its own model.
Single item store
import requests
API_KEY = "your-engramma-api-key"
BASE_URL = "https://api.engramma-memory.com"
response = requests.post(
f"{BASE_URL}/v1/memory/text/store",
headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
json={
"text": "Our deployment process uses blue-green deploys on Kubernetes.",
"metadata": {"source": "wiki", "category": "devops"}
}
)
result = response.json()
# {
# "success": true,
# "pattern_id": "pat_abc123",
# "embedding_dim": 384,
# "patterns_used": 42,
# "patterns_limit": 10000
# }
print(f"Stored as {result['pattern_id']}")Batch store (up to 50 items per request)
import requests
API_KEY = "your-engramma-api-key"
BASE_URL = "https://api.engramma-memory.com"
items = [
{"text": "Q2 revenue was $4.2M, up 18% YoY.", "metadata": {"type": "finance"}},
{"text": "Main risk: supply chain delays in APAC region.", "metadata": {"type": "risk"}},
{"text": "Billing system owned by the Payments team.", "metadata": {"type": "ownership"}}
]
response = requests.post(
f"{BASE_URL}/v1/memory/text/batch-store",
headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
json={"items": items}
)
result = response.json()
# {
# "stored": 3,
# "failed": 0,
# "pattern_ids": ["pat_abc123", "pat_def456", "pat_ghi789"],
# "latency_ms": 45.2
# }
print(f"Stored {result['stored']} items in {result['latency_ms']}ms")Embedding-based migration (fallback)
Use this when you only have pre-computed embeddings without the original text. This uses the low-level vector endpoints that accept raw key/value arrays.
The low-level endpoints (/v1/memory/store, /v1/memory/batch/store) accept raw embedding vectors. You will not be able to use the text retrieval endpoint for these entries — use /v1/memory/query with a raw embedding vector instead.
import requests
API_KEY = "your-engramma-api-key"
BASE_URL = "https://api.engramma-memory.com"
# Single raw embedding store
embedding = [0.12, -0.34, 0.56, ...] # your pre-computed vector
value = [0.12, -0.34, 0.56, ...] # can be the same or associated data
response = requests.post(
f"{BASE_URL}/v1/memory/store",
headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
json={"key": embedding, "value": value}
)
print(response.json())Full migration from Pinecone
import os
import pinecone
import requests
# Source: Pinecone
pinecone.init(api_key=os.environ["PINECONE_API_KEY"])
index = pinecone.Index("my-index")
# Destination: Engramma
API_KEY = os.environ["ENGRAMMA_API_KEY"]
BASE_URL = "https://api.engramma-memory.com"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
# Export from Pinecone (paginated)
results = index.query(
vector=[0.0] * 1536, # dummy vector to fetch all
top_k=100,
include_metadata=True,
include_values=True,
namespace=""
)
# Separate text-based vs embedding-only items
text_items = []
embedding_items = []
for match in results.matches:
text = match.metadata.get("text", "")
if text:
text_items.append({
"text": text,
"metadata": {**match.metadata, "source": "pinecone_migration"}
})
else:
embedding_items.append({
"key": match.values,
"value": match.values
})
# Batch-store text items (50 at a time)
for i in range(0, len(text_items), 50):
batch = text_items[i:i+50]
resp = requests.post(
f"{BASE_URL}/v1/memory/text/batch-store",
headers=HEADERS,
json={"items": batch}
)
result = resp.json()
print(f"Text batch: stored {result['stored']}, failed {result['failed']}")
# Store raw embeddings one by one (low-level endpoint)
for item in embedding_items:
requests.post(
f"{BASE_URL}/v1/memory/store",
headers=HEADERS,
json=item
)
print(f"Migrated {len(text_items)} text items + {len(embedding_items)} embeddings from Pinecone")Full migration from Weaviate
import os
import weaviate
import requests
# Source: Weaviate
weaviate_client = weaviate.Client("http://localhost:8080")
# Destination: Engramma
API_KEY = os.environ["ENGRAMMA_API_KEY"]
BASE_URL = "https://api.engramma-memory.com"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
# Export from Weaviate
result = weaviate_client.query.get(
"Document", ["content", "title", "category"]
).with_limit(1000).do()
documents = result["data"]["Get"]["Document"]
# Build batch items
items = []
for doc in documents:
items.append({
"text": doc["content"],
"metadata": {
"title": doc.get("title"),
"category": doc.get("category"),
"source": "weaviate_migration"
}
})
# Batch-store (50 at a time)
for i in range(0, len(items), 50):
batch = items[i:i+50]
resp = requests.post(
f"{BASE_URL}/v1/memory/text/batch-store",
headers=HEADERS,
json={"items": batch}
)
result = resp.json()
print(f"Batch {i//50 + 1}: stored {result['stored']}, failed {result['failed']}")
print(f"Migrated {len(documents)} documents from Weaviate")Full migration from ChromaDB
import os
import chromadb
import requests
# Source: ChromaDB
chroma = chromadb.Client()
collection = chroma.get_collection("my-collection")
# Destination: Engramma
API_KEY = os.environ["ENGRAMMA_API_KEY"]
BASE_URL = "https://api.engramma-memory.com"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
# Export from ChromaDB
results = collection.get(
include=["documents", "metadatas", "embeddings"]
)
# Separate text-based vs embedding-only items
text_items = []
embedding_items = []
for i, doc in enumerate(results["documents"]):
metadata = results["metadatas"][i] if results["metadatas"] else {}
metadata["source"] = "chromadb_migration"
if doc:
text_items.append({"text": doc, "metadata": metadata})
elif results["embeddings"] and results["embeddings"][i]:
embedding_items.append({
"key": results["embeddings"][i],
"value": results["embeddings"][i]
})
# Batch-store text items (50 at a time)
for i in range(0, len(text_items), 50):
batch = text_items[i:i+50]
resp = requests.post(
f"{BASE_URL}/v1/memory/text/batch-store",
headers=HEADERS,
json={"items": batch}
)
result = resp.json()
print(f"Text batch: stored {result['stored']}, failed {result['failed']}")
# Store raw embeddings (low-level endpoint)
for item in embedding_items:
requests.post(
f"{BASE_URL}/v1/memory/store",
headers=HEADERS,
json=item
)
print(f"Migrated {len(text_items)} text items + {len(embedding_items)} embeddings from ChromaDB")Post-migration consolidation
After importing all data, run consolidation to organize memories and merge near-duplicates:
import requests
API_KEY = "your-engramma-api-key"
BASE_URL = "https://api.engramma-memory.com"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
# Step 1: Full consolidation (reorganizes and strengthens patterns)
resp = requests.post(
f"{BASE_URL}/v1/memory/consolidation/sleep",
headers=HEADERS,
json={"mode": "full"}
)
print("Consolidation:", resp.json())
# Step 2: Merge near-duplicates (threshold 0-1, lower = more aggressive)
resp = requests.post(
f"{BASE_URL}/v1/memory/consolidation/merge-duplicates",
headers=HEADERS,
json={"threshold": 0.85}
)
print("Merge duplicates:", resp.json())Validating your migration
After importing and consolidating, verify that your existing queries work as expected:
import requests
API_KEY = "your-engramma-api-key"
BASE_URL = "https://api.engramma-memory.com"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
# Run your most important queries and compare
test_queries = [
"What is our deployment process?",
"Who is responsible for the billing system?",
"What are the main risks in Q2?"
]
for query in test_queries:
resp = requests.post(
f"{BASE_URL}/v1/memory/text/retrieve",
headers=HEADERS,
json={"query": query, "top_k": 5}
)
data = resp.json()
# {
# "results": [
# {"text": "...", "metadata": {...}, "similarity": 0.94, "pattern_id": "pat_..."},
# ...
# ],
# "latency_ms": 2.3
# }
print(f"\nQuery: {query} ({data['latency_ms']}ms)")
for r in data["results"]:
print(f" [{r['similarity']:.2f}] {r['text'][:80]}...")What you gain after migration
| Before (Vector DB) | After (Engramma) |
|---|---|
| Cosine similarity only | similarity score with optimized 384-dim embeddings |
| Static storage | Self-improving via consolidation cycles |
| Manual deduplication | Automatic merging via merge-duplicates endpoint |
| No lifecycle management | Full consolidation with sleep/merge modes |
| Separate embedding pipeline | Built-in embedding (just send text) |
| Custom infrastructure | Managed API with usage tracking (patterns_used/patterns_limit) |
After migration, run consolidation periodically. The merge-duplicates endpoint with a threshold of 0.85 is a good starting point — it will merge items that are near-identical without being too aggressive.
Next steps
- Your First Memory — Quick introduction to the Engramma API
- How It Works — Understand the cognitive memory architecture
- Consolidation — How your migrated data improves over time