Amazon DynamoDB

Amazon DynamoDB - The Architecture Behind Single-Digit-Millisecond Scale

Amazon DynamoDB – The Architecture Behind Single-Digit-Millisecond Scale

A practitioner-level walkthrough of how DynamoDB actually partitions data, enforces consistency, handles hot keys, and executes transactions — the internals that shape every real production data-modeling decision.

If you already know what a NoSQL key-value store is and understand basic DynamoDB terms like tables and items, this guide moves past that. We’re going straight into what actually happens when DynamoDB routes a request to a partition, how it decides between strongly and eventually consistent reads under the hood, why a poorly chosen partition key can throttle an otherwise well-provisioned table, and how Global Secondary Indexes and Streams extend the base engine without changing its core guarantees. By the end, you’ll be able to model a table for a real access pattern and defend that design in a system-design interview.

1Core Concepts

The vocabulary that determines how your data is physically distributed.

Partition Keys Decide Placement, Not Just Uniqueness

Every DynamoDB item lives on a specific physical partition — a fixed slice of storage and throughput capacity — determined by hashing the item’s partition key (also called the hash key). This is the single most consequential design decision in any DynamoDB table: the partition key isn’t just an identifier, it’s the sharding function for your entire dataset. Two items with the same partition key always land on the same partition; items with different partition keys are spread across many partitions by DynamoDB’s internal hashing.

A sort key (range key) is optional but powerful — items sharing a partition key are stored together, ordered by sort key, which is what makes range queries like “all orders for customer X between two dates” efficient without scanning the whole table.

Analogy

Think of a partition key like the aisle number in a warehouse, and the sort key like the shelf position within that aisle. Look up “aisle 12, shelf 40-60” and a worker walks directly there — fast. Ask for “everything with a red label” scattered across every aisle, and someone has to walk the entire warehouse checking every shelf — that’s a table scan, and it’s exactly what a good partition key design avoids.

Capacity Modes: Provisioned vs. On-Demand

ModeHow Capacity WorksBest For
ProvisionedYou set Read/Write Capacity Units (RCUs/WCUs); optionally auto-scaled within boundsPredictable, steady traffic where cost optimization matters
On-DemandDynamoDB scales capacity automatically per request, billed per read/writeSpiky or unknown traffic patterns, new applications
!
Common Misunderstanding

On-Demand mode is not infinitely elastic on a millisecond timescale — it scales to roughly double the previous peak traffic within a 30-minute window by default. A workload that spikes 10x instantly can still see throttling even in On-Demand mode if it exceeds that scaling ceiling.

2Architecture & Components

How requests are routed from your application down to the physical partition serving them.
Routing Layer

Request Router

Receives API calls, authenticates via IAM, and hashes the partition key to determine which storage partition owns the item.

Storage Layer

Storage Nodes / Partitions

Each partition is replicated three times across different Availability Zones for durability, using Multi-Paxos-based consensus for write agreement.

Metadata Layer

Partition Metadata Service

Tracks which partitions exist and which storage nodes host them, enabling the request router to find the right destination.

Index Layer

Global / Local Secondary Indexes

Maintain alternate query paths on different key schemas, asynchronously (GSI) or synchronously (LSI) updated as the base table changes.

Change Capture

DynamoDB Streams

An ordered, time-limited log of item-level modifications, consumable by Lambda or Kinesis for event-driven architectures.

Caching Layer

DynamoDB Accelerator (DAX)

An optional in-memory cache cluster sitting in front of DynamoDB, cutting read latency from single-digit milliseconds to microseconds for cacheable reads.

flowchart TB
    APP[Application]
    RR[Request Router]
    subgraph PARTITIONS["Storage Partitions (replicated x3 across AZs)"]
        P1[Partition 1 - Leader]
        P1R1[Replica AZ-b]
        P1R2[Replica AZ-c]
    end
    GSI[(Global Secondary Index)]
    STREAM[DynamoDB Streams]
    LAMBDA[Lambda Consumer]
    DAX[DAX Cache Cluster]
    CW[CloudWatch Metrics]

    APP -->|cacheable read| DAX --> RR
    APP -->|write / strong read| RR
    RR -->|hash partition key| P1
    P1 -->|Paxos consensus| P1R1
    P1 -->|Paxos consensus| P1R2
    P1 -->|async propagate| GSI
    P1 -->|change events| STREAM --> LAMBDA
    P1 --> CW
    
