β‘ Amazon ElastiCache
Unlike RDS (disk-based), ElastiCache stores frequently accessed data in memory (RAM) for very high performance and very low latency.
π‘ Simple definition: A fully managed in-memory database service supporting Redis and Memcached β lets apps access hot data instantly while easing load on the primary database.
π€ What is an In-Memory Database?
π Disk (like RDS) β slower, built for durable permanent storage
β‘RAM (ElastiCache) β extremely fast, built for quick access to frequently used data
Reading from RAM is far faster than reading from disk β that's the whole performance story.
π― Exam tip: "In-memory database," "extremely fast," "very low latency" β ElastiCache
π οΈ Supported Engines
π΄ Redis
π΅ Memcached
AWS fully manages either engine.
π€ Why Use It?
If thousands of users repeatedly request the same data from RDS, the database ends up answering identical queries over and over β wasted work.
π‘ Caching stores that frequently accessed data in a fast layer so the app can check there first, instead of hitting the database every time.
ποΈ How It Works
Without caching:
<!-- ELB -> EC2 -> RDS (no cache): every request hits the DB directly and queries pile up. Self-contained, drop into codeveda.dev. -->
<div class="infographic-nocache">
<header class="nc-head">
<button class="nc-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>
</header>
<div class="nc-canvas">
<svg viewBox="0 0 760 280" xmlns="http://www.w3.org/2000/svg" class="nc-svg">
<defs>
<marker id="nc-arrow" 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"/>
</marker>
<marker id="nc-arrow-dashed" 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-dashed"/>
</marker>
</defs>
<!-- entry arrow -->
<line x1="8" y1="140" x2="58" y2="140" class="connector-line solid" marker-end="url(#nc-arrow)"/>
<!-- ELB -> EC2 -->
<line x1="132" y1="140" x2="280" y2="140" class="connector-line solid" marker-end="url(#nc-arrow)"/>
<!-- EC2 -> RDS -->
<line id="nc-line-rds" x1="368" y1="140" x2="560" y2="140" class="connector-line dashed" marker-end="url(#nc-arrow-dashed)"/>
<text x="464" y="122" text-anchor="middle" class="edge-label">Read / write</text>
<!-- motion path (invisible) for each request -->
<path id="nc-path-request" d="M20,140 L100,140 L324,140 L620,140" fill="none" stroke="none"/>
<!-- queue badge -->
<g id="nc-queue-badge" class="queue-badge" opacity="0">
<rect x="590" y="52" width="90" height="28" rx="14" class="queue-pill"/>
<text x="635" y="71" text-anchor="middle" class="queue-text">Queue: <tspan id="nc-queue-count">0</tspan></text>
</g>
<!-- ELB node -->
<g class="nc-node" data-part="elb" tabindex="0" role="button" aria-label="Elastic Load Balancer" aria-expanded="false">
<circle cx="100" cy="140" r="32" class="node-shape"/>
<g transform="translate(82,122) scale(1.5)">
<g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none" class="node-icon">
<rect x="16" y="16" width="6" height="6" rx="1"/><rect x="2" y="16" width="6" height="6" rx="1"/><rect x="9" y="2" width="6" height="6" rx="1"/><path d="M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3"/><path d="M12 12V8"/>
</g>
</g>
</g>
<text x="100" y="192" text-anchor="middle" class="node-label">Elastic Load Balancer</text>
<!-- EC2 node -->
<g class="nc-node" data-part="ec2" tabindex="0" role="button" aria-label="EC2 Instances" aria-expanded="false">
<circle id="nc-processing-ring" cx="324" cy="140" r="52" class="processing-ring"/>
<rect x="280" y="96" width="88" height="88" rx="14" class="node-shape"/>
<g transform="translate(296,112) scale(2.2)">
<g stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" fill="none" class="node-icon">
<path d="M12 20v2"/><path d="M12 2v2"/><path d="M17 20v2"/><path d="M17 2v2"/><path d="M2 12h2"/><path d="M2 17h2"/><path d="M2 7h2"/><path d="M20 12h2"/><path d="M20 17h2"/><path d="M20 7h2"/><path d="M7 20v2"/><path d="M7 2v2"/><rect x="4" y="4" width="16" height="16" rx="2"/><rect x="8" y="8" width="8" height="8" rx="1"/>
</g>
</g>
</g>
<text x="324" y="72" text-anchor="middle" class="node-label">EC2 Instances</text>
<text x="324" y="226" text-anchor="middle" class="node-label node-label--caption">Possibly in an ASG</text>
<!-- Amazon RDS node -->
<g class="nc-node" data-part="rds" tabindex="0" role="button" aria-label="Amazon RDS" aria-expanded="false">
<rect x="560" y="90" width="130" height="100" rx="12" class="node-shape"/>
<text x="588" y="120" class="node-label node-label--sm">Amazon</text>
<text x="588" y="136" class="node-label node-label--sm">RDS</text>
<g transform="translate(608,142) scale(1.35)"><g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none" class="node-icon"><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"/></g></g>
</g>
<text x="625" y="214" text-anchor="middle" class="node-label node-label--caption">SQL (relational)</text>
<text x="625" y="230" text-anchor="middle" class="node-label node-label--caption">Database</text>
<!-- request pulses (4 identical requests fired in quick succession) -->
<circle r="6" class="nc-pulse" id="nc-pulse-0" opacity="0"><animateMotion id="nc-motion-0" dur="1.1s" begin="indefinite" fill="freeze" calcMode="linear"><mpath href="#nc-path-request"/></animateMotion></circle>
<circle r="6" class="nc-pulse" id="nc-pulse-1" opacity="0"><animateMotion id="nc-motion-1" dur="1.1s" begin="indefinite" fill="freeze" calcMode="linear"><mpath href="#nc-path-request"/></animateMotion></circle>
<circle r="6" class="nc-pulse" id="nc-pulse-2" opacity="0"><animateMotion id="nc-motion-2" dur="1.1s" begin="indefinite" fill="freeze" calcMode="linear"><mpath href="#nc-path-request"/></animateMotion></circle>
<circle r="6" class="nc-pulse" id="nc-pulse-3" opacity="0"><animateMotion id="nc-motion-3" dur="1.1s" begin="indefinite" fill="freeze" calcMode="linear"><mpath href="#nc-path-request"/></animateMotion></circle>
</svg>
</div>
</div>
<style>
.infographic-nocache {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--error: #c0392b;
--error-soft: #fbe9e7;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -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-nocache[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--error: #e57373;
--error-soft: #3a2222;
}
.infographic-nocache * { box-sizing: border-box; }
.infographic-nocache .nc-head {
text-align: center;
padding: 0.5rem clamp(1rem, 4vw, 2rem) 1rem;
}
.infographic-nocache .nc-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-nocache .nc-run-btn:hover { opacity: 0.88; }
.infographic-nocache .nc-run-btn:disabled { opacity: 0.5; cursor: default; }
.infographic-nocache .run-icon { width: 15px; height: 15px; }
.infographic-nocache .nc-canvas { padding: 0 clamp(0.75rem, 3vw, 2rem) 1rem; }
.infographic-nocache .nc-svg { width: 100%; height: auto; display: block; overflow: visible; }
.infographic-nocache .connector-line { stroke: var(--line); stroke-width: 1.5; }
.infographic-nocache .connector-line.dashed { stroke-dasharray: 5 4; }
.infographic-nocache .arrow-fill { fill: var(--ink-soft); }
.infographic-nocache .arrow-fill-dashed { fill: var(--line); }
.infographic-nocache .edge-label { font-size: 13px; fill: var(--ink-soft); font-family: var(--body-font); }
.infographic-nocache .nc-node { cursor: pointer; outline: none; }
.infographic-nocache .nc-node .node-shape {
fill: var(--paper-alt);
stroke: var(--line);
stroke-width: 1.5;
transition: fill 0.2s, stroke 0.2s, opacity 0.15s;
}
.infographic-nocache .nc-node.is-active .node-shape { fill: var(--accent-soft); stroke: var(--accent); }
.infographic-nocache .nc-node.is-overloaded .node-shape { fill: var(--error-soft); stroke: var(--error); }
.infographic-nocache .nc-svg.has-active .nc-node:not(.is-active) { opacity: 0.45; }
.infographic-nocache .nc-node:focus-visible .node-shape { stroke: var(--accent); stroke-width: 2.5; }
.infographic-nocache .nc-pulse { fill: var(--accent); transition: opacity 0.2s; }
.infographic-nocache .processing-ring {
fill: none;
stroke: var(--accent);
stroke-width: 3;
stroke-dasharray: 10 8;
opacity: 0;
transform-origin: 324px 140px;
}
.infographic-nocache .processing-ring.is-spinning {
opacity: 0.8;
animation: nc-spin 0.9s linear infinite;
}
@keyframes nc-spin { to { transform: rotate(360deg); } }
.infographic-nocache .queue-badge { transition: opacity 0.2s; }
.infographic-nocache .queue-pill { fill: var(--ink); transition: fill 0.2s; }
.infographic-nocache .queue-badge.is-hot .queue-pill { fill: var(--error); }
.infographic-nocache .queue-text {
fill: var(--paper);
font-family: var(--body-font);
font-size: 13px;
font-weight: 700;
}
.infographic-nocache .node-icon { color: var(--accent); }
.infographic-nocache .node-label {
font-family: var(--display-font);
font-size: 15px;
font-weight: 500;
fill: var(--ink);
}
.infographic-nocache .node-label--sm { font-size: 13px; }
.infographic-nocache .node-label--caption { font-size: 13px; fill: var(--ink-soft); font-weight: 400; }
@media (prefers-reduced-motion: reduce) {
.infographic-nocache * { transition-duration: 0.001ms !important; animation-duration: 0.001ms !important; }
}
</style>
<script>
(function () {
var wrapper = document.currentScript.closest('.infographic-nocache')
|| document.querySelector('.infographic-nocache');
// --- dark mode detection (cookie / body attribute) ---
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('.nc-svg');
var nodes = wrapper.querySelectorAll('.nc-node');
var runBtn = wrapper.querySelector('.nc-run-btn');
var processingRing = wrapper.querySelector('#nc-processing-ring');
var rdsNode = wrapper.querySelector('.nc-node[data-part="rds"]');
var lineRds = wrapper.querySelector('#nc-line-rds');
var queueBadge = wrapper.querySelector('#nc-queue-badge');
var queueCountEl = wrapper.querySelector('#nc-queue-count');
var pulses = [
wrapper.querySelector('#nc-pulse-0'),
wrapper.querySelector('#nc-pulse-1'),
wrapper.querySelector('#nc-pulse-2'),
wrapper.querySelector('#nc-pulse-3')
];
var motions = [
wrapper.querySelector('#nc-motion-0'),
wrapper.querySelector('#nc-motion-1'),
wrapper.querySelector('#nc-motion-2'),
wrapper.querySelector('#nc-motion-3')
];
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 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 queueCount = 0;
function setQueue(n) {
queueCount = n;
queueCountEl.textContent = n;
queueBadge.classList.toggle('is-hot', n >= 2);
rdsNode.classList.toggle('is-overloaded', n >= 2);
}
// --- Run Flow: 4 identical requests fired in quick succession, all going straight to RDS ---
var speed = reducedMotion ? 0.35 : 1;
var requestInterval = 500 * speed; // how often a new request is fired
var travelDur = 1100 * speed; // ELB -> EC2 -> RDS travel time
var processDur = 900 * speed; // how long RDS takes to clear one query
var requestCount = 4;
var timers = [];
function after(ms, fn) { timers.push(setTimeout(fn, ms)); }
runBtn.addEventListener('click', function () {
timers.forEach(clearTimeout);
timers = [];
runBtn.disabled = true;
setActive(null);
processingRing.classList.remove('is-spinning');
lineRds.classList.remove('is-flowing');
setQueue(0);
queueBadge.setAttribute('opacity', '1');
if (!reducedMotion) processingRing.classList.add('is-spinning');
setActive(['elb', 'ec2', 'rds']);
lineRds.classList.add('is-flowing');
// fire the 4 requests, staggered β arriving faster than RDS can clear them
var arrivalTimes = [];
for (var i = 0; i < requestCount; i++) {
(function (idx) {
after(idx * requestInterval, function () {
pulses[idx].setAttribute('opacity', reducedMotion ? '0' : '1');
try { motions[idx].beginElement(); } catch (e) { /* Safari fallback: queue counter still plays */ }
});
})(i);
var arrival = i * requestInterval + travelDur;
arrivalTimes.push(arrival);
after(arrival, function () {
setQueue(queueCount + 1);
});
}
// process the queue one item at a time, starting once the first request lands
var t = arrivalTimes[0];
for (var j = 0; j < requestCount; j++) {
var startAt = Math.max(t, arrivalTimes[j]);
t = startAt + processDur;
after(t, function () {
setQueue(Math.max(0, queueCount - 1));
});
}
var totalDur = t + 400 * speed;
after(totalDur, function () {
processingRing.classList.remove('is-spinning');
lineRds.classList.remove('is-flowing');
pulses.forEach(function (p) { p.setAttribute('opacity', '0'); });
});
after(totalDur + 600 * speed, function () {
setActive(null);
queueBadge.setAttribute('opacity', '0');
runBtn.disabled = false;
});
});
})();
</script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Fraunces:wght@500&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">1οΈβ£ Every request β 2οΈβ£ Straight to RDS β 3οΈβ£ Repeated identical queries pile up.
With caching:
<!-- ELB -> EC2 -> ElastiCache / Amazon RDS fork. Self-contained, drop into codeveda.dev. -->
<div class="infographic-cachefork">
<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>
</header>
<div class="cf-canvas">
<svg viewBox="0 0 900 480" xmlns="http://www.w3.org/2000/svg" class="cf-svg">
<defs>
<marker id="cf-arrow" 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"/>
</marker>
<marker id="cf-arrow-dashed" 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-dashed"/>
</marker>
</defs>
<!-- entry arrow -->
<line x1="8" y1="240" x2="58" y2="240" class="connector-line solid" marker-end="url(#cf-arrow)"/>
<!-- ELB -> EC2 -->
<line x1="130" y1="240" x2="286" y2="240" class="connector-line solid" marker-end="url(#cf-arrow)"/>
<!-- EC2 -> ElastiCache / RDS fork -->
<line id="cf-line-cache" x1="358" y1="228" x2="620" y2="130" class="connector-line dashed" marker-end="url(#cf-arrow-dashed)"/>
<line id="cf-line-rds" x1="358" y1="252" x2="620" y2="350" class="connector-line dashed" marker-end="url(#cf-arrow-dashed)"/>
<text x="500" y="152" class="edge-label edge-label--cache">Read / write from cache</text>
<text x="500" y="170" class="edge-label edge-label--cache-sm">Fast</text>
<text x="500" y="368" class="edge-label edge-label--rds">Read / write</text>
<text x="500" y="386" class="edge-label edge-label--rds">from DB</text>
<text x="500" y="404" class="edge-label edge-label--rds-sm">Slower</text>
<!-- motion paths (invisible) for the run animation -->
<path id="cf-path-elb" d="M20,240 L110,240" fill="none" stroke="none"/>
<path id="cf-path-ec2" d="M110,240 L322,240" fill="none" stroke="none"/>
<path id="cf-path-cache" d="M322,240 L650,142" fill="none" stroke="none"/>
<path id="cf-path-cache-rt" d="M370,232 L610,148 L370,232" fill="none" stroke="none"/>
<path id="cf-path-rds" d="M322,240 L650,368 L322,240" fill="none" stroke="none"/>
<!-- ELB node -->
<g class="cf-node" data-part="elb" tabindex="0" role="button" aria-label="Elastic Load Balancer" aria-expanded="false">
<circle cx="110" cy="240" r="32" class="node-shape"/>
<g transform="translate(92,222) scale(1.5)">
<g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none" class="node-icon">
<rect x="16" y="16" width="6" height="6" rx="1"/><rect x="2" y="16" width="6" height="6" rx="1"/><rect x="9" y="2" width="6" height="6" rx="1"/><path d="M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3"/><path d="M12 12V8"/>
</g>
</g>
</g>
<text x="110" y="292" text-anchor="middle" class="node-label">Elastic Load Balancer</text>
<!-- EC2 node -->
<g class="cf-node" data-part="ec2" tabindex="0" role="button" aria-label="EC2 Instances" aria-expanded="false">
<circle id="cf-processing-ring" cx="330" cy="240" r="52" class="processing-ring"/>
<rect x="286" y="196" width="88" height="88" rx="14" class="node-shape"/>
<g transform="translate(302,212) scale(2.2)">
<g stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" fill="none" class="node-icon">
<path d="M12 20v2"/><path d="M12 2v2"/><path d="M17 20v2"/><path d="M17 2v2"/><path d="M2 12h2"/><path d="M2 17h2"/><path d="M2 7h2"/><path d="M20 12h2"/><path d="M20 17h2"/><path d="M20 7h2"/><path d="M7 20v2"/><path d="M7 2v2"/><rect x="4" y="4" width="16" height="16" rx="2"/><rect x="8" y="8" width="8" height="8" rx="1"/>
</g>
</g>
</g>
<text x="330" y="172" text-anchor="middle" class="node-label">EC2 Instances</text>
<text x="330" y="326" text-anchor="middle" class="node-label node-label--caption">Possibly in an ASG</text>
<!-- ElastiCache node -->
<g class="cf-node" data-part="cache" tabindex="0" role="button" aria-label="ElastiCache in-memory database" aria-expanded="false">
<rect x="650" y="60" width="120" height="120" rx="10" class="node-shape"/>
<g transform="translate(710,124)">
<g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none" class="node-icon">
<!-- left rack -->
<rect x="-38" y="-19" width="19" height="38" rx="4"/>
<line x1="-34" y1="-11" x2="-23" y2="-11"/>
<line x1="-34" y1="-3" x2="-23" y2="-3"/>
<line x1="-34" y1="5" x2="-23" y2="5"/>
<line x1="-34" y1="13" x2="-23" y2="13"/>
<!-- right rack -->
<rect x="19" y="-19" width="19" height="38" rx="4"/>
<line x1="23" y1="-11" x2="34" y2="-11"/>
<line x1="23" y1="-3" x2="34" y2="-3"/>
<line x1="23" y1="5" x2="34" y2="5"/>
<line x1="23" y1="13" x2="34" y2="13"/>
</g>
<g stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" fill="var(--paper-alt)" class="node-icon">
<ellipse cx="0" cy="-15" rx="24" ry="8"/>
<path d="M-24,-15 V15 A24,8 0 0 0 24,15 V-15"/>
<path d="M-24,0 A24,8 0 0 0 24,0"/>
</g>
</g>
</g>
<text x="710" y="42" text-anchor="middle" class="node-label node-label--title">ElastiCache</text>
<text x="710" y="200" text-anchor="middle" class="node-label node-label--caption">In-memory database</text>
<!-- Amazon RDS node -->
<g class="cf-node" data-part="rds" tabindex="0" role="button" aria-label="Amazon RDS" aria-expanded="false">
<rect x="650" y="300" width="120" height="100" rx="12" class="node-shape"/>
<text x="676" y="330" class="node-label node-label--sm">Amazon</text>
<text x="676" y="346" class="node-label node-label--sm">RDS</text>
<g transform="translate(696,352) scale(1.35)"><g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none" class="node-icon"><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"/></g></g>
</g>
<text x="710" y="424" text-anchor="middle" class="node-label node-label--caption">SQL (relational)</text>
<text x="710" y="440" text-anchor="middle" class="node-label node-label--caption">Database</text>
<!-- cache miss badge -->
<g id="cf-miss-badge" class="miss-badge" opacity="0">
<rect x="656" y="188" width="60" height="26" rx="13" class="miss-pill"/>
<text x="686" y="205" text-anchor="middle" class="miss-text">MISS</text>
</g>
<!-- cache stored badge -->
<g id="cf-cached-badge" class="cached-badge" opacity="0">
<rect x="644" y="188" width="132" height="26" rx="13" class="cached-pill"/>
<text x="710" y="205" text-anchor="middle" class="cached-text">Stored for next time</text>
</g>
<!-- pulses -->
<circle r="7" class="cf-pulse" id="cf-pulse-store" opacity="0"><animateMotion id="cf-motion-store" dur="0.8s" begin="indefinite" fill="freeze" calcMode="linear"><mpath href="#cf-path-cache"/></animateMotion></circle>
<circle r="7" class="cf-pulse" id="cf-pulse-elb" opacity="0"><animateMotion id="cf-motion-elb" dur="0.8s" begin="indefinite" fill="freeze" calcMode="linear"><mpath href="#cf-path-elb"/></animateMotion></circle>
<circle r="7" class="cf-pulse" id="cf-pulse-ec2" opacity="0"><animateMotion id="cf-motion-ec2" dur="0.9s" begin="indefinite" fill="freeze" calcMode="linear"><mpath href="#cf-path-ec2"/></animateMotion></circle>
<circle r="7" class="cf-pulse" id="cf-pulse-cache" opacity="0"><animateMotion id="cf-motion-cache" dur="0.5s" begin="indefinite" fill="freeze" calcMode="linear"><mpath href="#cf-path-cache-rt"/></animateMotion></circle>
<circle r="7" class="cf-pulse" id="cf-pulse-rds" opacity="0"><animateMotion id="cf-motion-rds" dur="1.6s" begin="indefinite" fill="freeze" calcMode="linear"><mpath href="#cf-path-rds"/></animateMotion></circle>
</svg>
</div>
</div>
<style>
.infographic-cachefork {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-deep:#1d4ed8;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--onfill: #f7f5f1;
--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: 880px;
margin: 0 auto;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-cachefork[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-deep:#3a63c4;
--accent-soft:#202942;
--line: #2c313d;
--error: #e57373;
--error-soft: #3a2222;
--success: #4caf7d;
--success-soft:#1c332a;
}
.infographic-cachefork * { box-sizing: border-box; }
.infographic-cachefork .cf-head {
text-align: center;
padding: 0.5rem clamp(1rem, 4vw, 2rem) 1rem;
}
.infographic-cachefork .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-cachefork .cf-run-btn:hover { opacity: 0.88; }
.infographic-cachefork .cf-run-btn:disabled { opacity: 0.5; cursor: default; }
.infographic-cachefork .run-icon { width: 15px; height: 15px; }
.infographic-cachefork .cf-canvas { padding: 0 clamp(0.75rem, 3vw, 2rem) 1rem; }
.infographic-cachefork .cf-svg { width: 100%; height: auto; display: block; overflow: visible; }
.infographic-cachefork .connector-line {
stroke: var(--line);
stroke-width: 1.5;
}
.infographic-cachefork .connector-line.dashed { stroke-dasharray: 5 4; }
.infographic-cachefork .arrow-fill { fill: var(--ink-soft); }
.infographic-cachefork .arrow-fill-dashed { fill: var(--line); }
.infographic-cachefork .connector-line.is-flowing {
stroke: var(--accent);
stroke-width: 2.5;
stroke-dasharray: 6 4;
animation: cf-flow 0.6s linear infinite;
}
@keyframes cf-flow { to { stroke-dashoffset: -20; } }
.infographic-cachefork .edge-label { font-size: 13px; fill: var(--ink); font-family: var(--body-font); }
.infographic-cachefork .edge-label--cache { fill: var(--ink); }
.infographic-cachefork .edge-label--cache-sm { fill: var(--ink-soft); font-size: 12px; }
.infographic-cachefork .edge-label--rds { fill: var(--ink); }
.infographic-cachefork .edge-label--rds-sm { fill: var(--ink-soft); font-size: 12px; }
.infographic-cachefork .cf-node { cursor: pointer; outline: none; }
.infographic-cachefork .cf-node .node-shape {
fill: var(--paper-alt);
stroke: var(--line);
stroke-width: 1.5;
transition: fill 0.15s, stroke 0.15s, opacity 0.15s;
}
.infographic-cachefork .cf-node.is-active .node-shape { fill: var(--accent-soft); stroke: var(--accent); }
.infographic-cachefork .cf-node.is-miss .node-shape {
fill: var(--error-soft);
stroke: var(--error);
transition: fill 0.15s, stroke 0.15s;
}
.infographic-cachefork .cf-svg.has-active .cf-node:not(.is-active) { opacity: 0.45; }
.infographic-cachefork .cf-node:focus-visible .node-shape { stroke: var(--accent); stroke-width: 2.5; }
.infographic-cachefork .cf-pulse { fill: var(--accent); transition: opacity 0.2s; }
.infographic-cachefork .processing-ring {
fill: none;
stroke: var(--accent);
stroke-width: 3;
stroke-dasharray: 10 8;
opacity: 0;
transform-origin: 330px 240px;
}
.infographic-cachefork .processing-ring.is-spinning {
opacity: 0.8;
animation: cf-spin 0.9s linear infinite;
}
@keyframes cf-spin { to { transform: rotate(360deg); } }
.infographic-cachefork .miss-badge { transition: opacity 0.2s; }
.infographic-cachefork .miss-pill { fill: var(--ink); }
.infographic-cachefork .miss-text {
fill: var(--paper);
font-family: var(--body-font);
font-size: 12px;
font-weight: 700;
letter-spacing: 0.04em;
}
.infographic-cachefork .cached-badge { transition: opacity 0.2s; }
.infographic-cachefork .cached-pill { fill: var(--success); }
.infographic-cachefork .cached-text {
fill: var(--paper);
font-family: var(--body-font);
font-size: 12px;
font-weight: 700;
}
.infographic-cachefork .cf-node.is-cached .node-shape {
fill: var(--success-soft);
stroke: var(--success);
transition: fill 0.15s, stroke 0.15s;
}
.infographic-cachefork .node-icon--soft { color: var(--ink-soft); }
.infographic-cachefork .node-icon { color: var(--accent); }
.infographic-cachefork .node-icon--onfill { color: var(--onfill); }
.infographic-cachefork .node-label {
font-family: var(--display-font);
font-size: 15px;
font-weight: 500;
fill: var(--ink);
}
.infographic-cachefork .node-label--title { font-size: 17px; font-weight: 600; }
.infographic-cachefork .node-label--sm { font-size: 13px; }
.infographic-cachefork .node-label--caption { font-size: 13px; fill: var(--ink-soft); font-weight: 400; }
@media (prefers-reduced-motion: reduce) {
.infographic-cachefork * { transition-duration: 0.001ms !important; animation-duration: 0.001ms !important; }
}
</style>
<script>
(function () {
var wrapper = document.currentScript.closest('.infographic-cachefork')
|| document.querySelector('.infographic-cachefork');
// --- dark mode detection (cookie / body attribute) ---
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 processingRing = wrapper.querySelector('#cf-processing-ring');
var missBadge = wrapper.querySelector('#cf-miss-badge');
var cachedBadge = wrapper.querySelector('#cf-cached-badge');
var cacheNode = wrapper.querySelector('.cf-node[data-part="cache"]');
var lines = {
cache: wrapper.querySelector('#cf-line-cache'),
rds: wrapper.querySelector('#cf-line-rds')
};
var pulses = {
elb: wrapper.querySelector('#cf-pulse-elb'),
ec2: wrapper.querySelector('#cf-pulse-ec2'),
cache: wrapper.querySelector('#cf-pulse-cache'),
rds: wrapper.querySelector('#cf-pulse-rds'),
store: wrapper.querySelector('#cf-pulse-store')
};
var motions = {
elb: wrapper.querySelector('#cf-motion-elb'),
ec2: wrapper.querySelector('#cf-motion-ec2'),
cache: wrapper.querySelector('#cf-motion-cache'),
rds: wrapper.querySelector('#cf-motion-rds'),
store: wrapper.querySelector('#cf-motion-store')
};
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 setLine(key, on) { lines[key].classList.toggle('is-flowing', on); }
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: state highlights still play */ }
}
function hidePulse(key) { pulses[key].setAttribute('opacity', '0'); }
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); }
});
});
// --- Run Flow: request travels ELB -> EC2 (processing), checks the fast cache (round trips), misses, falls back to the slower DB ---
var speed = reducedMotion ? 0.35 : 1;
var elbDur = 800 * speed;
var ec2Dur = 1100 * speed;
var cacheTrip = 500 * speed;
var cacheTrips = 3;
var missDur = 700 * speed;
var rdsDur = 2600 * speed;
var storeDur = 700 * speed;
var cachedHoldDur = 900 * speed;
var gap = 250 * speed;
var timers = [];
function after(ms, fn) { timers.push(setTimeout(fn, ms)); }
runBtn.addEventListener('click', function () {
timers.forEach(clearTimeout);
timers = [];
runBtn.disabled = true;
setActive(null);
setLine('cache', false);
setLine('rds', false);
processingRing.classList.remove('is-spinning');
missBadge.setAttribute('opacity', '0');
cacheNode.classList.remove('is-miss');
cacheNode.classList.remove('is-cached');
cachedBadge.setAttribute('opacity', '0');
var t = 0;
// Stage 1: request enters and reaches the ELB
after(t, function () {
setActive('elb');
fire('elb', elbDur);
});
t += elbDur + gap * 0.3;
// Stage 2: ELB forwards to an EC2 instance β it spins while deciding what to do
after(t, function () {
setActive('ec2');
hidePulse('elb');
fire('ec2', ec2Dur);
if (!reducedMotion) processingRing.classList.add('is-spinning');
});
t += ec2Dur + gap * 0.3;
after(t, function () {
processingRing.classList.remove('is-spinning');
});
// Stage 3: EC2 checks the cache first β quick round trips, fast path
after(t, function () {
setActive('cache');
hidePulse('ec2');
setLine('cache', true);
});
for (var i = 0; i < cacheTrips; i++) {
after(t + i * cacheTrip, function () { fire('cache', cacheTrip); });
}
var cachePhaseDur = cacheTrips * cacheTrip;
after(t + cachePhaseDur, function () {
setLine('cache', false);
hidePulse('cache');
});
t += cachePhaseDur + gap * 0.3;
// Stage 3b: cache miss β no data found, node flashes red with a badge
after(t, function () {
missBadge.setAttribute('opacity', '1');
cacheNode.classList.add('is-miss');
});
after(t + missDur, function () {
missBadge.setAttribute('opacity', '0');
cacheNode.classList.remove('is-miss');
});
t += missDur + gap;
// Stage 4: on the miss, EC2 falls back to the database β noticeably slower path
after(t, function () {
setActive('rds');
setLine('rds', true);
fire('rds', rdsDur);
});
after(t + rdsDur, function () {
setLine('rds', false);
hidePulse('rds');
});
t += rdsDur + gap;
// Stage 5: EC2 stores the result in ElastiCache so the next request is a hit
after(t, function () {
setActive(['ec2', 'cache']);
setLine('cache', true);
fire('store', storeDur);
});
after(t + storeDur, function () {
setLine('cache', false);
hidePulse('store');
cacheNode.classList.add('is-cached');
cachedBadge.setAttribute('opacity', '1');
});
t += storeDur + cachedHoldDur;
after(t, function () {
cacheNode.classList.remove('is-cached');
cachedBadge.setAttribute('opacity', '0');
});
t += gap;
// Reset
after(t, function () {
setActive(null);
runBtn.disabled = false;
});
});
})();
</script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Fraunces:wght@500&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">1οΈβ£ App gets a request β 2οΈβ£ Checks ElastiCache first β 3οΈβ£ HIT: Return instantly β 4οΈβ£ MISS: Fetch from RDS β 5οΈβ£ Store it in ElastiCache for next time.
This cuts unnecessary database queries and boosts performance.
Data lives entirely in RAM, so you get:
β‘ Faster response times
β±οΈ Lower latency
π Better user experience
π Less load on the primary database
Reduce database load. Repeated identical reads get served from cache, freeing RDS to focus on new or changing data.
π High performance β memory beats disk
β±οΈ Very low latency β milliseconds or microseconds
π Reduced DB load β cache absorbs repeat reads
π Better UX β especially under heavy traffic
AWS handles OS maintenance, security patching, optimization, setup, monitoring, failure recovery, and backups (where supported, e.g. Redis) β so you just build your app.
π RDS vs ElastiCache
ποΈ RDS | β‘ ElastiCache |
|---|---|
Relational data | Cached, frequently accessed data |
Disk storage | In-memory (RAM) |
Long-term storage | Temporary, fast access |
Slower | Extremely fast |
Primary database | Cache layer |
π‘ ElastiCache doesn't replace RDS β it works alongside it.
π§ Putting It Together
<!-- Static diagram: Users -> LB -> EC2 -> ElastiCache (hit) / RDS (miss, then cached). Self-contained, drop into codeveda.dev. -->
<div class="infographic-cacheflow">
<div class="cfx-canvas">
<svg viewBox="0 0 900 430" xmlns="http://www.w3.org/2000/svg" class="cfx-svg">
<defs>
<marker id="cfx-arrow" 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"/>
</marker>
<marker id="cfx-arrow-dashed" 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-dashed"/>
</marker>
</defs>
<!-- Users -> LB -->
<line x1="60" y1="210" x2="128" y2="210" class="connector-line solid" marker-end="url(#cfx-arrow)"/>
<!-- LB -> EC2 -->
<line x1="192" y1="210" x2="330" y2="210" class="connector-line solid" marker-end="url(#cfx-arrow)"/>
<!-- EC2 -> Cache (checked first) -->
<line x1="404" y1="196" x2="628" y2="120" class="connector-line dashed" marker-end="url(#cfx-arrow-dashed)"/>
<text x="500" y="140" class="edge-label edge-label--step">1. Check cache</text>
<!-- Cache -> RDS (on miss) -->
<line x1="700" y1="185" x2="700" y2="298" class="connector-line dashed" marker-end="url(#cfx-arrow-dashed)"/>
<text x="718" y="230" class="edge-label edge-label--miss">Miss β</text>
<text x="718" y="247" class="edge-label edge-label--miss">query RDS</text>
<!-- RDS -> Cache (store result) -->
<line x1="644" y1="330" x2="600" y2="188" class="connector-line dashed" marker-end="url(#cfx-arrow-dashed)"/>
<text x="548" y="270" text-anchor="middle" class="edge-label edge-label--store">3. Store result</text>
<text x="548" y="287" text-anchor="middle" class="edge-label edge-label--store-sm">for next time</text>
<!-- Cache hit label -->
<text x="732" y="76" text-anchor="start" class="edge-label edge-label--hit">Hit β</text>
<text x="732" y="93" text-anchor="start" class="edge-label edge-label--hit">fast response</text>
<!-- Users node -->
<g class="cfx-node">
<circle cx="30" cy="210" r="24" class="node-shape"/>
<g transform="translate(16,196) scale(1.2)">
<g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none" class="node-icon">
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><path d="M16 3.128a4 4 0 0 1 0 7.744"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><circle cx="9" cy="7" r="4"/>
</g>
</g>
</g>
<text x="30" y="255" text-anchor="middle" class="node-label node-label--sm">Users</text>
<!-- Load Balancer node -->
<g class="cfx-node">
<circle cx="160" cy="210" r="32" class="node-shape"/>
<g transform="translate(142,192) scale(1.5)">
<g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none" class="node-icon">
<rect x="16" y="16" width="6" height="6" rx="1"/><rect x="2" y="16" width="6" height="6" rx="1"/><rect x="9" y="2" width="6" height="6" rx="1"/><path d="M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3"/><path d="M12 12V8"/>
</g>
</g>
</g>
<text x="160" y="262" text-anchor="middle" class="node-label">Load Balancer</text>
<!-- EC2 node -->
<g class="cfx-node">
<rect x="330" y="166" width="80" height="80" rx="14" class="node-shape"/>
<g transform="translate(344,180) scale(2)">
<g stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" fill="none" class="node-icon">
<path d="M12 20v2"/><path d="M12 2v2"/><path d="M17 20v2"/><path d="M17 2v2"/><path d="M2 12h2"/><path d="M2 17h2"/><path d="M2 7h2"/><path d="M20 12h2"/><path d="M20 17h2"/><path d="M20 7h2"/><path d="M7 20v2"/><path d="M7 2v2"/><rect x="4" y="4" width="16" height="16" rx="2"/><rect x="8" y="8" width="8" height="8" rx="1"/>
</g>
</g>
</g>
<text x="370" y="142" text-anchor="middle" class="node-label">EC2 Instances</text>
<text x="370" y="266" text-anchor="middle" class="node-label node-label--caption">Possibly in an ASG</text>
<!-- ElastiCache node -->
<g class="cfx-node">
<rect x="628" y="30" width="100" height="100" rx="10" class="node-shape"/>
<g transform="translate(678,84)">
<g stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" fill="none" class="node-icon">
<rect x="-32" y="-16" width="16" height="32" rx="4"/>
<line x1="-29" y1="-9" x2="-20" y2="-9"/><line x1="-29" y1="-2" x2="-20" y2="-2"/><line x1="-29" y1="5" x2="-20" y2="5"/><line x1="-29" y1="12" x2="-20" y2="12"/>
<rect x="16" y="-16" width="16" height="32" rx="4"/>
<line x1="20" y1="-9" x2="29" y2="-9"/><line x1="20" y1="-2" x2="29" y2="-2"/><line x1="20" y1="5" x2="29" y2="5"/><line x1="20" y1="12" x2="29" y2="12"/>
</g>
<g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="var(--paper-alt)" class="node-icon">
<ellipse cx="0" cy="-13" rx="20" ry="7"/>
<path d="M-20,-13 V13 A20,7 0 0 0 20,13 V-13"/>
<path d="M-20,0 A20,7 0 0 0 20,0"/>
</g>
</g>
</g>
<text x="678" y="16" text-anchor="middle" class="node-label node-label--title">ElastiCache</text>
<text x="678" y="150" text-anchor="middle" class="node-label node-label--caption">In-memory database</text>
<!-- Amazon RDS node -->
<g class="cfx-node">
<rect x="644" y="300" width="112" height="90" rx="12" class="node-shape"/>
<text x="668" y="326" class="node-label node-label--sm">Amazon</text>
<text x="668" y="341" class="node-label node-label--sm">RDS</text>
<g transform="translate(686,346) scale(1.2)"><g stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none" class="node-icon"><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"/></g></g>
</g>
<text x="700" y="408" text-anchor="middle" class="node-label node-label--caption">SQL (relational) Database</text>
</svg>
<p class="cfx-takeaway">Fewer direct queries, faster app.</p>
</div>
</div>
<style>
.infographic-cacheflow {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -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-cacheflow[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
}
.infographic-cacheflow * { box-sizing: border-box; }
.infographic-cacheflow .cfx-canvas { padding: 1.5rem clamp(0.75rem, 3vw, 2rem) 1.5rem; }
.infographic-cacheflow .cfx-svg { width: 100%; height: auto; display: block; overflow: visible; }
.infographic-cacheflow .connector-line { stroke: var(--line); stroke-width: 1.5; }
.infographic-cacheflow .connector-line.dashed { stroke-dasharray: 5 4; }
.infographic-cacheflow .arrow-fill { fill: var(--ink-soft); }
.infographic-cacheflow .arrow-fill-dashed { fill: var(--line); }
.infographic-cacheflow .edge-label { font-size: 12.5px; fill: var(--ink-soft); font-family: var(--body-font); }
.infographic-cacheflow .edge-label--step { fill: var(--ink); font-weight: 600; }
.infographic-cacheflow .edge-label--hit { fill: var(--accent); font-weight: 600; font-size: 13px; }
.infographic-cacheflow .edge-label--miss { fill: var(--ink); font-weight: 600; }
.infographic-cacheflow .edge-label--store { fill: var(--ink); font-weight: 600; }
.infographic-cacheflow .edge-label--store-sm { fill: var(--ink-soft); font-size: 11.5px; }
.infographic-cacheflow .cfx-node .node-shape {
fill: var(--paper-alt);
stroke: var(--line);
stroke-width: 1.5;
}
.infographic-cacheflow .node-icon { color: var(--accent); }
.infographic-cacheflow .node-label {
font-family: var(--display-font);
font-size: 15px;
font-weight: 500;
fill: var(--ink);
}
.infographic-cacheflow .node-label--title { font-size: 16px; font-weight: 600; }
.infographic-cacheflow .node-label--sm { font-size: 13px; }
.infographic-cacheflow .node-label--caption { font-size: 12.5px; fill: var(--ink-soft); font-weight: 400; }
.infographic-cacheflow .cfx-takeaway {
text-align: center;
font-family: var(--display-font);
font-size: 1.05rem;
font-weight: 500;
color: var(--ink);
margin: 1.25rem 0 0;
}
</style>
<script>
(function () {
var wrapper = document.currentScript.closest('.infographic-cacheflow')
|| document.querySelector('.infographic-cacheflow');
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>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Fraunces:wght@500&family=Inter:wght@400;500;600&display=swap" rel="stylesheet"><!-- Icon-annotated flow strip: Users -> LB -> EC2 -> ElastiCache -> RDS. Self-contained, drop into codeveda.dev. -->
<div class="infographic-flowstrip">
<div class="fs-row">
<span class="fs-chip">
<svg class="fs-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><path d="M16 3.128a4 4 0 0 1 0 7.744"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><circle cx="9" cy="7" r="4"/></svg>
<span class="fs-label">Users</span>
</span>
<span class="fs-arrow">β</span>
<span class="fs-chip">
<svg class="fs-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="16" y="16" width="6" height="6" rx="1"/><rect x="2" y="16" width="6" height="6" rx="1"/><rect x="9" y="2" width="6" height="6" rx="1"/><path d="M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3"/><path d="M12 12V8"/></svg>
<span class="fs-label">Load Balancer</span>
</span>
<span class="fs-arrow">β</span>
<span class="fs-chip">
<svg class="fs-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20v2"/><path d="M12 2v2"/><path d="M17 20v2"/><path d="M17 2v2"/><path d="M2 12h2"/><path d="M2 17h2"/><path d="M2 7h2"/><path d="M20 12h2"/><path d="M20 17h2"/><path d="M20 7h2"/><path d="M7 20v2"/><path d="M7 2v2"/><rect x="4" y="4" width="16" height="16" rx="2"/><rect x="8" y="8" width="8" height="8" rx="1"/></svg>
<span class="fs-label">EC2</span>
</span>
<span class="fs-text">checks</span>
<span class="fs-chip">
<svg class="fs-icon fs-icon--cache" viewBox="0 0 64 40" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round">
<rect x="2" y="4" width="16" height="32" rx="4"/>
<line x1="5" y1="11" x2="14" y2="11"/><line x1="5" y1="18" x2="14" y2="18"/><line x1="5" y1="25" x2="14" y2="25"/><line x1="5" y1="32" x2="14" y2="32"/>
<rect x="46" y="4" width="16" height="32" rx="4"/>
<line x1="50" y1="11" x2="59" y2="11"/><line x1="50" y1="18" x2="59" y2="18"/><line x1="50" y1="25" x2="59" y2="25"/><line x1="50" y1="32" x2="59" y2="32"/>
<g fill="var(--paper-alt)">
<ellipse cx="32" cy="7" rx="20" ry="7"/>
<path d="M12,7 V33 A20,7 0 0 0 52,33 V7"/>
<path d="M12,20 A20,7 0 0 0 52,20"/>
</g>
</svg>
<span class="fs-label">ElastiCache</span>
</span>
<span class="fs-text">first β</span>
<span class="fs-text">falls back to</span>
<span class="fs-chip">
<svg class="fs-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" 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>
<span class="fs-label">RDS</span>
</span>
<span class="fs-text">on a miss, caching the result for next time.</span>
</div>
</div>
<style>
.infographic-flowstrip {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -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);
padding: 1.5rem clamp(1rem, 4vw, 2rem);
}
.infographic-flowstrip[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
}
.infographic-flowstrip * { box-sizing: border-box; }
.infographic-flowstrip .fs-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.5rem 0.4rem;
line-height: 1.4;
}
.infographic-flowstrip .fs-chip {
display: inline-flex;
align-items: center;
gap: 0.35rem;
background: var(--paper-alt);
border: 1px solid var(--line);
border-radius: 999px;
padding: 0.3rem 0.75rem 0.3rem 0.5rem;
}
.infographic-flowstrip .fs-icon {
width: 18px;
height: 18px;
color: var(--accent);
flex: none;
}
.infographic-flowstrip .fs-icon--cache { width: 26px; height: 16px; }
.infographic-flowstrip .fs-label {
font-family: var(--display-font);
font-weight: 500;
font-size: 0.92rem;
color: var(--ink);
white-space: nowrap;
}
.infographic-flowstrip .fs-arrow {
color: var(--ink-soft);
font-size: 1rem;
}
.infographic-flowstrip .fs-text {
color: var(--ink-soft);
font-size: 0.92rem;
}
.infographic-flowstrip .fs-takeaway {
font-family: var(--display-font);
font-size: 1.05rem;
font-weight: 500;
color: var(--ink);
margin: 1rem 0 0;
}
</style>
<script>
(function () {
var wrapper = document.currentScript.closest('.infographic-flowstrip')
|| document.querySelector('.infographic-flowstrip');
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>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Fraunces:wght@500&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">π― Exam Tips
β‘ ElastiCache = fully managed in-memory database service
π΄ Supports Redis and π΅ Memcached
π Used to cache frequently accessed data, cutting repeat queries to the primary DB
π Reduces read pressure on RDS
π§ Data lives in RAM β much faster than disk
π‘ "In-memory database" / "very low latency" / "high-performance caching" β ElastiCache