strands-dynamodb-storage (Python)
Python implementation of the Amazon DynamoDB Storage backend for the Strands Agents SDK — at
parity with ../typescript/. Implements the SDK's strands.storage.Storage protocol
(write/read/delete/list, plus namespace) so one DynamoDB-backed instance serves Session
Manager, Memory Manager, and any subsystem that persists bytes.
Install
pip install strands-dynamodb-storage
Usage
from strands import Agent
from strands.session import SnapshotSessionManager
from strands_dynamodb_storage import DynamoDBStorage
storage = DynamoDBStorage("agent-data", region_name="us-east-1")
agent = Agent(session_manager=SnapshotSessionManager(storage=storage))
The same instance backs any subsystem that accepts a Storage, for example offloading oversized
tool results with the context offloader:
from strands import Agent
from strands.vended_plugins.context_offloader import ContextOffloader
agent = Agent(plugins=[ContextOffloader(storage=storage)])
Direct byte usage (async):
store = DynamoDBStorage("agent-data", region_name="us-east-1")
await store.write("sessions/s1/snapshot.json", b'{"turn": 1}')
data = await store.read("sessions/s1/snapshot.json") # bytes | None
keys = await store.list("sessions/s1/") # native Query
# Note: prefixes must cover at least a full scope and identifier ("scope/id/").
# list("") and single-segment prefixes are rejected as too broad -- they would
# require a cross-partition Scan. This deliberately narrows the SDK Storage
# contract (whose in-memory backends list everything on ""); SDK subsystems
# always pass namespaced prefixes and are unaffected.
scoped = await store.list(DynamoDBListQuery(pk="sessions/s1", sk_prefix="scopes/"))
await store.delete("sessions/s1/snapshot.json")
Features (parity with the TypeScript package)
- Single-table design (
pk/sk), with a structuredDynamoDBListQueryextension point. - Optional Amazon S3 offload for values above the item-size limit (
s3_bucket=...). - Optional gzip
compression="gzip"(applied before the offload check). - Optional per-item TTL (
ttl_seconds=...) with read/list expiry filtering (search does not filter; see below). - Native vector
search()via Amazon DynamoDB vector indexes (SearchVectors, requires boto3 >= 1.43.64); avector_searchadapter can override the call.
Semantic search
search() gives an agent semantic long-term memory over the same table: write each memory
with its embedding, then query by meaning. Scoring runs in the database against a DynamoDB
vector index (no second vector store, no ETL), and because the index is partitioned on pk,
every search is scoped to the caller's key space -- one tenant's memories can never surface
in another's results. Creating the table with a vector index (and the IAM permissions needed)
is covered in the repository README's Provisioning and permissions.
Two behaviours to know: pk is required whenever the index's SearchSchema declares a HASH
element (the provisioning guide's setup does) and must be omitted when it doesn't. And because
TTL deletion is asynchronous, search() can briefly return items whose expiry has passed but
which DynamoDB has not yet physically deleted -- expiry filtering applies to read/list only.
from strands_dynamodb_storage import DynamoDBStorage, SearchQuery
store = DynamoDBStorage("agent-memory", region_name="us-east-1", prefix="user/u1")
# store a memory with its embedding (kept inline even when the payload offloads to S3)
await store.write(
"memories/m1",
b"likes window seats",
vector=embed("likes window seats"), # your embedding model, e.g. 1024 floats
metadata={"kind": "preference"},
)
# recall by meaning, scoped to this store's partition
results = await store.search(SearchQuery(
vector=embed("seating preferences?"),
top_k=5,
pk="user/u1", # the physical partition: the full key's first two segments
filter={"kind": "preference"}, # optional metadata equality filter
include_values=True, # hydrate each match's stored bytes
))
for r in results:
print(r.key, r.score, r.data)
# ordered most-similar-first; score direction follows the index's distance function
# (COSINE/EUCLIDEAN: lower = nearer; DOT_PRODUCT: higher = more similar)
Like a global secondary index, the vector index is eventually consistent, and a freshly
created index backfills before it is searchable. Requires boto3 >= 1.43.64; a
vector_search adapter, when configured, overrides the native call (testing, custom routing).
Examples
Runnable, live-verified examples for every capability, from session resume to a customer-support capstone, live in the examples library.
Development
python -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/python -m pytest -q # unit tests (moto, offline)
.venv/bin/ruff check src tests && .venv/bin/mypy src
RUN_INTEG=1 AWS_REGION=us-east-1 .venv/bin/python -m pytest tests/integ -q # real DynamoDB + S3
Metadata
Release files for strands-dynamodb-storage 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| strands_dynamodb_storage-0.1.2.tar.gz | 26.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| strands_dynamodb_storage-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 45.1 kB
Release files / strands_dynamodb_storage-0.1.2.tar.gz
| Download URL | strands_dynamodb_storage-0.1.2.tar.gz |
|---|---|
| Size | 26.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f61b35a6289b4651ffd9b2e1961f033a99c38b7f4470643916c511ef1e13db6e
|
|
BLAKE2b-256 checksum How to use checksums |
a571c093e71f9b27bb6e5c74de475178d59bee42abf4f8d9102ca73775b22bf9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.
Transparency logRelease files / strands_dynamodb_storage-0.1.2-py3-none-any.whl
| Download URL | strands_dynamodb_storage-0.1.2-py3-none-any.whl |
|---|---|
| Size | 19.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0d71578fc8cbb832b70b831ff11a22cd4ba2cbf7f435ead9f419162af6ea8c4e
|
|
BLAKE2b-256 checksum How to use checksums |
798aca1adad39eb26cf6ad44659bf80781d475130a69064da16cd4ccc52ea0bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.
Transparency log