Fig 1. Request routing, replicated partitions, secondary indexes, and streams

Note the asymmetry: writes and strongly consistent reads always go to the partition leader; DAX sits in front of the router for read-heavy, cache-friendly access patterns; and GSIs update asynchronously, meaning a GSI read can briefly lag behind the base table under heavy write load.

3Internal Working

How writes achieve durability and how consistency models differ under the hood.

Write Path: Consensus Before Acknowledgment

1

Request Routed

The request router hashes the partition key and forwards the write to that partition’s current leader replica.

2

Consensus Achieved

The leader replicates the write to its two peer replicas using a Paxos-based consensus protocol, requiring a majority to agree before the write is considered durable.

3

Write Acknowledged

Once a majority of replicas confirm, the client receives a success response — the write is now durable across multiple Availability Zones.

4

Streams & Indexes Updated

Change events are appended to the Streams log and propagated asynchronously to any Global Secondary Indexes.

Eventually Consistent vs. Strongly Consistent Reads

By default, a GetItem or Query call returns an eventually consistent read, which may be served by any replica — including one that hasn’t yet received the very latest write, though the propagation delay is typically well under a second. Setting ConsistentRead=true forces the read to go to the leader replica, guaranteeing you see the most recent successful write, at roughly double the read capacity cost and slightly higher latency.

Analogy

It’s like asking any employee at a company’s three branch offices for the latest customer address (eventually consistent) versus insisting on calling headquarters directly, where updates are recorded first (strongly consistent). The branch offices are usually right, and always faster to reach — but right after headquarters processes a change, a branch might answer with slightly stale information for a brief moment.

i
What an Interviewer May Ask

“When would you deliberately choose eventually consistent reads even though strong consistency is available?” Strong answers point to cost and throughput: eventually consistent reads use half the read capacity units of strongly consistent ones, and most access patterns — a product catalog page, a social feed — tolerate a sub-second staleness window in exchange for significantly higher throughput at lower cost.

4Data Flow & Lifecycle

How an item moves from write, through indexing and streaming, to eventual expiry.
flowchart LR
    A[Item Written] --> B[Base Table Partition]
    B -->|async| C[GSI Update]
    B -->|sync, same partition| D[LSI Update]
    B -->|change log| E[DynamoDB Streams - 24hr retention]
    E --> F[Lambda / Kinesis Consumer]
    B -->|TTL attribute expires| G[Automatic Deletion]
    G --> E
    
Fig 2. Item lifecycle across base table, indexes, streams, and TTL-based expiry

Time to Live (TTL) lets you mark an attribute as an expiry timestamp; DynamoDB then automatically deletes expired items in the background, at no additional write-capacity cost, typically within 48 hours of expiry. TTL deletions still appear as delete events on Streams, which is how downstream systems (e.g., archiving expired sessions to S3) stay in sync without polling.

Real Flow: Event-Driven Order Processing

An e-commerce order table uses Streams to trigger a Lambda function on every new order item written. The Lambda function updates an inventory count in a separate table and publishes an event to EventBridge — all without the order-writing service needing to know anything about inventory or notifications, decoupling the write path from downstream side effects.

5Advantages, Disadvantages & Trade-offs

Advantages

  • Single-digit-millisecond latency at virtually any scale, with no manual sharding
  • Fully managed — no server patching, replication setup, or failover configuration
  • On-Demand mode removes capacity planning entirely for unpredictable workloads
  • Streams enable clean event-driven architecture without custom change-data-capture tooling
  • Transactions provide ACID guarantees across up to 100 items when needed

Disadvantages / Trade-offs

  • No ad-hoc query flexibility — every access pattern must be designed for in advance via keys and indexes
  • A poorly chosen partition key can create a “hot partition,” throttling requests despite adequate overall capacity
  • Joins and multi-table transactions are far more limited than in relational databases
  • Item size is capped at 400 KB, unsuitable for large blobs without offloading to S3
“DynamoDB doesn’t ask you to normalize your data — it asks you to know your access patterns before you write a single line of schema.”

6Performance & Scalability

