ποΈ Amazon DynamoDB
Unlike RDS, DynamoDB is a NoSQL database β no related tables, just a flexible model built for:
Massive scale
High performance
And extremely low latency
π‘ Simple definition
A fully managed, serverless NoSQL database with high availability, automatic scaling, and single-digit millisecond performance β even at millions of requests.
π A Flagship AWS Service
Built for apps needing:
π Massive scalability
β‘ Extremely fast performance
π High availability
π Automatic scaling
Powers large-scale apps that keep performing well as data and traffic explode.
π― Exam tip
"NoSQL database" β DynamoDB
π Built for High Availability
Every table is automatically replicated across three Availability Zones in the Region β no configuration needed.
One AZ goes down, your data's still there.
<div class="infographic-ha3az">
<style>
.infographic-ha3az {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--ok: #1a7f4b;
--ok-soft: #e2f3ea;
--down: #b3492f;
--down-soft: #fbe9e3;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', system-ui, -apple-system, sans-serif;
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-ha3az[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--ok: #4fbf87;
--ok-soft: #16261e;
--down: #e08268;
--down-soft: #2b1c17;
}
.infographic-ha3az * { box-sizing: border-box; }
.infographic-ha3az .ha-wrap { padding: 0 clamp(1.25rem, 5vw, 3rem); }
.infographic-ha3az .ha-eyebrow {
font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase;
color: var(--accent); font-weight: 600; margin: 1.75rem 0 0.4rem;
}
.infographic-ha3az h1 {
font-family: var(--display-font); font-weight: 600; font-size: clamp(1.5rem, 4vw, 2.1rem);
line-height: 1.15; margin: 0 0 0.5rem;
}
.infographic-ha3az .ha-sub {
color: var(--ink-soft); font-size: 0.95rem; margin: 0 0 1.75rem; max-width: 54ch;
}
.infographic-ha3az .ha-sub b { color: var(--ink); font-weight: 600; }
.infographic-ha3az .region {
border: 1.5px dashed var(--line);
border-radius: 10px;
padding: 1.5rem 1.25rem 1.75rem;
position: relative;
}
.infographic-ha3az .region-label {
position: absolute; top: -0.7rem; left: 1rem;
background: var(--paper); padding: 0 0.5rem;
display: flex; align-items: center; gap: 0.4rem;
font-size: 0.78rem; font-weight: 600; letter-spacing: 0.03em;
color: var(--ink-soft);
}
.infographic-ha3az .region-label svg { width: 14px; height: 14px; stroke: var(--ink-soft); flex-shrink: 0; }
.infographic-ha3az .az-row {
display: grid; grid-template-columns: repeat(3, 1fr);
gap: 1.5rem; align-items: start; margin-top: 0.5rem;
}
.infographic-ha3az .az {
background: var(--paper-alt); border: 1px solid var(--line); border-radius: 8px;
padding: 1rem 0.9rem 1.1rem; text-align: center; position: relative;
}
.infographic-ha3az .az-name {
font-size: 0.72rem; font-weight: 700; letter-spacing: 0.04em; color: var(--ink-soft);
text-transform: uppercase; margin-bottom: 0.6rem;
}
.infographic-ha3az .az-icons { display: flex; justify-content: center; gap: 0.5rem; margin-bottom: 0.55rem; }
.infographic-ha3az .az-icons .icon-badge {
width: 34px; height: 34px; border-radius: 7px; display: flex; align-items: center; justify-content: center;
background: var(--accent-soft); border: 1px solid var(--line);
}
.infographic-ha3az .az-icons .icon-badge svg { width: 18px; height: 18px; stroke: var(--accent); }
.infographic-ha3az .az-status {
display: inline-flex; align-items: center; gap: 0.3rem;
font-size: 0.72rem; font-weight: 600; padding: 0.2rem 0.55rem; border-radius: 999px;
background: var(--ok-soft); color: var(--ok);
}
.infographic-ha3az .az-status svg { width: 12px; height: 12px; }
.infographic-ha3az .az.is-down { background: transparent; border-style: dashed; opacity: 0.85; }
.infographic-ha3az .az.is-down .icon-badge { background: var(--down-soft); border-color: var(--down); opacity: 0.55; }
.infographic-ha3az .az.is-down .icon-badge svg { stroke: var(--down); }
.infographic-ha3az .az.is-down .az-status { background: var(--down-soft); color: var(--down); }
.infographic-ha3az .az.is-down .az-name { text-decoration: line-through; text-decoration-color: var(--down); }
.infographic-ha3az .sync-row {
display: grid; grid-template-columns: repeat(3, 1fr); align-items: center;
margin: -0.15rem 0 -0.15rem;
pointer-events: none;
}
.infographic-ha3az .sync-line {
height: 1px; background: repeating-linear-gradient(90deg, var(--line) 0 6px, transparent 6px 11px);
margin: 0 -0.75rem;
}
.infographic-ha3az .outcome {
margin-top: 1.5rem; display: flex; align-items: center; gap: 0.8rem;
background: var(--ok-soft); border: 1px solid var(--ok);
border-radius: 8px; padding: 0.9rem 1.1rem;
}
.infographic-ha3az .outcome svg { width: 24px; height: 24px; stroke: var(--ok); flex-shrink: 0; }
.infographic-ha3az .outcome p { margin: 0; font-size: 0.92rem; color: var(--ink); }
.infographic-ha3az .outcome p b { color: var(--ok); }
.infographic-ha3az footer.ha-note {
color: var(--ink-soft); font-size: 0.78rem; margin: 1rem 0 1.75rem; text-align: center;
}
@media (max-width: 620px) {
.infographic-ha3az .az-row { grid-template-columns: 1fr; }
.infographic-ha3az .sync-row { display: none; }
}
</style>
<div class="ha-wrap">
<div class="ha-eyebrow">High Availability</div>
<div class="region">
<div class="region-label">
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/></svg>
REGION
</div>
<div class="az-row">
<div class="az">
<div class="az-name">AZ 1</div>
<div class="az-icons">
<div class="icon-badge"><svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"/><rect width="20" height="8" x="2" y="14" rx="2" ry="2"/><line x1="6" x2="6.01" y1="6" y2="6"/><line x1="6" x2="6.01" y1="18" y2="18"/></svg></div>
<div class="icon-badge"><svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5V19A9 3 0 0 0 21 19V5"/><path d="M3 12A9 3 0 0 0 21 12"/></svg></div>
</div>
<span class="az-status"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg> Live copy</span>
</div>
<div class="az is-down">
<div class="az-name">AZ 2</div>
<div class="az-icons">
<div class="icon-badge"><svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"/><rect width="20" height="8" x="2" y="14" rx="2" ry="2"/><line x1="6" x2="6.01" y1="6" y2="6"/><line x1="6" x2="6.01" y1="18" y2="18"/></svg></div>
<div class="icon-badge"><svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg></div>
</div>
<span class="az-status">Zone down</span>
</div>
<div class="az">
<div class="az-name">AZ 3</div>
<div class="az-icons">
<div class="icon-badge"><svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"/><rect width="20" height="8" x="2" y="14" rx="2" ry="2"/><line x1="6" x2="6.01" y1="6" y2="6"/><line x1="6" x2="6.01" y1="18" y2="18"/></svg></div>
<div class="icon-badge"><svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5V19A9 3 0 0 0 21 19V5"/><path d="M3 12A9 3 0 0 0 21 12"/></svg></div>
</div>
<span class="az-status"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg> Live copy</span>
</div>
</div>
<div class="sync-row">
<div class="sync-line"></div>
<div class="sync-line"></div>
</div>
</div>
<div class="outcome">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/></svg>
<p>One AZ goes down β <b>your data's still there</b>, served from the other two.</p>
</div>
</div>
</div>
<script>
(function () {
var wrapper = document.currentScript.closest('.infographic-ha3az')
|| document.querySelector('.infographic-ha3az');
var bodyAttr = document.body.getAttribute('data-darkmode');
var dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
var match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
})();
</script>π What Makes It Different
With RDS or ElastiCache, you pick an instance size (db.t3.micro, etc). With DynamoDB:
β No provisioning
β No instance sizing
β No infrastructure management
π‘ Serverless doesn't mean no servers β it means AWS manages them so you never touch them.
Handles millions of requests/second, trillions of items, hundreds of TB β scales automatically as demand grows.
Single-digit millisecond latency β ideal for e-commerce, gaming, mobile, and high-traffic apps that need instant responses.
π― Exam tip: "Serverless," "single-digit ms latency," "massive scalability," "NoSQL" β DynamoDB
π Security
Integrates directly with IAM β control who can access tables, what actions they can take, and authentication/authorization.
π° Cost Optimisation
Automatic scaling based on demand
Pay for capacity used
Two table classes: Standard (frequent access) and Standard-IA (infrequent access, lower storage cost)
π How Data is Stored
DynamoDB stores items (not rows) with a Primary Key and attributes.
<div class="infographic-ddbkey">
<style>
.infographic-ddbkey {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--pk: #f2b705;
--pk-ink: #7a5c00;
--pk-cell-ink:#1a1a1a;
--sk: #1e3a8a;
--sk-cell-ink:#ffffff;
--attr-bg: #dcdcdc;
--attr-ink: #1a1a1a;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', system-ui, -apple-system, sans-serif;
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-ddbkey[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--pk: #caa53a;
--pk-ink: #e8d488;
--pk-cell-ink:#1a1408;
--sk: #3a5bc7;
--sk-cell-ink:#f2f4fb;
--attr-bg: #2a2a32;
--attr-ink: #d8d6d0;
}
.infographic-ddbkey * { box-sizing: border-box; }
.infographic-ddbkey .ddb-wrap { padding: 0 clamp(1.25rem, 5vw, 3rem); }
.infographic-ddbkey .ddb-eyebrow {
font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase;
color: var(--accent); font-weight: 600; margin: 1.75rem 0 0.35rem;
}
.infographic-ddbkey h1 {
font-family: var(--display-font); font-weight: 600; font-size: clamp(1.4rem, 3.6vw, 1.9rem);
line-height: 1.15; margin: 0 0 1.75rem;
}
.infographic-ddbkey .ddb-grid {
display: grid;
grid-template-columns: 28px 128px 148px 26px 1fr;
column-gap: 10px;
row-gap: 10px;
align-items: stretch;
}
/* header row */
.infographic-ddbkey .head-pk { grid-column: 2 / 4; }
.infographic-ddbkey .head-attrs { grid-column: 5 / 6; }
.infographic-ddbkey .head-pk, .infographic-ddbkey .head-attrs { padding-bottom: 0.4rem; }
.infographic-ddbkey .head-title {
font-family: var(--display-font); font-weight: 700; font-size: 1.15rem;
text-align: center; margin-bottom: 0.3rem;
}
.infographic-ddbkey .stem { width: 2px; height: 12px; background: var(--ink); margin: 0 auto; }
.infographic-ddbkey .bracket-svg { display: block; width: 100%; height: 30px; }
.infographic-ddbkey .bracket-svg path { fill: none; stroke: var(--ink); stroke-width: 2; }
.infographic-ddbkey .sub-labels { display: grid; grid-template-columns: 128px 148px; column-gap: 10px; margin-top: 0.35rem; }
.infographic-ddbkey .sub-label { text-align: center; }
.infographic-ddbkey .sub-label .lbl {
font-weight: 700; font-size: 0.95rem; margin-bottom: 0.3rem;
}
.infographic-ddbkey .sub-label.pk .lbl { color: var(--pk-ink); }
.infographic-ddbkey .sub-label.sk .lbl { color: var(--accent); }
.infographic-ddbkey .sub-label svg { width: 18px; height: 18px; margin: 0 auto; display: block; }
.infographic-ddbkey .sub-label.pk svg { stroke: var(--pk-ink); }
.infographic-ddbkey .sub-label.sk svg { stroke: var(--accent); }
.infographic-ddbkey .attrs-note {
border: 1.5px solid var(--ink); border-radius: 8px;
padding: 0.7rem 1rem; text-align: center; font-weight: 600; font-size: 0.92rem;
margin-top: 0.35rem;
}
.infographic-ddbkey .attrs-label {
text-align: center; color: var(--ink-soft); font-weight: 600; font-size: 0.92rem; margin-bottom: 0.3rem;
}
/* items bracket spans data rows */
.infographic-ddbkey .items-cell { grid-column: 1 / 2; grid-row: 2 / 6; position: relative; }
.infographic-ddbkey .items-label {
position: absolute; left: -6px; top: 50%; transform: translate(-100%, -50%) rotate(0deg);
font-weight: 700; font-size: 0.85rem; white-space: nowrap; color: var(--ink);
}
.infographic-ddbkey .items-bracket-svg { width: 100%; height: 100%; display: block; }
.infographic-ddbkey .items-bracket-svg path { fill: none; stroke: var(--ink); stroke-width: 2; vector-effect: non-scaling-stroke; }
/* data rows */
.infographic-ddbkey .row-pk, .infographic-ddbkey .row-sk {
border-radius: 6px; display: flex; align-items: center; justify-content: center;
font-weight: 700; font-size: 0.98rem; text-align: center; padding: 0.6rem 0.5rem; min-height: 54px;
}
.infographic-ddbkey .row-pk { background: var(--pk); color: var(--pk-cell-ink); grid-column: 2 / 3; }
.infographic-ddbkey .row-sk { background: var(--sk); color: var(--sk-cell-ink); grid-column: 3 / 4; }
.infographic-ddbkey .row-attrs { display: flex; gap: 10px; align-items: stretch; grid-column: 5 / 6; }
.infographic-ddbkey .attr-chip {
background: var(--attr-bg); color: var(--attr-ink); border-radius: 6px;
display: flex; align-items: center; justify-content: center; text-align: center;
font-weight: 600; font-size: 0.92rem; padding: 0.6rem 0.9rem; min-height: 54px; flex: 1 1 0;
}
@media (max-width: 680px) {
.infographic-ddbkey .ddb-grid { grid-template-columns: 22px 100px 118px 0 1fr; column-gap: 8px; }
.infographic-ddbkey .row-attrs { flex-wrap: wrap; }
.infographic-ddbkey .attr-chip { flex: 1 1 45%; font-size: 0.82rem; }
.infographic-ddbkey .items-label { font-size: 0.72rem; }
}
.infographic-ddbkey footer.ddb-note {
color: var(--ink-soft); font-size: 0.78rem; margin: 1.5rem 0 1.75rem; text-align: center;
}
</style>
<div class="ddb-wrap">
<div class="ddb-grid">
<!-- header row -->
<div class="head-pk">
<div class="head-title">Primary Key</div>
<div class="stem"></div>
<svg class="bracket-svg" viewBox="0 0 320 30" preserveAspectRatio="none"><path d="M8,30 V14 Q8,6 16,6 H304 Q312,6 312,14 V30"/></svg>
<div class="sub-labels">
<div class="sub-label pk">
<div class="lbl">Partition Key</div>
<svg viewBox="0 0 24 24" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v13"/><path d="m19 12-7 7-7-7"/></svg>
</div>
<div class="sub-label sk">
<div class="lbl">Sort Key</div>
<svg viewBox="0 0 24 24" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v13"/><path d="m19 12-7 7-7-7"/></svg>
</div>
</div>
</div>
<div class="head-attrs">
<div class="head-title">Products</div>
<div class="attrs-label">Attributes</div>
<svg class="bracket-svg" viewBox="0 0 400 30" preserveAspectRatio="none"><path d="M8,30 V14 Q8,6 16,6 H384 Q392,6 392,14 V30"/></svg>
<div class="attrs-note">Schema is defined per Item</div>
</div>
<!-- items bracket -->
<div class="items-cell">
<span class="items-label">Items</span>
<svg class="items-bracket-svg" viewBox="0 0 20 100" preserveAspectRatio="none"><path d="M18,2 H8 V98 H18"/></svg>
</div>
<!-- row 1: Odyssey -->
<div class="row-pk">1</div>
<div class="row-sk">Book ID</div>
<div class="row-attrs">
<div class="attr-chip">Odyssey</div>
<div class="attr-chip">Homer</div>
<div class="attr-chip">1871</div>
</div>
<!-- row 2: 6 Partitas -->
<div class="row-pk">2</div>
<div class="row-sk">Album ID</div>
<div class="row-attrs">
<div class="attr-chip">6 Partitas</div>
<div class="attr-chip">Bach</div>
</div>
<!-- row 3: Partita No. 1 -->
<div class="row-pk">2</div>
<div class="row-sk">Album ID: Track ID</div>
<div class="row-attrs">
<div class="attr-chip">Partita No. 1</div>
</div>
<!-- row 4: The Kid -->
<div class="row-pk">3</div>
<div class="row-sk">Movie ID</div>
<div class="row-attrs">
<div class="attr-chip">The Kid</div>
<div class="attr-chip">Drama, Comedy</div>
<div class="attr-chip">Chaplin</div>
</div>
</div>
</div>
</div>
<script>
(function () {
var wrapper = document.currentScript.closest('.infographic-ddbkey')
|| document.querySelector('.infographic-ddbkey');
var bodyAttr = document.body.getAttribute('data-darkmode');
var dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
var match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
})();
</script>Primary Key β a Partition Key alone, or Partition Key + Sort Key β uniquely identifies each item
Attributes β the data fields for that item
π Partition Key | π·οΈ Sort Key | π€ Name | π§ Email | π Country |
|---|---|---|---|---|
101 | Customer | John | Kenya | |
102 | Customer | Sarah | Canada |
Unlike relational tables, different items can have different attributes β much more flexible.
π§ Why Is DynamoDB So Popular?
Developers choose DynamoDB because it combines several powerful features in a single service:
β Fully managed
β Serverless
β Highly available
β Automatically scalable
β Extremely fast
These capabilities make DynamoDB an excellent choice for modern cloud-native applications.
β‘ Amazon DynamoDB Accelerator (DAX)
DynamoDB is fast β but some apps need even faster access to hot data.
π‘ DAX is a fully managed, in-memory cache built specifically for DynamoDB β sits in front of your tables for high-speed reads.
ποΈ How It Works
<meta charset="utf-8">
<!-- App -> DAX (in-memory cache) -> HIT: instant return / MISS: fetch DynamoDB + cache. AWS-style vertical layout, 3:2. Self-contained, drop into codeveda.dev. -->
<div class="infographic-daxarch">
<header class="cf-head">
<button class="cf-run-btn" type="button">
<svg class="run-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="6 3 20 12 6 21 6 3"/></svg>
<span class="run-label">Run Flow</span>
</button>
<p class="cf-status" aria-live="polite"> </p>
</header>
<div class="cf-canvas">
<svg viewBox="0 0 720 480" xmlns="http://www.w3.org/2000/svg" class="cf-svg">
<defs>
<marker id="da-arrow-hit" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M0,0 L10,5 L0,10 z" class="arrow-fill-hit"/>
</marker>
</defs>
<!-- ============ double-headed arrow 1 : App <-> DAX ============ -->
<polygon class="dbl-arrow" points="
300,124 286,146 296,146 296,208 286,208 300,230 314,208 304,208 304,146 314,146
"/>
<text x="270" y="200" text-anchor="end" class="edge-label edge-label--step">β App requests data</text>
<!-- HIT arc: DAX -> back to App -->
<path id="da-arc-hit" d="M324,220 C 490,188 490,104 324,90" class="connector-line hit-arc" fill="none" marker-end="url(#da-arrow-hit)"/>
<text x="505" y="128" class="edge-label edge-label--hit">β’ HIT</text>
<text x="505" y="144" class="edge-label edge-label--hit-sm">return instantly</text>
<!-- ============ double-headed arrow 2 : DAX <-> DynamoDB ============ -->
<polygon class="dbl-arrow" points="
300,300 286,322 296,322 296,350 286,350 300,372 314,350 304,350 304,322 314,322
"/>
<text x="340" y="322" class="edge-label edge-label--miss">β£ MISS β fetch from DynamoDB,</text>
<text x="340" y="338" class="edge-label edge-label--miss">cache it for next time</text>
<!-- motion paths (invisible) -->
<path id="da-path-app" d="M300,102 L300,220" fill="none" stroke="none"/>
<path id="da-path-down" d="M300,232 L300,296" fill="none" stroke="none"/>
<path id="da-path-fetch" d="M300,300 L300,356" fill="none" stroke="none"/>
<path id="da-path-return" d="M300,356 L300,300" fill="none" stroke="none"/>
<path id="da-path-arc" d="M324,220 C 490,188 490,104 324,90" fill="none" stroke="none"/>
<!-- ============ App node ============ -->
<g class="cf-node" data-part="app" tabindex="0" role="button" aria-label="Client applications" aria-expanded="false">
<g transform="translate(300,60)">
<g class="node-icon node-icon--app" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" fill="none">
<rect x="-24" y="-22" width="48" height="32" rx="3"/>
<line x1="0" y1="10" x2="0" y2="19"/>
<line x1="-15" y1="19" x2="15" y2="19"/>
</g>
</g>
</g>
<text x="300" y="110" text-anchor="middle" class="node-label node-label--caption">applications</text>
<!-- ============ DAX node ============ -->
<g class="cf-node" data-part="dax" tabindex="0" role="button" aria-label="DAX in-memory cache" aria-expanded="false">
<circle id="da-processing-ring" cx="300" cy="255" r="52" class="processing-ring"/>
<g transform="translate(300,255)">
<g class="node-icon node-icon--purple" stroke="currentColor" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round" fill="none">
<!-- cylinder -->
<ellipse cx="-4" cy="-24" rx="20" ry="7"/>
<path d="M-24,-24 V4 A20,7 0 0 0 16,4 V-24"/>
<path d="M-24,-10 A20,7 0 0 0 12,-3.5"/>
<!-- lightning bolt -->
<path d="M8,-2 L-2,16 L6,16 L-4,34 L14,12 L6,12 Z" fill="var(--purple)" stroke="none"/>
<!-- speed lines -->
<line x1="-34" y1="20" x2="-14" y2="20"/>
<line x1="-34" y1="27" x2="-8" y2="27"/>
<line x1="-34" y1="34" x2="-16" y2="34"/>
</g>
</g>
</g>
<text x="345" y="242" class="node-label node-label--title">DAX</text>
<text x="345" y="260" class="node-label node-label--caption">DynamoDB Accelerator</text>
<text x="345" y="278" class="node-label node-label--caption">β‘ Checks memory</text>
<!-- ============ DynamoDB region ============ -->
<g class="cf-node" data-part="dynamodb" tabindex="0" role="button" aria-label="Amazon DynamoDB table region" aria-expanded="false">
<rect x="60" y="355" width="600" height="122" rx="8" class="region-box"/>
<!-- Amazon DynamoDB tile -->
<rect x="90" y="368" width="70" height="70" rx="12" class="ddb-tile"/>
<g transform="translate(125,403)">
<g stroke="var(--paper)" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" fill="none">
<ellipse cx="0" cy="-13" rx="16" ry="6"/>
<path d="M-16,-13 V13 A16,6 0 0 0 16,13 V-13"/>
<path d="M-16,0 A16,6 0 0 0 16,0"/>
</g>
</g>
<text x="125" y="452" text-anchor="middle" class="node-label node-label--sm">Amazon</text>
<text x="125" y="466" text-anchor="middle" class="node-label node-label--sm">DynamoDB</text>
<!-- table icons -->
<g class="table-icon" data-table="1" transform="translate(255,403)">
<g class="node-icon node-icon--purple" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none">
<rect x="-22" y="-22" width="44" height="44" rx="4"/>
<line x1="-22" y1="-9" x2="22" y2="-9"/>
<line x1="-22" y1="4" x2="22" y2="4"/>
<line x1="-4" y1="-22" x2="-4" y2="22"/>
</g>
</g>
<text x="255" y="452" text-anchor="middle" class="node-label node-label--sm">table</text>
<g class="table-icon" data-table="2" transform="translate(405,403)">
<g class="node-icon node-icon--purple" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none">
<rect x="-22" y="-22" width="44" height="44" rx="4"/>
<line x1="-22" y1="-9" x2="22" y2="-9"/>
<line x1="-22" y1="4" x2="22" y2="4"/>
<line x1="-4" y1="-22" x2="-4" y2="22"/>
</g>
</g>
<text x="405" y="452" text-anchor="middle" class="node-label node-label--sm">table</text>
<g class="table-icon" data-table="3" transform="translate(555,403)">
<g class="node-icon node-icon--purple" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none">
<rect x="-22" y="-22" width="44" height="44" rx="4"/>
<line x1="-22" y1="-9" x2="22" y2="-9"/>
<line x1="-22" y1="4" x2="22" y2="4"/>
<line x1="-4" y1="-22" x2="-4" y2="22"/>
</g>
</g>
<text x="555" y="452" text-anchor="middle" class="node-label node-label--sm">table</text>
</g>
<!-- badges -->
<g id="da-miss-badge" class="miss-badge" opacity="0">
<rect x="474" y="308" width="60" height="26" rx="13" class="miss-pill"/>
<text x="504" y="325" text-anchor="middle" class="miss-text">MISS</text>
</g>
<g id="da-cached-badge" class="cached-badge" opacity="0">
<rect x="368" y="288" width="156" height="26" rx="13" class="cached-pill"/>
<text x="446" y="305" text-anchor="middle" class="cached-text">Stored for next time</text>
</g>
<g id="da-hit-badge" class="hit-badge" opacity="0">
<rect x="392" y="112" width="60" height="24" rx="12" class="hit-pill"/>
<text x="422" y="128" text-anchor="middle" class="hit-text">HIT</text>
</g>
<!-- pulses -->
<circle r="7" class="cf-pulse" id="da-pulse-app" opacity="0"><animateMotion id="da-motion-app" dur="0.7s" begin="indefinite" fill="freeze" calcMode="linear"><mpath href="#da-path-app"/></animateMotion></circle>
<circle r="7" class="cf-pulse" id="da-pulse-down" opacity="0"><animateMotion id="da-motion-down" dur="0.6s" begin="indefinite" fill="freeze" calcMode="linear"><mpath href="#da-path-down"/></animateMotion></circle>
<circle r="7" class="cf-pulse" id="da-pulse-fetch" opacity="0"><animateMotion id="da-motion-fetch" dur="1.8s" begin="indefinite" fill="freeze" calcMode="linear"><mpath href="#da-path-fetch"/></animateMotion></circle>
<circle r="7" class="cf-pulse" id="da-pulse-return" opacity="0"><animateMotion id="da-motion-return" dur="0.7s" begin="indefinite" fill="freeze" calcMode="linear"><mpath href="#da-path-return"/></animateMotion></circle>
<circle r="7" class="cf-pulse cf-pulse--hit" id="da-pulse-arc" opacity="0"><animateMotion id="da-motion-arc" dur="0.7s" begin="indefinite" fill="freeze" calcMode="linear"><mpath href="#da-path-arc"/></animateMotion></circle>
</svg>
</div>
</div>
<style>
.infographic-daxarch {
--ink: #232b36;
--ink-soft: #5c6570;
--paper: #ffffff;
--paper-alt: #f6f5f2;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--purple: #5b21d6;
--purple-soft:#efe7fd;
--line: #dcd8d0;
--arrow: #7ea2e0;
--error: #c0392b;
--error-soft: #fbe9e7;
--success: #1e8e5a;
--success-soft:#e2f4ea;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
box-sizing: border-box;
max-width: 820px;
margin: 0 auto;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-daxarch[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1c1c22;
--accent: #5b8def;
--accent-soft:#202942;
--purple: #b18bff;
--purple-soft:#241c3a;
--line: #2c313d;
--arrow: #5b8def;
--error: #e57373;
--error-soft: #3a2222;
--success: #4caf7d;
--success-soft:#1c332a;
}
.infographic-daxarch * { box-sizing: border-box; }
.infographic-daxarch .cf-head { text-align: center; padding: 0.5rem clamp(1rem, 4vw, 2rem) 0.25rem; }
.infographic-daxarch .cf-run-btn {
display: inline-flex; align-items: center; gap: 0.5rem;
background: var(--accent); color: var(--paper); border: none; border-radius: 999px;
padding: 0.55rem 1.3rem; font-family: inherit; font-size: 0.88rem; font-weight: 600;
cursor: pointer; transition: opacity 0.15s;
}
.infographic-daxarch .cf-run-btn:hover { opacity: 0.88; }
.infographic-daxarch .cf-run-btn:disabled { opacity: 0.5; cursor: default; }
.infographic-daxarch .run-icon { width: 15px; height: 15px; }
.infographic-daxarch .cf-status { margin: 0.6rem 0 0; font-size: 0.85rem; font-weight: 600; color: var(--ink-soft); min-height: 1.2em; }
.infographic-daxarch .cf-canvas { padding: 0 clamp(0.75rem, 3vw, 2rem) 1rem; }
.infographic-daxarch .cf-svg { width: 100%; aspect-ratio: 3 / 2; height: auto; display: block; overflow: visible; }
.infographic-daxarch .dbl-arrow { fill: var(--paper-alt); stroke: var(--arrow); stroke-width: 1.75; stroke-linejoin: round; }
.infographic-daxarch .connector-line.hit-arc { stroke: var(--success); stroke-width: 1.75; stroke-dasharray: 5 4; opacity: 0.8; }
.infographic-daxarch .arrow-fill-hit { fill: var(--success); }
.infographic-daxarch .connector-line.is-flowing { stroke: var(--accent); }
.infographic-daxarch .dbl-arrow.is-flowing { stroke: var(--accent); stroke-width: 2.25; }
.infographic-daxarch .connector-line.is-flowing-hit { stroke: var(--success); opacity: 1; stroke-width: 2.25; }
.infographic-daxarch .edge-label { font-size: 13px; fill: var(--ink-soft); font-family: var(--body-font); font-weight: 600; }
.infographic-daxarch .edge-label--step { fill: var(--ink-soft); }
.infographic-daxarch .edge-label--hit { fill: var(--success); font-size: 14px; }
.infographic-daxarch .edge-label--hit-sm { fill: var(--success); font-weight: 500; font-size: 12px; }
.infographic-daxarch .edge-label--miss { fill: var(--ink); }
.infographic-daxarch .cf-node { cursor: pointer; outline: none; }
.infographic-daxarch .cf-svg.has-active .cf-node:not(.is-active) { opacity: 0.45; }
.infographic-daxarch .cf-node:focus-visible { outline: none; }
.infographic-daxarch .node-icon--app { color: var(--ink); }
.infographic-daxarch .node-icon--purple { color: var(--purple); }
.infographic-daxarch .cf-node.is-miss .node-icon--purple { color: var(--error); }
.infographic-daxarch .cf-node.is-hit .node-icon--purple { color: var(--success); }
.infographic-daxarch .processing-ring {
fill: none; stroke: var(--accent); stroke-width: 3; stroke-dasharray: 10 8;
opacity: 0; transform-origin: 300px 255px;
}
.infographic-daxarch .processing-ring.is-spinning { opacity: 0.8; animation: da-spin 0.9s linear infinite; }
@keyframes da-spin { to { transform: rotate(360deg); } }
.infographic-daxarch .region-box { fill: none; stroke: var(--arrow); stroke-width: 1.5; }
.infographic-daxarch .cf-node.is-active .region-box { stroke: var(--accent); stroke-width: 2; }
.infographic-daxarch .ddb-tile { fill: var(--purple); }
.infographic-daxarch .table-icon { transition: opacity 0.15s; }
.infographic-daxarch .table-icon.is-caching .node-icon--purple { color: var(--success); }
.infographic-daxarch .miss-badge, .infographic-daxarch .cached-badge, .infographic-daxarch .hit-badge { transition: opacity 0.2s; }
.infographic-daxarch .miss-pill { fill: var(--ink); }
.infographic-daxarch .miss-text { fill: var(--paper); font-family: var(--body-font); font-size: 12px; font-weight: 700; letter-spacing: 0.04em; }
.infographic-daxarch .cached-pill { fill: var(--success); }
.infographic-daxarch .cached-text { fill: var(--paper); font-family: var(--body-font); font-size: 12px; font-weight: 700; }
.infographic-daxarch .hit-pill { fill: var(--success); }
.infographic-daxarch .hit-text { fill: var(--paper); font-family: var(--body-font); font-size: 11px; font-weight: 700; letter-spacing: 0.04em; }
.infographic-daxarch .cf-pulse { fill: var(--accent); transition: opacity 0.2s; }
.infographic-daxarch .cf-pulse--hit { fill: var(--success); }
.infographic-daxarch .node-label { font-family: var(--display-font); font-size: 15px; font-weight: 500; fill: var(--ink); }
.infographic-daxarch .node-label--title { font-size: 17px; font-weight: 600; fill: var(--purple); }
.infographic-daxarch .node-label--sm { font-size: 13px; font-weight: 600; fill: var(--ink); }
.infographic-daxarch .node-label--caption { font-size: 12.5px; fill: var(--ink-soft); font-weight: 400; font-family: var(--body-font); }
@media (max-width: 560px) {
.infographic-daxarch .edge-label { font-size: 11.5px; }
}
@media (prefers-reduced-motion: reduce) {
.infographic-daxarch * { transition-duration: 0.001ms !important; animation-duration: 0.001ms !important; }
}
</style>
<script>
(function () {
var wrapper = document.currentScript.closest('.infographic-daxarch')
|| document.querySelector('.infographic-daxarch');
var bodyAttr = document.body.getAttribute('data-darkmode');
var dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
var match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
var reducedMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var svg = wrapper.querySelector('.cf-svg');
var nodes = wrapper.querySelectorAll('.cf-node');
var runBtn = wrapper.querySelector('.cf-run-btn');
var statusEl = wrapper.querySelector('.cf-status');
var processingRing = wrapper.querySelector('#da-processing-ring');
var missBadge = wrapper.querySelector('#da-miss-badge');
var cachedBadge = wrapper.querySelector('#da-cached-badge');
var hitBadge = wrapper.querySelector('#da-hit-badge');
var daxNode = wrapper.querySelector('.cf-node[data-part="dax"]');
var appNode = wrapper.querySelector('.cf-node[data-part="app"]');
var ddbNode = wrapper.querySelector('.cf-node[data-part="dynamodb"]');
var arrows = wrapper.querySelectorAll('.dbl-arrow');
var arcLine = wrapper.querySelector('#da-arc-hit');
var pulses = {
app: wrapper.querySelector('#da-pulse-app'),
down: wrapper.querySelector('#da-pulse-down'),
fetch: wrapper.querySelector('#da-pulse-fetch'),
return: wrapper.querySelector('#da-pulse-return'),
arc: wrapper.querySelector('#da-pulse-arc')
};
var motions = {
app: wrapper.querySelector('#da-motion-app'),
down: wrapper.querySelector('#da-motion-down'),
fetch: wrapper.querySelector('#da-motion-fetch'),
return: wrapper.querySelector('#da-motion-return'),
arc: wrapper.querySelector('#da-motion-arc')
};
function setActive(parts) {
var list = parts ? (Array.isArray(parts) ? parts : [parts]) : [];
nodes.forEach(function (n) {
var isMatch = list.indexOf(n.dataset.part) !== -1;
n.classList.toggle('is-active', isMatch);
n.setAttribute('aria-expanded', isMatch ? 'true' : 'false');
});
svg.classList.toggle('has-active', list.length > 0);
}
function setArrow1(on) { arrows[0].classList.toggle('is-flowing', on); }
function setArrow2(on) { arrows[1].classList.toggle('is-flowing', on); }
function setArc(on, hit) {
arcLine.classList.toggle('is-flowing', on && !hit);
arcLine.classList.toggle('is-flowing-hit', on && !!hit);
}
function fire(key, dur) {
motions[key].setAttribute('dur', (dur / 1000) + 's');
pulses[key].setAttribute('opacity', reducedMotion ? '0' : '1');
try { motions[key].beginElement(); } catch (e) { /* Safari fallback */ }
}
function hidePulse(key) { pulses[key].setAttribute('opacity', '0'); }
function setStatus(text) { statusEl.textContent = text; }
function toggleNode(node) {
var wasActive = node.classList.contains('is-active');
setActive(wasActive ? null : node.dataset.part);
}
nodes.forEach(function (node) {
node.addEventListener('click', function () { toggleNode(node); });
node.addEventListener('keydown', function (e) {
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggleNode(node); }
});
});
var speed = reducedMotion ? 0.35 : 1;
var appDur = 650 * speed;
var checkDurMiss = 500 * speed;
var fetchDur = 1800 * speed;
var returnDur = 650 * speed;
var cachedHold = 800 * speed;
var arcDurSlow = 650 * speed;
var betweenRuns = 650 * speed;
var checkDurHit = 300 * speed;
var hitHold = 750 * speed;
var arcDurFast = 400 * speed;
var gap = 180 * speed;
var timers = [];
function after(ms, fn) { timers.push(setTimeout(fn, ms)); }
function resetVisuals() {
setActive(null);
setArrow1(false); setArrow2(false); setArc(false);
processingRing.classList.remove('is-spinning');
missBadge.setAttribute('opacity', '0');
cachedBadge.setAttribute('opacity', '0');
hitBadge.setAttribute('opacity', '0');
daxNode.classList.remove('is-miss', 'is-hit');
ddbNode.classList.remove('is-miss');
}
runBtn.addEventListener('click', function () {
timers.forEach(clearTimeout);
timers = [];
runBtn.disabled = true;
resetVisuals();
var t = 0;
// ===== Request 1: cache MISS =====
after(t, function () {
setStatus('\u2460 App requests data');
setActive('app');
setArrow1(true);
fire('app', appDur);
});
t += appDur + gap * 0.3;
after(t, function () {
setArrow1(false);
setStatus('\u2461 DAX checks memory');
setActive('dax');
hidePulse('app');
if (!reducedMotion) processingRing.classList.add('is-spinning');
});
t += checkDurMiss;
after(t, function () {
processingRing.classList.remove('is-spinning');
setStatus('\u2463 MISS \u2014 fetch from DynamoDB, cache it for next time');
setActive(['dax', 'dynamodb']);
daxNode.classList.add('is-miss');
ddbNode.classList.add('is-miss');
missBadge.setAttribute('opacity', '1');
setArrow2(true);
fire('fetch', fetchDur);
});
t += fetchDur;
after(t, function () {
setArrow2(false);
hidePulse('fetch');
missBadge.setAttribute('opacity', '0');
daxNode.classList.remove('is-miss');
ddbNode.classList.remove('is-miss');
setActive(['dax', 'dynamodb']);
setArrow2(true);
fire('return', returnDur);
});
t += returnDur;
after(t, function () {
setArrow2(false);
hidePulse('return');
setActive('dax');
cachedBadge.setAttribute('opacity', '1');
});
t += cachedHold;
after(t, function () {
cachedBadge.setAttribute('opacity', '0');
setActive(['dax', 'app']);
setArc(true, false);
fire('arc', arcDurSlow);
});
t += arcDurSlow;
after(t, function () {
setArc(false);
hidePulse('arc');
setActive(null);
setStatus('Data now cached in DAX \u2014 next request \u2026');
});
t += betweenRuns;
// ===== Request 2: cache HIT =====
after(t, function () {
setStatus('\u2460 App requests data');
setActive('app');
setArrow1(true);
fire('app', appDur);
});
t += appDur + gap * 0.3;
after(t, function () {
setArrow1(false);
setStatus('\u2461 DAX checks memory');
setActive('dax');
hidePulse('app');
if (!reducedMotion) processingRing.classList.add('is-spinning');
});
t += checkDurHit;
after(t, function () {
processingRing.classList.remove('is-spinning');
setStatus('\u2462 HIT \u2014 return instantly');
daxNode.classList.add('is-hit');
hitBadge.setAttribute('opacity', '1');
setActive(['dax', 'app']);
setArc(true, true);
fire('arc', arcDurFast);
});
t += arcDurFast;
after(t, function () {
setArc(false);
hidePulse('arc');
appNode.classList.add('is-hit');
});
t += hitHold;
after(t, function () {
resetVisuals();
setStatus('\u00A0');
runBtn.disabled = false;
});
});
})();
</script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Fraunces:wght@500;600&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">1οΈβ£ App requests data β 2οΈβ£ DAX checks memory β 3οΈβ£ HIT: return instantly β 4οΈβ£ MISS: fetch from DynamoDB, cache it for next time.
π Performance
Without DAX: single-digit millisecond latency
With DAX: microsecond latency β up to 10Γ faster reads
π Fully Managed
AWS handles provisioning, maintenance, scaling, availability, and security.
π€ DAX vs ElastiCache
β‘ DAX | π ElastiCache |
|---|---|
Built specifically for DynamoDB | Works with many databases/apps |
Fully integrated with DynamoDB | General-purpose caching |
Optimized for DynamoDB workloads | Caches data from multiple sources |
Boosts DynamoDB read performance | Boosts performance broadly |
π‘ ElastiCache can cache DynamoDB data too, but DAX is purpose-built for it and integrates seamlessly.
π― Exam Tips
β‘ DynamoDB = fully managed, serverless NoSQL database
π Auto-replicated across 3 AZs for high availability
π Scales to millions of requests/sec and trillions of items
β‘ Single-digit millisecond latency
π Data stored as items with a Primary Key + attributes
π Auto-scaling + IAM integration for security
β‘ DAX = in-memory cache built for DynamoDB, up to 10Γ faster, microsecond latency
π‘ "Serverless NoSQL database" β DynamoDB. "Caching for DynamoDB" β DAX.