database

Amazon DynamoDB

Serverless NoSQL with single-digit-millisecond latency at any scale — no servers, no joins. Here's when DynamoDB fits, what it costs, how it connects to Lambda and EC2, and the modeling mistakes Design Beaver catches as you draw.

Updated July 12, 2026

What DynamoDB is

DynamoDB is a serverless, fully managed NoSQL key-value and document database with single-digit-millisecond performance at any scale. There are no servers to provision or patch, and no joins — you denormalize your data and access it by key rather than querying it relationally. You design the table around the access patterns you know you’ll have, then scale to zero or to near-limitless throughput without touching a server.

Design Beaver models DynamoDB as a regional, API-accessed service that isn’t subnet-resident, and validates as you draw what can trigger it, what can read it, and whether the connection is set up correctly.

When to use DynamoDB (and when not to)

Reach for DynamoDB when your access patterns are known in advance and are mostly lookups by key, when you need predictable low latency regardless of scale, and when you’re building serverless and don’t want to manage instances, patching, or capacity.

Don’t reach for it when the application needs joins, ad-hoc queries across entity types, or reporting directly against live data — that’s a relational database or a warehouse. It’s also the wrong first choice when the data model isn’t settled: DynamoDB wants the table designed around known access patterns up front, and reworking that later is real work. And remember global secondary indexes are always eventually consistent, so it’s a poor fit if you need strong consistency across them.

Variants: capacity mode and table class

DynamoDB has no instance sizes. The choices that matter are capacity mode — how you pay for throughput — and table class — how you pay for storage.

OptionWhat it is
On-demand capacity modedefaultPay-per-request pricing with no capacity planning; scales instantly (including to zero) but costs more per request than well-utilized provisioned capacity.
Provisioned capacity modeReserve read/write capacity units (RCU/WCU) ahead of time, optionally with auto scaling. Cheaper at steady, predictable traffic; requires capacity planning.
DynamoDB Standard (table class)defaultDefault table class for typical workloads.
DynamoDB Standard-Infrequent Access (table class)Lower storage price, higher read/write request price — for tables holding data that is rarely accessed but where storage cost dominates the bill.

DynamoDB pricing

You pay for throughput plus storage. On-demand keeps it simple and scales to zero; provisioned with auto scaling gets materially cheaper once traffic is steady. One cheap habit: default to eventually consistent reads, which cost half of strongly consistent ones.

Two capacity modes: on-demand (pay per read/write request) or provisioned (pay per reserved RCU/WCU-hour, optionally with auto scaling). Storage billed per GB/month on top of either mode.

OptionRepresentative rate
on-demand$0.125 per million read request units; $0.625 per million write request units (Standard table class)
provisioned$0.00013 per RCU-hour; $0.00065 per WCU-hour (Standard table class); reserved capacity discounts up to ~54% (1-yr) or ~77% (3-yr)
standard-table-class$0.25/GB-month storage (after the 25 GB free tier)
standard-ia-table-class$0.10/GB-month storage; higher per-request pricing than Standard

Free tier

  • Always Free: 25 GB storage
  • Always Free: 25 provisioned WCUs and 25 provisioned RCUs (enough for roughly 200M requests/month)

Keeping the bill down

  • Use on-demand for spiky or unpredictable traffic, or new tables where the access pattern isn't proven yet
  • Switch to provisioned + auto scaling once traffic is steady and predictable — materially cheaper at sustained utilization
  • Eventually consistent reads cost half of strongly consistent reads — default to eventual unless the read genuinely needs the latest write

us-east-1 (rates vary by region). Rates as of 2026-07. Verify at the official pricing page before using for real cost estimates — this list is not kept in sync with AWS pricing changes.

How DynamoDB connects to other services

DynamoDB earns its place in a serverless architecture through two edges — a stream that triggers compute, and an SDK client that reads and writes it. Each has a requirement that makes it work, and Design Beaver models both.

  • DynamoDB Streams triggers a Lambda function on item-level changes (insert/update/delete) — the canonical event-driven pairing with DynamoDB

  • EC2

    An application running on EC2 reads/writes DynamoDB table items via the AWS SDK

What DynamoDB can’t connect to