3,000 WCU
MAX WRITE THROUGHPUT PER PARTITION
10,000 RCU
MAX READ THROUGHPUT PER PARTITION
10 GB
MAX ITEM COLLECTION SIZE PER PARTITION KEY

Adaptive Capacity and Hot Partitions

DynamoDB’s adaptive capacity feature automatically redistributes throughput toward partitions receiving disproportionate traffic, isolating a hot partition key from throttling the rest of the table — but it operates within limits, and a sufficiently skewed access pattern (e.g., one celebrity user’s ID receiving 90% of a social app’s write traffic) can still throttle even with adaptive capacity active. This is why write-heavy, highly skewed workloads often use write sharding — appending a random suffix to a hot partition key to spread writes across multiple physical partitions, then fanning in reads across the shards.

Lyft’s Ride-Matching at Scale

Lyft uses DynamoDB for latency-sensitive components of its ride-matching system, where single-digit-millisecond reads and writes at massive concurrent scale during peak ride-hailing demand directly affect how quickly a rider gets matched with a nearby driver — a workload pattern DynamoDB’s partitioned architecture is purpose-built to serve.

7High Availability & Reliability

Every DynamoDB table is automatically replicated synchronously across three Availability Zones within a region by default — there is no “Single-AZ mode” to opt out of, unlike some other AWS data services. For multi-region resilience, Global Tables replicate a table across multiple AWS Regions using a multi-active, last-writer-wins conflict resolution model.

ADR-018: Global Tables for a Multi-Region Session StoreAccepted
Context

A SaaS platform serves users from both US and EU regions and needs session data to survive a full regional outage without user-visible downtime.

Decision

Enable DynamoDB Global Tables across two regions, accepting last-writer-wins conflict resolution since session data updates are simple and rarely conflict.

Consequences

Roughly doubles write costs (each write replicates to the second region) but eliminates a single-region failure as a cause of session-store downtime; the team documents that concurrent conflicting writes to the same session ID from two regions are resolved by timestamp, not merged.

8Security

Access Control

IAM Fine-Grained Permissions

IAM policies can restrict access down to specific items via leading-key conditions, enabling secure multi-tenant tables without separate tables per tenant.

Encryption

At Rest by Default

All tables are encrypted at rest with AWS-owned or AWS KMS customer-managed keys; encryption cannot be disabled.

Network

VPC Endpoints

Gateway VPC endpoints allow private connectivity to DynamoDB without traversing the public internet, avoiding NAT gateway costs and exposure.

Auditability

CloudTrail

Logs every control-plane and, optionally, data-plane API call for compliance and forensic review.

!
Trap

IAM leading-key conditions restrict which partition keys a principal can access, but they don’t inherently restrict which attributes within an item are visible — a common multi-tenant security gap is assuming key-level isolation also enforces field-level isolation, which it does not without additional application-layer checks.

9Monitoring, Logging & Metrics

MetricWhat It Tells You
ThrottledRequestsWhether requests are being rejected due to exceeded capacity on a table or partition
ConsumedReadCapacityUnits / ConsumedWriteCapacityUnitsActual usage versus provisioned capacity, key input for right-sizing
SuccessfulRequestLatencyReal-world read/write latency percentiles, useful for SLO tracking
SystemErrors / UserErrorsDistinguishes AWS-side issues from client-side request mistakes
ReplicationLatency (Global Tables)How far behind a replica region is from the source of a write

Production Pattern: Hot Partition Detection

Teams enable Contributor Insights on a table to surface the specific partition keys generating the most throttled requests, turning a vague “the table is throttling” alert into an actionable “this specific customer ID is hot” finding within minutes instead of hours of guesswork.

10Deployment & Cloud Integration

1

IaC Table Definition

Terraform or CloudFormation defines table schema, indexes, capacity mode, and TTL settings as version-controlled, peer-reviewed code.

2

Serverless Integration

Lambda functions read/write via the AWS SDK, commonly fronted by API Gateway, forming a fully serverless request path with no servers to patch.

3

Streams-Driven Pipelines

DynamoDB Streams trigger Lambda consumers for search indexing (OpenSearch), analytics (Kinesis Firehose to S3), or cache invalidation.

4

Backup Automation

Point-in-time recovery (PITR) is enabled as a table setting, allowing restore to any second within the last 35 days without a manual backup schedule.

11Design Patterns & Anti-patterns

