DynamoDB Fundamentals
AWS's fully managed NoSQL key-value and document database — single-digit-millisecond performance at any scale, with a fundamentally different design model than a relational database.
Want a visual for this topic?
Generate a diagram tailored to DynamoDB Fundamentals — the AI picks whichever visual (architecture, flowchart, ER diagram, etc.) best fits this specific AWS concept.
Sign in to generate a visual →🎓 Learning objectives
- •Explain DynamoDB's core data model: tables, items, partition keys, and sort keys
- •Explain the difference between On-Demand and Provisioned capacity modes
- •Explain what a Global Secondary Index solves and its tradeoffs
- •Explain what DAX adds on top of DynamoDB
What is it?
Amazon DynamoDB is a fully managed, serverless NoSQL database offering consistent single-digit-millisecond performance at virtually any scale, storing data as items (similar to rows) identified by a primary key, grouped into tables, with no fixed schema beyond that key structure — each item can have different attributes.
Why it exists
Relational databases, even well-tuned ones, have real scaling ceilings and can experience latency variability under very high, unpredictable traffic — a single database server (even with read replicas) is fundamentally limited by that server's capacity. DynamoDB exists to remove that ceiling entirely: it's built on a distributed architecture from the ground up specifically to handle massive scale with predictable low latency, at the cost of giving up some of the flexibility (arbitrary joins, ad-hoc queries) that a relational database provides.
Problem it solves
It solves the scale-ceiling problem (DynamoDB scales horizontally to handle essentially unlimited request volume, unlike a single relational database instance), the latency-predictability problem (consistent single-digit-millisecond response times regardless of table size, because of how its storage is partitioned), and the operational-overhead problem (fully serverless — no instance to size, patch, or manage at all).
Intuition
A relational database is like a single, very well-organized library with one head librarian who can efficiently answer complex questions about any book in relation to any other. DynamoDB is like thousands of small, identical filing cabinets spread across a warehouse, each holding a slice of the data, with a very fast lookup system that knows exactly which cabinet to check for a specific labeled folder — extremely fast for 'get me this specific folder,' but it can't easily answer 'find every folder related to this other folder' without you having designed that relationship into the labeling scheme upfront.
Analogy
A coat check system at a huge venue: you get a numbered ticket (the partition key), and retrieving your coat is instant because the attendant goes directly to that number's rack — no searching. But asking 'which coats belong to people over 6 feet tall' isn't something the coat check system was built to answer efficiently, because it isn't organized by height; you'd need to have deliberately organized it that way (a secondary index) if you knew in advance you'd need that kind of lookup.
Technical explanation
Every DynamoDB table requires a Partition Key (and optionally a Sort Key, together forming a composite primary key). DynamoDB hashes the partition key to determine physical storage placement, which is what gives consistent performance at scale but also means queries MUST specify the partition key (or use a secondary index) — there's no efficient way to scan for arbitrary attribute values without one. A Global Secondary Index (GSI) lets you query by a different attribute as if it were a new partition/sort key pair, at the cost of additional storage and eventual-consistency propagation lag from the base table. A Local Secondary Index (LSI) allows an alternate sort key within the same partition key, must be created at table creation time, and provides strongly consistent reads (unlike GSIs). DAX (DynamoDB Accelerator) is an in-memory caching layer that sits in front of DynamoDB, reducing read latency from single-digit milliseconds to microseconds for read-heavy workloads with hot keys, with no application code changes beyond swapping the client endpoint.
Architecture
A gaming leaderboard application uses a DynamoDB table with game_id as the partition key and score as the sort key, letting it instantly retrieve a specific game's top scores in sorted order with zero application-side sorting logic. A GSI on player_id lets the same table also efficiently answer 'show me all games this specific player has played,' a query pattern the base table's key structure alone couldn't serve efficiently.
Workflow
- Design your primary key (partition key, and sort key if needed) based on your application's most common and highest-volume access pattern — this is the single most important DynamoDB design decision and is much harder to change later than in a relational schema. 2) Add Global Secondary Indexes for other query patterns you know you'll need. 3) Choose On-Demand capacity mode for unpredictable or new workloads, Provisioned (with Auto Scaling) for stable, predictable workloads where you can achieve cost savings from committing to a baseline. 4) Add DAX only if you have a genuinely read-heavy, latency-critical workload after measuring actual DynamoDB latency isn't already sufficient.
Example
A ride-sharing app's trip-tracking table uses driver_id as the partition key and trip_start_timestamp as the sort key, so retrieving a specific driver's trip history, sorted chronologically, is a single fast query. A GSI on rider_id serves the separate, equally common query pattern of 'show this rider's trip history,' since the base table's key structure (organized around drivers) couldn't answer that efficiently on its own.
Real-world usage
DynamoDB is documented by AWS as powering parts of Amazon.com's own retail infrastructure during massive-scale events like Prime Day, specifically chosen for its predictable low latency under extreme, spiky load; it's a common default choice for serverless applications (paired with Lambda and API Gateway) precisely because its fully-managed, scale-to-zero-cost-when-idle nature matches serverless's operational model.
Trade-offs
DynamoDB trades relational flexibility (arbitrary joins, ad-hoc queries, easy schema evolution) for massive, predictable scale and operational simplicity — the right choice when you know your access patterns in advance and need to handle very high or unpredictable request volume; a relational database is the better choice when your application needs genuinely flexible, evolving query patterns or complex multi-table joins that don't map cleanly onto DynamoDB's key-based access model. On-Demand capacity mode trades a higher per-request cost for zero capacity planning and automatic scaling to any traffic level; Provisioned mode with Auto Scaling is cheaper for stable, predictable workloads but requires more upfront capacity planning.
Visual explanation
Picture a table as a wide set of filing cabinets, distributed based on each item's Partition Key (the primary lookup value, e.g. user_id) — DynamoDB uses this key to instantly determine which physical partition holds an item, giving O(1) lookup regardless of total table size. An optional Sort Key (e.g. timestamp) lets multiple items share the same partition key but be ordered and range-queried within that partition (e.g. all of one user's orders, sorted by date).
Advantages
- —
Virtually unlimited horizontal scale with consistent single-digit-millisecond latency regardless of table size
- —
Fully serverless — no instances to provision, patch, or manage, and On-Demand mode means paying only for actual read/write activity
- —
Native integration with DynamoDB Streams enables reactive architectures (e.g. triggering a Lambda function on every table change)
- —
Built-in support for TTL (automatic item expiration), point-in-time recovery, and global tables (multi-Region active-active replication)
Disadvantages
- —
No arbitrary ad-hoc querying or joins like SQL — every access pattern must be designed for upfront via the primary key and secondary indexes
- —
Changing your access patterns after the fact often requires adding new GSIs (with their own storage/consistency cost) or, in the worst case, redesigning the table entirely
- —
Item size is capped at 400KB, unsuitable for storing large blobs directly (store a reference to S3 instead)
- —
The mental model shift from relational thinking (design schema, then query flexibly) to DynamoDB thinking (design for your queries first, then structure data to match) has a real learning curve
Common mistakes
- —
Designing a DynamoDB table the way you'd design a relational schema (normalized, expecting to join tables at query time) instead of designing around your actual access patterns upfront
- —
Choosing a partition key with low cardinality (e.g. a status field with only 3 possible values) creating 'hot partitions' where traffic concentrates unevenly and throttling occurs even though the table overall has capacity
- —
Adding a GSI as an afterthought for every new query need without considering the added storage cost and eventual-consistency implications
- —
Storing large binary blobs (images, videos) directly as item attributes instead of storing them in S3 and keeping only a reference/URL in DynamoDB
- —
Using DynamoDB for a workload that genuinely needs complex relational queries and joins, fighting the tool instead of choosing RDS/Aurora for that use case
In the AWS Console
- 1
AWS Console → DynamoDB → Tables → Create table
Enter a table name, and define the Partition key (and optional Sort key) based on your primary access pattern.
This primary key structure is the hardest thing to change later — spend real time upfront confirming it matches your most important, highest-volume query pattern.
- 2
DynamoDB → Tables → [your table] → Indexes → Create index
Define a Global Secondary Index with a different partition/sort key combination to support a second query pattern the base table's key can't serve.
Each GSI is billed separately for its own storage and throughput — don't add indexes you don't have an actual query need for.
- 3
DynamoDB → Tables → [your table] → Additional settings → Read/write capacity settings
Choose 'On-demand' for unpredictable or new workloads, or 'Provisioned' with Auto Scaling enabled for stable, predictable traffic where you can commit to a baseline capacity.
You can switch between On-Demand and Provisioned modes later, but no more than once per 24 hours — plan ahead rather than switching reactively.
- 4
AWS Console → DynamoDB → DAX clusters → Create cluster
Select the target table and cluster size, then update your application's client to use the DAX endpoint instead of connecting to DynamoDB directly.
DAX is a write-through cache — writes still go to DynamoDB and are reflected in the cache, but only add DAX after confirming your workload is genuinely read-heavy and latency-sensitive enough to justify the extra cost.
🎤 Interview questions
Why does DynamoDB require you to design your access patterns before designing the table, unlike a relational database? (Listen for: DynamoDB's performance comes from partitioning by key; queries not aligned with the key structure can't be served efficiently, unlike SQL's flexible ad-hoc querying via joins and WHERE clauses on any column.)
What causes a 'hot partition' in DynamoDB, and how do you avoid it? (Listen for: a partition key with low cardinality or highly skewed access concentrates traffic on one physical partition; fix by choosing a higher-cardinality key or adding a random/calculated suffix to spread load.)
What's the difference between a Global Secondary Index and a Local Secondary Index? (Listen for: GSI = different partition+sort key, own storage, eventually consistent, can be added anytime; LSI = same partition key with an alternate sort key, must be defined at table creation, supports strongly consistent reads.)
When would you add DAX in front of DynamoDB? (Listen for: after confirming a genuinely read-heavy, latency-critical workload with hot keys that would benefit from microsecond-level cached reads — not as a default addition.)
When would you choose DynamoDB over RDS for a new application? (Listen for: known, key-based access patterns, need for massive/unpredictable scale with consistent low latency, and comfort giving up flexible ad-hoc relational querying in exchange.)