DynamoDB is an API endpoint, not an HTTP origin or a DNS target — so several edges that look reasonable on a canvas aren’t real integrations. Design Beaver flags them.

  • DynamoDB is a database API endpoint, not an HTTP content origin — CloudFront distributions serve cached content from origins like S3, ALB, or API Gateway, never a DynamoDB table directly

  • DynamoDB has no DNS-addressable endpoint that a domain resolves to — a table is reached through the AWS SDK/API, not through a hostname a Route 53 record would point at

  • RDS

    DynamoDB and RDS are peer database services with no direct integration between them — an application chooses one or the other (or uses both independently) rather than connecting them together as an architectural edge

  • S3

    No standing architectural connection — DynamoDB's export-to-S3 and import-from-S3 features are one-off/scheduled operations invoked through the API or console (and require point-in-time recovery to be enabled for export), not a persistent connection comparable to a Lambda trigger or an SDK client relationship

Anti-patterns Design Beaver catches

These are the DynamoDB mistakes that come from bringing a relational mindset to a NoSQL database — the ones that pass a design review and then throttle or overspend in production.

Modeling a DynamoDB table the way you would a relational schema (one table per entity type, normalized, expecting joins)

Why it breaksDynamoDB has no JOIN operator and charges per request — a normalized multi-table design causes excessive round trips and defeats the single-digit-millisecond performance model it's built for

Do this insteadDesign the table around known access patterns first (single-table design where appropriate), denormalizing data to fetch what's needed in one request

Using Scan operations as the primary way to read data

Why it breaksScan reads every item in the table (or index) and filters client-side — it consumes far more read capacity than a targeted Query and gets slower as the table grows

Do this insteadDesign partition/sort keys and secondary indexes so the real access patterns can be served with Query, reserving Scan for infrequent batch/analytics use

Choosing a partition key with low cardinality or uneven access (e.g. a status field with only a few values)

Why it breaksCauses hot partitions — traffic concentrates on a small number of physical partitions, throttling requests even though the table's overall provisioned/on-demand capacity looks sufficient

Do this insteadPick a partition key with high cardinality and even access distribution across the expected traffic pattern

Gotchas that bite in production

  • No joins, on purpose. Coming from a relational mindset, the instinct to normalize into many small tables will hurt you — DynamoDB rewards denormalized, access-pattern-driven design, and that has a real learning curve.
  • Eventually consistent by default. A read may not reflect a very recent write unless you explicitly ask for a strongly consistent read — which costs twice the read capacity and isn’t available on global secondary indexes at all.
  • Hot partition keys throttle you even when overall capacity looks fine. A low-cardinality or unevenly-accessed partition key concentrates traffic on a few physical partitions. The fix is a better key, not more capacity.
  • Streams have a subscriber limit. More than 2 Lambda functions subscribed to the same DynamoDB stream can cause read throttling on the stream itself.

Further reading

Frequently asked questions

When should you use Amazon DynamoDB?
Use DynamoDB when your access patterns are known up front and mostly key-based lookups, when you need predictable single-digit-millisecond latency at any scale, and when you want a serverless database with no instances to manage. It's a poor fit when you need joins, ad-hoc relational queries, or complex reporting — a relational database like RDS fits better — or when your data model is still changing frequently.
How much does Amazon DynamoDB cost?
DynamoDB has two capacity modes — on-demand (pay per read/write request) or provisioned (pay per reserved capacity unit, optionally with auto scaling) — plus per-GB storage. There's an always-free tier for storage and provisioned capacity. Eventually consistent reads cost half of strongly consistent ones. Verify the current figures and rates on the official pricing page before estimating.
How does DynamoDB connect to Lambda?
Two ways. DynamoDB Streams can trigger a Lambda function on item-level changes (insert, update, delete) — the canonical event-driven pairing — and Lambda can read and write table items via the SDK, the typical serverless API backend. Streams must be enabled on the table first, and no more than 2 functions should subscribe to the same stream or you risk read throttling.
Should you use Scan to read data in DynamoDB?
Only for occasional batch work. Scan reads every item in the table or index and filters client-side, so it burns far more read capacity than a targeted Query and gets slower as the table grows. Design your keys and secondary indexes so real access patterns are served by Query. Design Beaver's anti-pattern checks flag Scan-as-primary-access designs.

Validate your DynamoDB architecture as you draw

Design Beaver checks your AWS design in real time — missing queues, invalid connections, and security anti-patterns, caught before you ship. It’s live in beta, free, and runs in your browser with no account.

Open the app →

Prefer email? Get new features in your inbox:

← All supported services