15. When to use it
DynamoDB · 15. When to use itDynamoDB is excellent at a narrow job and genuinely bad at everything else, which makes this chapter easier to write than most. The difficulty is not knowing whether it fits; it is being honest about whether you know your access patterns.
The question
Section titled “The question”Do you know, today, the complete list of ways you will read this data — and will that list stay stable?
YES DynamoDB will serve it at any scale, at a price you can compute, with almost no operational work.
NO every new question is a new index, a migration or a scan. you will spend your time fighting the thing that was supposed to help.
"MOSTLY" be careful. mostly-known patterns plus a few GSIs is fine; mostly- known plus ad hoc analytics means you need a second system anyway.Everything else in this chapter is detail on that one test.
Against PostgreSQL / Aurora
Section titled “Against PostgreSQL / Aurora” POSTGRESQL WINS ON • ad hoc queries — new questions cost a SELECT • joins, aggregates, window functions, CTEs • constraints the database enforces for you • one system for OLTP and light reporting • tooling, hiring, portability • cost at small and medium scale
DYNAMODB WINS ON • predictable single-digit-ms latency at ANY size • zero operational work — no failover, vacuum, patching, or capacity planning meetings • traffic that is spiky or enormous • serverless architectures where connection pools are a genuine problem THE CONNECTION-POOL POINT IS REAL
Lambda + PostgreSQL means RDS Proxy or a pool that exhausts under scale-out. Lambda + DynamoDB is an HTTPS request. That alone decides many serverless architectures.The honest framing: PostgreSQL covers far more of the space, and a well-indexed Postgres handles more traffic than most teams will ever generate. Choose DynamoDB when the shape of the workload — key access, huge scale, spiky traffic, serverless — matches what it does.
Against Cassandra
Section titled “Against Cassandra”The most direct comparison, since they share an ancestor (chapter 1).
SAME IDEAS partition key decides placement; no joins; denormalise for the query; scale horizontally
CASSANDRA you run it. you tune consistency per query. multi-region and multi-cloud on your terms. no per-request pricing.
DYNAMODB AWS runs it. consistency is a boolean. capacity is a number you set or don't. you cannot leave AWS with it. CHOOSE CASSANDRA WHEN • you are not on AWS, or must not be locked to it • write volume is extreme and steady — the economics favour owned hardware • you have the operational capability, honestly assessed
CHOOSE DYNAMODB WHEN • you are on AWS and want nobody operating a database • traffic is spiky — you pay for what you useCassandra’s own chapter 15 argues the other side of this, and the two are consistent.
Against MongoDB
Section titled “Against MongoDB” MONGODB flexible documents AND flexible queries. secondary indexes on anything. aggregation pipeline. you can ask new questions later.
DYNAMODB flexible documents, RIGID access patterns. predictability is the product.If “we will figure out the queries as we go” describes your project, MongoDB — or PostgreSQL with JSONB — is a far more forgiving choice, and Atlas removes most of the operational argument.
Against Redis
Section titled “Against Redis” REDIS microseconds, in memory, rich data structures, durability as an option rather than a guarantee
DYNAMODB milliseconds, durable by default, unbounded size, no evictionThey are complements more often than alternatives: Redis in front for hot reads, DynamoDB behind as the source of truth — which is also what DAX (chapter 12) does, with less flexibility and API compatibility.
Against other managed key-value stores
Section titled “Against other managed key-value stores” FIRESTORE Google's equivalent. better ad hoc querying, real-time listeners; GCP lock-in instead of AWS. COSMOS DB Azure's, with multiple APIs and five consistency levels. more flexible, more complex, more expensive. SCYLLA / KEYSPACES Cassandra-compatible managed services — a middle path when you want the Cassandra model without operating it.The lock-in question
Section titled “The lock-in question”Say it plainly, because it is the objection that actually matters:
THERE IS NO SELF-HOSTED DYNAMODB. The API is proprietary, the service is AWS-only, and DynamoDB Local is a test harness, not a deployment option. HOW MUCH THIS MATTERS DEPENDS ON
① is the rest of your stack already AWS? then the marginal lock-in is small.
② how much application logic encodes the model? single-table design (ch 8) is DEEPLY specific. migrating it means rewriting your data layer, not swapping a driver.
③ what would you migrate TO? Cassandra and Scylla share the mental model, which makes them the realistic destinations. A relational target is a rewrite.Mitigations exist and are worth doing regardless: keep DynamoDB calls behind a repository interface, keep the access-pattern list current, and keep exports flowing to S3 (chapter 11) so the data itself is never trapped.
Where it is uniquely right
Section titled “Where it is uniquely right” • serverless applications at scale, where connection-based databases are the bottleneck • session stores, user profiles, shopping carts, device state — key access, huge volume • IoT and telemetry ingestion, with TTL for expiry and streams for processing • gaming leaderboards and player state • anything with unpredictable, spiky traffic where provisioning for peak would be absurd • event sourcing and outboxes, with streams doing the delivery (ch 10)Where it is the wrong answer
Section titled “Where it is the wrong answer” ✗ unknown or fast-changing access patterns ✗ reporting, BI, analytics as a primary workload ✗ anything needing joins across entities you did not model together ✗ full-text search ✗ small applications where a $20 Postgres would do ✗ teams with strong SQL skills, no AWS commitment, and modest scale ✗ workloads needing multi-region STRONG consistency — last-writer-wins is what you get (ch 11)The cost crossover
Section titled “The cost crossover”Money decides more of these arguments than architecture does, and the shape is predictable.
SMALL (< 100 req/s, < 10 GB) Postgres on a small managed instance: ~$30–60/mo DynamoDB on-demand: often < $10 → DynamoDB wins, and needs no operator
MEDIUM (steady 1,000 req/s, 100 GB) Postgres: one decent instance + a replica DynamoDB provisioned + reserved: comparable → a genuine toss-up. decide on access patterns and team skills, not cost.
LARGE (50,000 req/s, spiky, 1 TB) Postgres: sharding, read replicas, an operator or two, and a failover runbook DynamoDB: a bigger number on the bill and no additional people → DynamoDB usually wins on TOTAL cost once engineer-hours are counted
ANALYTICS-HEAVY, ANY SIZE DynamoDB + a second system for analytics → count BOTH systems. this is where DynamoDB looks cheap and the architecture is not.The last row is the one that surprises teams: the database bill falls and an Athena, ClickHouse or warehouse bill appears beside it, along with the pipeline that feeds it (chapter 10).
Migrating, in either direction
Section titled “Migrating, in either direction” POSTGRES → DYNAMODB ① list the access patterns from the query log — actual SQL in production, not the schema ② design keys (ch 8); anything that does not fit is a candidate for a second system ③ dual-write, or backfill and then switch reads ④ keep the relational database until the pattern list has been stable for a quarter
DYNAMODB → ANYTHING ELSE ① export to S3 — full, then incremental (ch 11) ② the data is DynamoDB JSON; the SHAPE is the hard part, because single-table items are heterogeneous ③ Cassandra/Scylla is the closest target; relational is a rewrite of the data layerThe argument in one paragraph
Section titled “The argument in one paragraph”DynamoDB trades flexibility for predictability, and the trade is excellent when you can name your access patterns in advance. It gives single-digit-millisecond latency that does not degrade with size, an operational burden close to zero, and a bill you can calculate from a list of queries before writing any code. It charges for that with no joins, no ad hoc questions, no aggregates, a second system for anything analytical, a data model that is deeply specific to one vendor’s product, and a design mistake — the partition key — that costs a full migration to correct. Choose it when the workload is key-access at scale on AWS, keep the access-pattern list beside the table definition, and keep exports flowing to somewhere that can answer the questions this database refuses to.
What to take from this chapter
Section titled “What to take from this chapter”- The test is whether you know the complete, stable list of access patterns. Everything else follows.
- PostgreSQL covers far more of the space and wins on ad hoc queries, joins, constraints and cost at moderate scale; DynamoDB wins on predictable latency at any size, zero operations, spiky traffic and serverless connection models.
- Cassandra shares the model: choose it to avoid lock-in or for steady extreme write volume with the operational capability; choose DynamoDB to have nobody operating a database.
- MongoDB (or Postgres with JSONB) is the forgiving choice when queries are still being discovered.
- Redis is a complement, not an alternative — hot reads in front, durable truth behind.
- Lock-in is real: no self-hosted option, and single-table design encodes the vendor’s model deep in your application. Mitigate with a repository boundary, a current pattern list, and continuous S3 exports.
- It is uniquely right for serverless at scale, session and profile stores, IoT ingestion, gaming state, spiky traffic and event sourcing.
- It is wrong for unknown patterns, analytics, joins, search, small applications, and multi-region strong consistency.
Next: the cheat sheet — limits, costs, commands, expressions and error messages on one page.