ExtendDB is an independent open source project managed by Amazon Web Services. It is not Amazon DynamoDB and does not contain any DynamoDB source code. "DynamoDB" is a trademark of Amazon.com, Inc. ExtendDB is a clean-room implementation that speaks the DynamoDB wire protocol. Behavioral differences from the real service are documented in Differences from DynamoDB.
A DynamoDB-compatible API adapter, ExtendDB speaks the DynamoDB wire protocol — any AWS SDK, CLI, or tool that works with DynamoDB works with ExtendDB, unchanged.
- Local development — run DynamoDB workloads on your laptop with zero cloud dependency
- CI/CD pipelines — deterministic integration tests against a DynamoDB-compatible backend
- Self-hosted deployments — run DynamoDB workloads on your own infrastructure (on-premises, private cloud, edge)
- Multi-cloud — use DynamoDB semantics on any cloud that runs an ExtendDB-supported database backend
- Air-gapped environments — DynamoDB functionality with no internet connectivity
- Full DynamoDB wire protocol: CRUD, Query, Scan, Batch, Transactions, Streams, TTL, Import/Export
- Pluggable storage: PostgreSQL (default), SQLite, MongoDB, and Cassandra
- SigV4 authentication with IAM compatibility: users, groups, roles, policies, permissions boundaries
- Web management console for account and credential administration
- TLS with automatic self-signed certificate generation (replaceable with CA-signed certs)
- CSRF protection, security headers, session management
- JSON metrics endpoint with DynamoDB CloudWatch-style metric names and dimensions
- Daemon mode with syslog logging, plus
--foregroundfor container and supervisor environments
# Build
cargo build --release
# Initialize (creates databases, admin credentials, TLS cert, config file)
./target/release/extenddb init
# Start
./target/release/extenddb serve --config extenddb.toml
# Use with any AWS SDK (TLS with self-signed cert — trust via AWS_CA_BUNDLE)
export AWS_CA_BUNDLE=~/.extenddb/tls/cert.pem
aws dynamodb list-tables --endpoint-url https://127.0.0.1:18443 --region us-east-1See Getting Started for the full walkthrough, or use the platform installer scripts:
scripts/install-linux.sh # Linux
scripts/install-macos.sh # macOS- Rust 1.88+ (
rustup update) - Python 3.10+ (for test suites and documentation)
- A storage backend:
- PostgreSQL 14+ (see
docs/local-postgres-setup.md) - SQLite (embedded)
- MongoDB 7+ (see
docs/local-mongodb-setup.md) - Cassandra 4.1+ (see
docs/cassandra-setup.md)
- PostgreSQL 14+ (see
python3 -m venv ~/venvs/extenddb-venv
source ~/venvs/extenddb-venv/bin/activate
pip install -r requirements.txtExtendDB ships with builtin IAM-like authentication enabled by default. All requests must be signed with valid SigV4 credentials created via the management API.
| Mode | Config | Description |
|---|---|---|
| Builtin IAM-like | auth.provider = "builtin" |
Full SigV4 signature verification with local credential store and IAM policy evaluation. This is the default and only supported mode. |
extenddb init generates extenddb.toml automatically. See extenddb.sample.toml for all keys, defaults, and descriptions.
Environment variable overrides use the EXTENDDB__ prefix:
export EXTENDDB__SERVER__PORT=9000
export EXTENDDB__AUTH__PROVIDER=builtinRuntime settings (no restart required):
extenddb settings --config extenddb.toml set log_level debugTLS is mandatory. extenddb init generates a self-signed certificate at ~/.extenddb/tls/cert.pem. The server refuses to start with TLS disabled.
To use the self-signed cert with AWS CLI and SDKs, set AWS_CA_BUNDLE:
export AWS_CA_BUNDLE=~/.extenddb/tls/cert.pemReplace with a CA-signed certificate for production:
[server.tls]
cert_path = "/etc/extenddb/tls/cert.pem"
key_path = "/etc/extenddb/tls/key.pem"The production images contain ExtendDB only. The storage backend runs as a separate service. See
docker/README.md for the PostgreSQL image and docker/README-mongodb.md for the MongoDB image,
external database requirements, hardened local Compose stacks, smoke tests, and explicit init/migrate/serve
production lifecycle. The SQLite and Cassandra backends have no dedicated container guide yet.
By default extenddb serve daemonizes itself, which doesn't play well with container runtimes and process supervisors that expect PID 1 to stay attached. Pass --foreground (alias --no-daemon) to keep the process in the foreground and stream logs to stderr instead of syslog:
extenddb serve --config extenddb.toml --foregroundUse this with Docker, Kubernetes, systemd Type=simple, runit, s6, or any other supervisor that captures stdout/stderr.
In --foreground mode extenddb writes no PID file and never creates run_dir, so the container can run with a read-only root filesystem. Two consequences:
extenddb statusstill works (it probes the port) but reports the PID as unknown.extenddb stopcannot signal the process — there is no PID file to read. Stop it through your supervisor, which deliversSIGTERMand triggers the same graceful shutdown.
Pass --write-pid-file to opt back in when you do want stop and status to work against a foreground server, for example when running it from a shell rather than under a supervisor. The file goes to the usual run_dir path, so neither command needs extra arguments, and run_dir has to be writable.
For a container HEALTHCHECK, use the healthcheck subcommand rather than curl; it needs no shell or extra binaries, so it works on a distroless/scratch image and accepts the self-signed certificate:
extenddb healthcheck --config extenddb.toml # exit 0 healthy, 1 not
extenddb healthcheck --endpoint https://127.0.0.1:18443 # explicit targetThis is a liveness check, which is what a container HEALTHCHECK wants. The /health path does not query the storage
backend, so it will report healthy even if the storage backend becomes unreachable after startup. That is deliberate,
since a liveness probe that failed on a database outage would restart every replica at once. A backend that is
unreachable at startup does stop the server from listening. There is no separate readiness endpoint yet.
Run one extenddb serve per catalog. On SQLite this is enforced: the server takes an exclusive lock on <database>.lock
next to the database file and a second server on the same file will refuse to start (init, migrate, and destroy take
the same lock while they run). On PostgreSQL, MongoDB and Cassandra nothing prevents a second ExtendDB instance from
running, but running more than one against the same catalog is not supported in this release: every instance runs every
background worker, credential and policy caches are per instance with no cross-instance invalidation (a revoked key
stays valid on the other instance for up to the cache TTL), and /health does not check the database.
See the deployment guide.
To make the generated self-signed certificate valid for the name clients use — an in-cluster service DNS name, for example — pass --tls-san to init (repeatable):
extenddb init --catalog-db extenddb_catalog \
--tls-san extenddb.default.svc.cluster.local --tls-san extenddb.example.cominit never regenerates an existing certificate, so if one is already present it verifies that it already covers every requested --tls-san and fails with an explicit error if it does not, rather than silently dropping the name.
# Health check
curl --cacert ~/.extenddb/tls/cert.pem https://127.0.0.1:18443/health
# JSON metrics (DynamoDB CloudWatch-style)
curl --cacert ~/.extenddb/tls/cert.pem https://127.0.0.1:18443/metrics
# Syslog (Linux)
journalctl -t extenddb -f
# Syslog (macOS)
log stream --predicate 'processImagePath ENDSWITH "extenddb"' --level infoWeb-based administration at https://127.0.0.1:18443/console/. Manage accounts, users, groups, roles, policies, and access keys through a browser. Accept the self-signed certificate warning on first visit.
extenddb serve --config extenddb.toml # Start server (daemon)
extenddb serve --config extenddb.toml --foreground # Start in foreground
extenddb init --catalog-db NAME # Initialize deployment
extenddb stop --config extenddb.toml # Graceful shutdown
extenddb status --config extenddb.toml # Check if running
extenddb healthcheck --config extenddb.toml # Probe /health (exit 0 healthy, 1 not)
extenddb verify --config extenddb.toml # Validate deployment
extenddb migrate --config extenddb.toml # Apply schema migrations
extenddb destroy --config extenddb.toml # Tear down deployment
extenddb settings --config extenddb.toml list # List runtime settings (secrets masked)
extenddb manage --user admin --password <pw> <subcommand> # IAM management
See Admin Guide for the full CLI and management API reference.
CreateTable, DeleteTable, DescribeTable, ListTables, UpdateTable, DescribeEndpoints, DescribeLimits
PutItem, GetItem, DeleteItem, UpdateItem (SET, REMOVE, ADD, DELETE actions; condition expressions; all ReturnValues modes)
Query, Scan (key conditions, filters, projections, pagination, index selection)
BatchGetItem (100 keys), BatchWriteItem (25 ops), TransactGetItems (100 items), TransactWriteItems (100 ops)
SearchVectors, and vector indexes on CreateTable and UpdateTable (cosine, Euclidean and dot product; on-demand tables only). On PostgreSQL this requires the pgvector extension on the data database; without it every vector operation is refused and nothing else is affected.
ListStreams, DescribeStream, GetShardIterator, GetRecords
UpdateTimeToLive, DescribeTimeToLive, TagResource, UntagResource, ListTagsOfResource, ImportTable, ExportTableToPointInTime
crates/
auth/ — SigV4 verification, IAM policy engine
bin/ — CLI, config, daemon lifecycle
core/ — types, validation, expressions (pure sync Rust, no async)
engine/ — operation handlers
server/ — HTTP server, management API, web console
storage/ — storage trait definitions
storage-cassandra/ — Cassandra backend (experimental)
storage-mongodb/ — MongoDB backend
storage-postgres/ — PostgreSQL backend (default/reference)
storage-sqlite/ — SQLite backend (embedded)
docs/
adr/ — architecture decision records
design/ — architecture and design documents
manuals/ — user-facing guides (PDF pipeline)
| Document | Description |
|---|---|
| Getting Started | Full setup walkthrough |
| Architecture Guide | System design and crate structure |
| Admin Guide | Server lifecycle, configuration, IAM management |
| Security Model | Threat model, authentication, authorization |
| Deployment Guide | Self-hosted, multi-cloud, air-gapped deployments |
| Differences from DynamoDB | Behavioral differences and unsupported operations |
| Troubleshooting | Common errors and solutions |
Build PDFs:
python3 docs/build-docs.pyContributions are welcome. See CONTRIBUTING.md for build, test, and code-style requirements.
ExtendDB uses two lightweight processes for tracking decisions:
- ADRs record decisions that have been made.
- RFCs propose changes that affect the wire protocol, storage trait, auth model, on-disk format, public CLI, or any significant new feature or subsystem. Substantial changes go through an RFC before implementation.
Adding a storage backend? Start with RFC-0002: Backend Plugin Policy and the Backend Acceptance Criteria.
Code in protected paths is reviewed via .github/CODEOWNERS.
Copyright 2026 ExtendDB contributors. Licensed under the Apache License, Version 2.0. See LICENSE for the full text.
This software is provided "as is" without warranty of any kind.