Intermediate6 min read

When NOT to Use Single-Table Design in DynamoDB

Single-table design is the default advice for DynamoDB, and it earns it: one Query hands back a parent and its children, no joins, no N+1.

But it is a trade — you buy read speed with a rigid, opaque schema. Some workloads can't afford that price, and forcing one table on them is its own footgun.

When should you not use single-table design in DynamoDB?

Avoid single-table design when your workload is heavy analytics, plain CRUD over a handful of unrelated entities, or entities that scale and fail independently. In those cases multiple tables read better, cost the same, and stay flexible. Single-table design only wins when access patterns are known, related, and high-volume.

  • Heavy analytics? Don't single-table. Overloaded keys are OLAP-hostile — export to a columnar store and query there instead.
  • Plain CRUD with a handful of access patterns? One table per entity is fine, readable, and costs you nothing in performance.
  • Entities that scale or fail independently? Separate tables let you tune, bill, and blast-radius them on their own.
  • Single-table still wins when your patterns are known, related, and high-volume — that's the case it was built for.

Know what single-table actually costs

Single-table design isn't free; it just moves the cost off the read path and onto everything else. You pay in legibility and flexibility.

A table holding five entity types behind PK/SK is hard to read, hard to onboard onto, and hard to change. A new access pattern can mean a backfill across every item type in the partition.

So the question isn't "is single-table good?" It's "do my access patterns justify the rigidity?" When they don't, reach for multiple tables.

Don't single-table an analytics workload

DynamoDB is built for OLTP — small, known, point-and-range reads. Analytics is OLAP: GROUP BY, big aggregates, ad-hoc slicing across the whole dataset. The two pull in opposite directions.

Single-table design makes OLAP worse, not better. Overloaded keys and mixed entity types mean an analytics job must first untangle which item is which before it can sum anything — the opposite of a clean columnar scan.

Coming from SQL, the reflex is to write the aggregate against the live table. In DynamoDB that's a full Scan — you pay for and read every item, which is the Scan footgun at full volume.

The fix isn't a cleverer key. It's a different store. AWS's own guidance is to export DynamoDB to S3 and run analytics with a query engine like Athena.

Keep OLTP and OLAP on separate engines (AWS DynamoDB Developer Guide, S3DataExport.html).

Don't single-table simple CRUD

If your app reads and writes a few unrelated entities by their own id, and you have maybe three access patterns, single-table buys you nothing.

Take a Tenants table and an ApiKeys table for a small B2B tool:

Tenants
TenantIdNamePlanTier
TNT-8842Northwindpro
ApiKeys
KeyIdTenantIdScope
KEY-01H9...TNT-8842read-write

Each query is a GetItem by id, or a Query on a GSI keyed by TenantId. There's no parent-and-children fetch to optimise, so there's nothing for an overloaded partition to win. Two clear tables read better than one murky one.

The trap is cargo-culting single-table because it's "best practice." Best practice is access-pattern-first. If the patterns are trivial, the simple shape is the right shape.

Split tables that scale or fail independently

A single table shares one throughput surface, one backup, one blast radius. When two entities have wildly different write rates or durability needs, that shared fate becomes a liability.

Picture a fleet-tracking system. Vehicles change rarely; their telemetry pours in every second:

Vehicles (cold, low write rate)
VehicleIdMakeModelRegion
VEH-204VolvoFH16eu-west
Telemetry (hot, high write rate, TTL'd)
DeviceTsVehicleIdSpeedKphFuel
2026-06-23T10:00:01ZVEH-204880.61

Two tables let you provision telemetry for a firehose, keep vehicles tiny and cheap, set a TTL on telemetry alone, and stop a telemetry write storm from throttling reads of the vehicle catalogue. One table couples all of that.

Per the 2007 Amazon Dynamo paper, partitioning and availability are first-class concerns — independent tables give you independent control over both.

Map the decision before you commit

Walk the workload through one gate: are the entities related, and are the patterns known and high-volume? If not, multiple tables.

Here's the call as a flow — start at the top and follow the first branch that matches:

YesNoNoYesNoYesNew workloadHeavy analyticsor OLAP?Separate store(export + Athena)Entities related+ fetched together?Multiple tables(simple CRUD)Known,high-volumepatterns?Multiple tables(stay flexible)Single-tabledesign

Only the bottom-right leaf earns single-table; every other path is better served by more than one table.

Single vs multiple, head to head

FactorSingle-tableMultiple tables
Related readsOne Query, no joinsClient-side join or extra round-trips
ReadabilityOpaque overloaded keysOne entity per table, self-documenting
New access patternOften a backfillAdd a table or GSI in isolation
Analytics / OLAPHostile — untangle before aggregatingStill export, but cleaner per-entity
Independent scalingShared throughput + blast radiusTune, bill, TTL, and back up separately
Best whenKnown, related, high-volume patternsUnrelated, evolving, or analytical

Pitfalls + next steps

The mirror-image mistake is over-correcting — splitting genuinely related, high-volume entities into a table-per-entity and rebuilding SQL-style joins in your app. That's the N+1 trap single-table kills.

Pick the shape the access patterns ask for, not the dogma.

When you do model relationships, lean on the right index type — see GSI vs LSI before you add one.

When you do write a query against a multi-table schema, sketch the KeyConditionExpression in the DynamoDB Expression Builder first.

That way you catch a full-Scan shape before it hits production.

Then try DynoTable to browse both shapes against your own tables and see which one your access patterns actually want.

Updated

Try this design interactively

Sketch your entities and access patterns in the free DynamoDB Single-Table Design tool — it suggests PK/SK key templates, previews the item collections, and shows which patterns need a GSI.

Open the Single-Table Design tool