DEV Community

Cover image for ExtendDB: Run the DynamoDB API on Your Database
DynoTable
DynoTable

Posted on Originally published at dynotable.com

ExtendDB: Run the DynamoDB API on Your Database

Say a hospital records system has to stay inside the building — patient data can
never leave the on-prem network, an auditor signs off on every dependency, and
the dev laptops have no internet at all. The team already wrote the application
against the DynamoDB API and likes it: single-digit-millisecond key lookups, a
clean item model, no schema migrations to babysit. But managed DynamoDB is a
cloud service, and "send the data to AWS" is a non-starter here.

ExtendDB is built for exactly that gap. It speaks the
DynamoDB wire protocol but stores the data in a database you run.

What is ExtendDB?

ExtendDB is AWS's open-source adapter (written in Rust) that implements the DynamoDB JSON wire protocol on top of a database you run yourself, such as PostgreSQL. Your existing AWS SDKs and the AWS CLI keep working unchanged — only the endpoint URL moves — so you get the DynamoDB API without sending data to the managed cloud service.

ExtendDB is an open-source adapter from AWS — written by AWS DynamoDB engineers
and
announced on the AWS Database Blog
that implements the DynamoDB JSON wire protocol in Rust. Because it
answers the same HTTP API the managed service does, your existing AWS SDKs and
the AWS CLI work unchanged. The only thing that moves is the endpoint URL —
no code rewrite, no new client library.

The interesting part is what sits behind that API. ExtendDB has pluggable
storage backends
: PostgreSQL is the reference implementation, and Cassandra is
cited as another possible backend. New backends are
implemented without modifying the core, so the DynamoDB-compatibility layer
and the storage layer evolve independently.

So a request flows like this:

ExtendDB: Run the DynamoDB API on Your Database

What it supports — and what it doesn't

Per the getting-started docs and the announcement,
ExtendDB (v0.1) covers the operations most applications actually call:

  • Tables — Create, Delete, Describe, List, Update.
  • Items — Put, Get, Delete, Update (including the SET / REMOVE / ADD / DELETE update actions).
  • Query and Scan — key conditions, filter expressions, projections, pagination, and secondary indexes.
  • BatchBatchGetItem and BatchWriteItem.
  • TransactionsTransactGetItems and TransactWriteItems.
  • Streams, TTL, Import/Export, and Tags.

What it deliberately does not implement is the set of
DynamoDB-specific managed features — most notably Global Tables and
cross-Region replication. Those are properties of the managed service's
global infrastructure, not of the API surface, so they don't carry over to an
adapter you host yourself.

vs DynamoDB Local

You may already use
DynamoDB Local for offline development. That's a single
JAR (or amazon/dynamodb-local Docker image) meant for unit tests on one
machine. ExtendDB aims broader than that single-process tool: local
development, on-prem deployments, edge and air-gapped environments, and
hybrid / multi-cloud setups where you want the DynamoDB API but the data lives in
infrastructure you control.

vs managed DynamoDB

This is the line AWS draws explicitly, and it matters:

ExtendDB is not DynamoDB. It is a compatible implementation, not a replacement
for the managed service. Performance characteristics, scaling behavior, and
operational properties differ.

Concretely, when you run ExtendDB:

  • You own the database's availability and backups. There's no managed multi-AZ durability or point-in-time recovery doing it for you — that's on you and your PostgreSQL operations.
  • TLS is mandatory on the endpoint.
  • Credentials are IAM-like but separate from AWS IAM — ExtendDB has its own credential model; it does not authenticate against your AWS account.

It's v0.1 and licensed Apache 2.0. Treat it as early software: great for
the environments above, not a drop-in swap for production-scale managed DynamoDB.

ExtendDB itself meters no RCU or WCU — capacity is your PostgreSQL's problem. When
the same API calls hit managed DynamoDB in us-east-1 on-demand, a 1 KB
PutItem bills 1 WCU and a 4 KB GetItem bills 0.5 RCU
eventually-consistent. Benchmark ExtendDB for latency; use the
pricing calculator to compare what the cloud
bill would look like for the same access pattern.

Setup

ExtendDB runs on Linux and macOS and needs Rust 1.85+ and
PostgreSQL 14+. The flow is two commands:

extenddb init
extenddb serve
Enter fullscreen mode Exit fullscreen mode

init provisions the schema in your PostgreSQL database; serve starts the
wire-protocol server, which listens on an endpoint like https://127.0.0.1:8000
(TLS is required, hence https).

Point the AWS SDK at it the same way you would any custom endpoint — only the URL
and the credentials change:

import {DynamoDBClient} from '@aws-sdk/client-dynamodb';

const client = new DynamoDBClient({
  endpoint: 'https://127.0.0.1:8000',
  region: 'local',
  credentials: {accessKeyId: '<extenddb-key>', secretAccessKey: '<extenddb-secret>'}
});
Enter fullscreen mode Exit fullscreen mode

Everything past the client config — PutItem, Query, TransactWriteItems
is identical to the code you'd write against managed DynamoDB. A single-table
item layout works exactly as it does in the cloud:

PK SK type backend createdAt
TENANT#acme AUDIT#2026-06-24 event postgres 2026-06-24T09:00:00Z
TENANT#acme AUDIT#2026-06-24b event postgres 2026-06-24T09:01:12Z
TENANT#beta AUDIT#2026-06-24 event postgres 2026-06-24T09:02:40Z

Do it in DynoTable

Because ExtendDB speaks the DynamoDB wire protocol, you don't need a separate
admin tool for it — point DynoTable at the ExtendDB endpoint the
same way you'd connect it to
DynamoDB Local: create an offline
(local) profile
with the ExtendDB port and throwaway credentials, and DynoTable
will browse, query, and edit the items — except now they're backed by PostgreSQL
on your own disk instead of a JAR's in-memory store.

This is the payoff of wire-protocol compatibility: the
SQL Workbench, the visual query builder, and item
editing all work against ExtendDB unchanged, so you get a real GUI over your
self-hosted data without writing scan scripts.

One caveat to plan for: ExtendDB's endpoint is HTTPS-only, while DynoTable's
offline profile (like most DynamoDB-Local setups) targets a loopback
host:port. If your client or tooling needs a plaintext loopback listener,
terminate TLS in front of ExtendDB (or run a local reverse proxy) and point the
GUI at that — the protocol on the wire is still DynamoDB JSON either way.

Pitfalls

  • Don't treat v0.1 as production DynamoDB. Scaling, latency, and durability are your PostgreSQL's, not AWS's. Benchmark for your workload before you depend on it.
  • No Global Tables / cross-Region replication. If your design relies on multi-Region active-active, ExtendDB isn't the path — that's a managed-service feature.
  • Back up the underlying database yourself. There's no managed PITR; a dropped PostgreSQL volume is gone. Wire up pg_dump / WAL archiving like any other PostgreSQL.
  • Credentials are ExtendDB's own, not AWS IAM. Don't expect IAM policies, roles, or condition keys to govern access — that authorization model doesn't carry over.

Next steps

  • Model your access patterns first — the same single-table design discipline applies whether the backend is DynamoDB or PostgreSQL-via-ExtendDB.
  • Build and inspect your reads and writes with the DynamoDB Expression Builder, then convert fixtures between plain JSON and the wire format with the DynamoDB-JSON converter.
  • When you're ready to poke at a live ExtendDB instance, connect DynoTable and browse it like any other table.

Top comments (0)