Good Patterns

  • Single-table design: modeling multiple related entity types in one table using generic partition/sort key prefixes to serve several access patterns with fewer indexes
  • Write sharding for known hot keys, distributing load across suffixed partition key variants
  • Using Streams for decoupled, event-driven side effects instead of synchronous cross-service calls
  • Sparse GSIs — indexing only items that have a given attribute, keeping the index small and cheap

Anti-patterns

  • Designing the schema around entities first and access patterns second, relational-database-style
  • Using Scan operations as a routine query path instead of a rare maintenance operation
  • Storing large binary blobs directly as item attributes instead of referencing them in S3
  • Ignoring item collection size limits when a partition key’s sort-key range grows unbounded over time

12Best Practices & Common Mistakes

Best Practice

Model Access Patterns Before Schema

List every query the application needs to run first, then design partition/sort keys and indexes to serve them — not the reverse.

Best Practice

Use Conditional Writes for Concurrency

ConditionExpression on writes prevents lost updates in concurrent scenarios without needing distributed locks.

Mistake

Choosing a Low-Cardinality Partition Key

A partition key like “status” with only a few possible values (active/inactive) concentrates all traffic onto a handful of partitions regardless of table size.

Mistake

Over-Indexing

Every GSI duplicates storage and consumes its own write capacity on every base table write — indexes should map directly to real, used access patterns, not “just in case” flexibility.

13Real-World & Industry Examples

Amazon.com: Shopping Cart Service

DynamoDB originated from Amazon’s internal need for a highly available, low-latency shopping cart service during peak events like Prime Day, where relational database bottlenecks under massive concurrent write load directly translated into lost sales.

Airbnb: Real-Time Pricing and Availability

Airbnb uses DynamoDB for components requiring rapid, high-throughput reads and writes tied to property availability calendars, where latency spikes directly degrade the booking experience during high-traffic periods.

Duolingo: Streak and Progress Tracking

Duolingo relies on DynamoDB to track user progress and streaks at massive scale across millions of daily active users, where single-digit-millisecond writes keep the app responsive immediately after each completed lesson.

Gaming: Leaderboards and Session State

Mobile and online games commonly use DynamoDB for session state and leaderboards, leveraging Global Tables to keep player state consistent for users connecting from different regions during global tournaments.

14Frequently Asked Questions

Q1What’s the practical difference between a GSI and an LSI?
An LSI shares the same partition key as the base table and must be created at table creation time, updating synchronously with the base table. A GSI can use an entirely different partition/sort key pair, can be added after table creation, and updates asynchronously — making GSIs far more flexible for evolving access patterns.
Q2Can DynamoDB transactions span multiple tables?
Yes — TransactWriteItems and TransactGetItems can operate across multiple tables within the same account and region, up to 100 items total per transaction, with full ACID guarantees.
Q3Why did my table throttle even though average utilization looked low?
Average table-level utilization can hide a hot partition — a small subset of partition key values receiving disproportionate traffic can throttle individually even while the table’s overall consumed capacity looks well under its provisioned limit.
Q4Does DynamoDB support SQL joins?
No — DynamoDB has no native join operation. Related data is typically either denormalized into a single item, modeled adjacently within the same partition using a shared partition key (single-table design), or joined at the application layer across multiple queries.
Q5How long are DynamoDB Streams records retained?
24 hours by default — consumers (typically Lambda) must process records within that window, since Streams is designed as a near-real-time change feed, not a long-term event store.

15Summary & Key Takeaways

Key Takeaways

  • The partition key is a sharding decision, not just a unique identifier — it determines physical data placement and throughput distribution.
  • Writes require majority consensus across three AZ-replicated copies before being acknowledged, giving durability without a Single-AZ mode to worry about.
  • Eventually consistent reads are the default and cost half the capacity of strongly consistent reads — most access patterns can tolerate the sub-second staleness window.
  • Adaptive capacity mitigates but doesn’t eliminate hot partitions — severely skewed access patterns still need write sharding.
  • Access patterns must be designed for upfront, since DynamoDB has no ad-hoc query flexibility or joins the way relational databases do.
  • Streams enable event-driven architectures without custom change-data-capture tooling, but only retain 24 hours of history.
  • Global Tables trade roughly double write cost for multi-region resilience using last-writer-wins conflict resolution.