📦 Clone and ⭐ stop-ai-agents-losing-memory-sample-for-aws
Part 1 of this post showed how keyword search misses semantic questions and measured two vector backends: FAISS and Amazon S3 Vectors (managed), on the same traveler memories. Both found the answer. The difference was deployment: local vs cloud-managed.
This part adds a third vector backend: Amazon DynamoDB Vector Search, generally available since 2025. The question and the memories are identical. Only the backend changes.
stored: dietary_notes: "Vegetarian; severe shellfish allergy — strictly no
crustaceans or mollusks."
asked: "What should I avoid eating when I go out for dinner on this trip?"
DynamoDB Vector Search: top hit (score 0.231) answer found: True
What is Amazon DynamoDB Vector Search?
It is a vector index added to an existing DynamoDB table. Not a separate service. You define a VectorIndexes block when you create (or update) the table, and DynamoDB stores the embeddings as a List attribute on each item. Queries use the SearchVectors API.
The key difference from S3 Vectors: the vectors live in the same table as your operational data. If your agent already reads user preferences or travel records from DynamoDB, you can add a vector index to that same table and query by meaning without provisioning another service.
| Amazon S3 Vectors | Amazon DynamoDB Vector Search | |
|---|---|---|
| Where vectors live | Dedicated vector bucket | Inside a DynamoDB table |
| Operational data collocated | No | Yes |
| Query latency | ~100–200 ms | Single-digit ms |
| Billing model | Per-query + storage | On-demand (PAY_PER_REQUEST) |
| Accuracy | ✅ same (same embeddings) | ✅ same (same embeddings) |
| Survives restart | Yes | Yes |
| Infrastructure to manage | None | None |
| Best for | Dedicated vector memory, no operational data to manage | Agents that already use DynamoDB, or want one service for data + embeddings |
Both are valid choices. S3 Vectors is purpose-built for dedicated vector workloads and the right fit when you want memory completely separate from your operational data. DynamoDB Vector Search is the right fit when your agent data is already in DynamoDB and you want one service for both.
(This demo uses Strands Agents. The pattern carries over to any agent framework.)
How does the embedding comparison look?
Same question, same Titan V2 embeddings, four backends side by side:
| Store | Finds answer | cos_sim | Query latency |
|---|---|---|---|
| Key-value (keyword scan) | No | — | — |
| FAISS | Yes | 0.231 | <0.1 ms |
| Amazon S3 Vectors | Yes | 0.231 | ~195 ms |
| Amazon DynamoDB Vector Search | Yes | 0.231 | single-digit ms |
All three vector backends return the same top hit with the same score, because they use the same Amazon Titan Text Embeddings V2 model. The embedding call (~510 ms) still dominates end-to-end latency for all of them. What changes is the query after the embedding.
How do you add a vector index to a DynamoDB table?
DynamoDB Vector Search requires on-demand billing (PAY_PER_REQUEST). The vector index is declared when creating the table:
client.create_table(
TableName="agent-memory-demo-ddb",
BillingMode="PAY_PER_REQUEST", # required for vector indexes
KeySchema=[{"AttributeName": "memory_key", "KeyType": "HASH"}],
AttributeDefinitions=[{"AttributeName": "memory_key", "AttributeType": "S"}],
VectorIndexes=[{
"IndexName": "memory-vector-index",
"VectorAttribute": {"AttributeName": "embedding"},
"Dimensions": 1024,
"DistanceFunction": "COSINE",
"Projection": {"ProjectionType": "ALL"},
}],
)
The demo self-provisions the table and index if missing: no console steps, no CDK required.
How do you write and query vectors?
Embeddings are stored as a DynamoDB List attribute alongside the rest of the item:
client.put_item(
TableName="agent-memory-demo-ddb",
Item={
"memory_key": {"S": "dietary_notes"},
"text": {"S": "Vegetarian; severe shellfish allergy..."},
"embedding": {"L": [{"N": str(float(f))} for f in vector]}, # 1024 floats
},
)
Querying uses the SearchVectors API with the same AttributeValue format:
resp = client.search_vectors(
TableName="agent-memory-demo-ddb",
IndexName="memory-vector-index",
SearchVector=[{"N": str(float(f))} for f in question_vector],
TopK=3,
)
Score note: SearchVectors returns a cosine distance (lower = more similar). The demo converts it to cosine similarity (1.0 − score) so the output is directly comparable to FAISS and S3 Vectors.
Does the index survive a restart?
Yes. It's DynamoDB. A fresh client instantiated after the demo runs still sees every item:
fresh = DynamoDBVectorStore()
fresh.count() == 10 # True — all 10 memories are there
This is the same restart test run in Part 1 for S3 Vectors. Both pass.
How do you run Test 4?
Test 4 runs as part of the existing test_vector_memory.py in the companion repo:
git clone https://github.com/elizabethfuentes12/stop-ai-agents-losing-memory-sample-for-aws
cd stop-ai-agents-losing-memory-sample-for-aws/02-vector-memory-demo
uv venv && uv pip install -r requirements.txt
uv run python test_vector_memory.py
Needs AWS credentials (aws configure) for Titan embeddings (Bedrock), S3 Vectors, and DynamoDB. The demo creates the DynamoDB table and vector index automatically if they don't exist. Requires boto3>=1.43.72 (SearchVectors was added in that release).
When do you pick DynamoDB over S3 Vectors?
| You have | Pick |
|---|---|
| No existing DynamoDB table; memory is the only use case | S3 Vectors — purpose-built for dedicated vector workloads |
| An existing DynamoDB table with user data | DynamoDB Vector Search — add the index to the same table; one service, one billing model |
| Need sub-100 ms query latency after the embedding call | DynamoDB Vector Search — single-digit ms vs ~200 ms |
| High QPS, hybrid search, or advanced filtering | Dedicated vector database (OpenSearch, Qdrant, etc.) |
FAQ
Can I add a vector index to an existing DynamoDB table?
Yes. Use update_table with VectorIndexUpdates to add the index to a table that already has data. Existing items without the embedding attribute won't appear in vector queries until you backfill their embeddings and update the items.
Does DynamoDB Vector Search work in all regions?
Check regional availability; the feature is GA but not in every region on launch day.
What's the cost compared to S3 Vectors?
DynamoDB Vector Search uses on-demand billing: you pay for read/write capacity units and storage on the table. S3 Vectors charges per query and per stored vector. For agent memory workloads (infrequent queries, small number of vectors per user) both are low cost; the deciding factor is architecture, not price.
Why does SearchVectors return a distance and not a similarity?
SearchVectors returns cosine distance (1 − cosine_similarity), where 0 means identical and 1 means opposite. The demo converts with 1.0 − score to get cosine similarity for easy comparison with FAISS (which returns inner product of normalized vectors, equivalent to cosine similarity) and S3 Vectors (which also returns 1 − distance).
Resources
- Companion repo — demo 02 with the full 4-backend test
- Amazon DynamoDB Vector Search — Developer Guide
- Amazon DynamoDB Vector Search GA announcement
- Amazon S3 Vectors — User Guide
- Amazon Titan Text Embeddings V2
- Part 1 — FAISS and S3 Vectors
Which surprised you more: the single-digit millisecond DynamoDB latency, or the fact that the cosine similarity score is identical across all four backends? Share in the comments.
Gracias!
🇻🇪 Dev.to Linkedin GitHub Twitter Instagram Youtube

Top comments (0)