Understanding Caching

The magic between your API and database.

Dev Adnani
November 12, 2025
6 min read
System-DesignScalabilitySoftware-Architecture

TL;DR

Caching isn’t about saving memory — it’s about saving time.

Every millisecond you shave off a request matters.

A well-implemented cache can turn a slow system into a real-time one, cut your database load by 90%, and make your users think your backend is magic.

But caching isn’t “just use Redis.” There are strategies, trade-offs, and gotchas you must understand — or you’ll end up caching bugs instead of data.

Let’s break it down. ⚡


The Core Idea

A cache is a temporary storage layer that keeps data that’s expensive to compute or fetch.

Expensive can mean:

  • a network call (to your DB or API)
  • a disk I/O
  • or a heavy computation (like aggregations)

Instead of doing the same work repeatedly, you store the result once and reuse it — until it becomes stale.

The idea is simple:

“Avoid doing the same expensive work twice.”

In real-world systems, caching sits between your API and your database, intercepting read and write calls.

User → API → Cache → Database


The Types of Caching 🧩

1. Lazy Caching (On-Demand / Cache-Aside)

When a request comes in:

  1. Check if the data exists in the cache.
  2. If yes, return it directly.
  3. If no, fetch from the database (expensive), store it in cache, and return it.
  4. Set an expiry (TTL) so the data doesn’t get stale forever.

Example:

Fetching product details in an e-commerce site.

The first user triggers a DB query → result is cached in Redis.

The next 10,000 users? Instant response from cache.

Pros: Simple and efficient.

Cons: The first request (cache miss) is always slow.


2. Eager Caching (Write-Through / Proactive)

Here, the cache is always kept up-to-date.

  1. Every time data changes, write to both DB and cache in the same request.
  2. Sometimes, you preload data you know users will need soon.

Examples:

  • Updating live cricket scores — data goes to DB and cache simultaneously.
  • When a celebrity posts, their followers’ feeds are pre-cached.
  • YouTube’s “Recommended” videos are cached before you even open the app.

Pros: Always fresh, ultra-low read latency.

Cons: Slower writes and potential over-caching.


3. Write-Behind Caching (Write-Back)

Here, data is written only to cache, and the cache syncs with DB later (asynchronously).

It’s great for metrics or logs where 100% consistency isn’t critical.

Example:

Incrementing view counters or likes on a post — Redis handles increments, and periodically flushes them to the DB.

Pros: Fast writes.

Cons: Risk of data loss if cache crashes before syncing.


4. Read-Through Caching

In this pattern, your application never talks to the DB directly — only the cache.

If data isn’t found in cache, the cache itself fetches from DB, updates itself, and returns the result.

Example:

A stock-trading app where real-time stock prices are fetched via cache.

If a stock’s price isn’t in cache, Redis automatically pulls it from the DB and stores it for future lookups.

Pros: Simplifies your app code.

Cons: Slightly more complex cache setup (used in managed systems like AWS ElastiCache).


5. Refresh-Ahead Caching

The cache refreshes hot data before it expires, based on access frequency or prediction.

Example:

A news app preloads tomorrow’s trending headlines or upcoming match results before users open the app.

So, when the day changes — the data is already warm in cache.

Pros: Zero cache misses for popular data.

Cons: Can waste resources on unnecessary refreshes.


Cache Invalidation — The Hardest Part 😅

Caching is easy to start, but hard to manage long-term.

The golden question:

“When should I invalidate the cache?”

Three universal truths:

  1. Cached data must eventually expire (TTL).
  2. Invalidate when the underlying data changes.
  3. Always design for fallback (if cache fails, DB should still work).

The Shortcut (From Experience)

RequirementCaching PatternExample
Expensive read operationsLazy cachingProduct details, blog fetch
Write-heavy systemsWrite-behindAnalytics, counters
High consistency needsEager cachingLive scores, stock prices
Predictable data accessRefresh-aheadTrending videos, news headlines
Full abstraction layerRead-throughStock prices, API-backed content

Final Thoughts 💭

Caching is one of those things that sounds simple — until it isn’t.

Get it right, and your system feels instant.

Get it wrong, and you’ll spend nights debugging inconsistent states.

Remember:

  • Cache what matters — not everything.
  • Always have a TTL and fallback.
  • Choose your caching pattern based on access frequency, data volatility, and consistency needs.

And yes — you can (and should) mix them:

  • Redis for fast reads,
  • Postgres for durability,
  • CDN edge cache for global performance.

Because in the end…

Great engineers don’t avoid caching —

they architect it consciously.

Dev Adnani

Full Stack Engineer