SCALABILITY & PERFORMANCE / SYSTEM CONCEPT BRIEF

Caching

A cache stores copies of frequently used data in a faster location so future requests avoid slow work.

BeginnerPhase 03 / Topic 4 of 13RequirementsTrade-offsFailure modes
01

Overview

A cache stores copies of frequently used data in a faster location so future requests avoid slow work. Reading from memory takes about 100 nanoseconds; a database query across the network commonly takes 1 to 10 milliseconds or more.

Caching appears at every layer: the browser, CDN, reverse proxy, application memory, distributed caches like Redis, and the database's own buffer pool. Each layer trades freshness for speed, so the core design question is always: how stale is acceptable?

Your desk vs the library

Books you use every day stay on your desk. Rarely used books stay in the library. When your desk is full, you return the book you have not touched in the longest time. That is an LRU cache.

02

When caching helps

  • Reads greatly outnumber writes (for example 100:1 on product pages).
  • The same data is requested repeatedly (skewed access: a few items are very popular).
  • The source is slow or expensive: complex queries, external APIs, rendering, ML inference.
  • Slightly stale data is acceptable for a short time.
03

Where it shows up in interviews

Read-heavy workloads

Recognize it when: reads outnumber writes 10:1 or more.

  • Design a news feed
  • Design a product catalog
  • Design a URL shortener's redirects
Expensive computations

Recognize it when: results are costly to compute but reused.

  • Design a leaderboard
  • Design a recommendation service
04

Where it is used in real software

Facebook memcache

Facebook serves billions of reads per second from memcache clusters in front of MySQL.

Redis / ElastiCache

The default cache for sessions, hot objects, rate limits, and leaderboards in most cloud architectures.

CDNs

Cloudflare, Akamai, and CloudFront cache static and dynamic content at edge locations close to users.

05

Key terms

Hit / miss
A hit finds data in the cache; a miss must fetch from the source.
Hit ratio
hits / (hits + misses). A higher ratio means fewer slow source calls.
TTL
Time-to-live: how long an entry stays valid before expiring.
Eviction
Removing entries when the cache is full, using a policy like LRU or LFU.
Invalidation
Removing or updating cached data when the source changes.
06

Cache-aside (the most common pattern)

  1. 1
    Check the cache

    The application looks up the key, for example user:42.

  2. 2
    Return on hit

    If present, return it immediately. No database call is made.

  3. 3
    Load on miss

    On a miss, query the database for the data.

  4. 4
    Populate the cache

    Store the result with a TTL so it expires even if invalidation fails.

  5. 5
    Invalidate on write

    When the data changes, write to the database first, then delete the cache key so the next read reloads fresh data.

07

Why the hit ratio matters

Cache latency 1 ms, database latency 50 ms, 10,000 requests per second.

Step 1 / 4
Hit ratioAverage latencyDB queries/secResult
0%50 ms10,000Database saturates
80%0.8 + 10 = 10.8 ms2,0005x less database load
95%0.95 + 2.5 = 3.45 ms50020x less database load
99%0.99 + 0.5 = 1.49 ms100100x less database load

NOWHit ratio: 0% | Average latency: 50 ms | DB queries/sec: 10,000 | Result: Database saturates

Average latency = hit% x cache latency + miss% x (cache + database latency). Going from 95% to 99% cuts database load by 5x, which is why tuning TTLs and key design matters.

08

Implementation

async function getUser(id: string): Promise<User> {  const key = `user:${id}`;   const cached = await redis.get(key);  if (cached) return JSON.parse(cached);          // hit   const user = await db.users.findById(id);       // miss  await redis.set(key, JSON.stringify(user), "EX", 300); // 5-minute TTL  return user;} async function updateUser(id: string, changes: Partial<User>) {  await db.users.update(id, changes);  // 1. source of truth first  await redis.del(`user:${id}`);       // 2. invalidate, do not overwrite}
09

Complexity and performance

L1 cache~1 ns

CPU cache reference.

RAM~100 ns

Main memory reference.

Redis (same zone)~0.5-1 ms

Mostly network round trip.

Database query~1-50 ms

Depends on indexes, load, and disk.

LRU get / setO(1)

Hash map plus doubly linked list.

10

Trade-offs

Freshness vs speed

Longer TTLs raise hit ratio but serve staler data. Choose TTL per data type: prices might need seconds, profile pictures can use hours.

Delete vs update on write

Deleting the key is safer: two concurrent writers updating the cache can leave the older value last. Deleting lets the next read load the current truth.

Local vs distributed

In-process caches are fastest but duplicate memory and diverge across servers. Redis or Memcached is shared and consistent across servers but adds a network hop.

Memory cost

Cache the hot working set, not everything. Measure the hit ratio before adding memory.

11

Variants and related techniques

Read-through

The cache library loads from the database on a miss, so application code only talks to the cache.

Write-through

Writes go to the cache and database together. Reads are always fresh; writes are slower.

Write-back (write-behind)

Writes go to the cache and are flushed to the database later. Very fast, but data can be lost if the cache fails.

Eviction policies

LRU evicts least recently used, LFU evicts least frequently used, and FIFO evicts oldest inserted. LRU is a strong default.

12

Common mistakes

  • Cache stampede: a hot key expires and thousands of requests hit the database at once.

    Fix: Use request coalescing or a lock per key, add TTL jitter, and refresh hot keys early.

  • Cache penetration: repeated requests for keys that do not exist.

    Fix: Cache negative results briefly or use a Bloom filter.

  • No TTL on entries.

    Fix: Always set a TTL as a safety net against missed invalidations.

  • Caching personalized data under a shared key.

    Fix: Include the user or tenant in the key and never cache authenticated responses at a public CDN.

13

Interview questions

How do you keep the cache consistent with the database?

Use cache-aside with write-then-delete, short TTLs as a backstop, and for stricter needs publish change events (CDC) that invalidate keys. Perfect consistency requires giving up some caching benefit.

What would you cache in a social feed?

Precomputed feed IDs per user, post objects by ID, and counts. Keep each separately so a post edit invalidates one key rather than every feed.

How do you handle a very hot key?

Replicate it across cache nodes or keep a small in-process copy, and add request coalescing so one miss does not create a thundering herd.

14

Practice problems

ProblemDifficultyWhat it trains
LRU CacheMediumImplement O(1) get and put.
LFU CacheHardFrequency buckets.
Design a product catalog read pathMediumLayers: CDN, Redis, database.