// Backend — 2026-09-02 — 8 min
What Is Cache? The Mechanism That Stops an App From Doing the Same Work Twice
What is cache, how does it work, and how does it turn a 200 ms response into a 5 ms one? Layers, a real example, and the risks, explained.
Every time you open a SaaS dashboard's home page, the same database query might be running behind the scenes again — same user, same day, same result, but the server recomputes it from scratch every single time. The short answer to what is cache lives right there: compute the result of an operation once, set it aside, and when the same request comes in again, hand back the saved answer instead of recomputing it. It sounds simple, but it's usually the actual reason an app responds in 5 milliseconds instead of 200, or a server can handle ten times the traffic under the same load.
##What Is Cache, and What Does It Actually Do?
Every cache system runs the same three steps: first it checks 'do I already have this answer' (a cache hit), and if so returns it directly; if not (a cache miss) it does the real work — queries the database, calls an API, runs an expensive computation — returns the result to the user, and also stores it for next time, usually as a key-value pair. The key is usually 'whatever makes this request unique': a product ID, a user ID, a URL. A cache entry stored under the key 'product-482' on an e-commerce site means a thousand different visitors hitting that product page trigger the database once, not a thousand times; the remaining 999 requests get served straight from memory, from cache. There's a metric for tracking this too: cache hit ratio, the percentage of requests served from cache. On a well-tuned system this usually sits above 80%; if it's lower, either the TTL is set too short, or you're caching data that's rarely actually repeated.
##The Layers Where Cache Actually Runs
Cache isn't one single place; it kicks in separately at almost every layer of an application, and in a real system several of these usually run together at once:
- Browser cache: once your browser downloads an image, a CSS or JS file, it keeps it on disk and won't re-download it on your next visit to the same site.
- CDN (content delivery network) cache: keeps static files stored ahead of time on a server geographically close to the user — Cloudflare and Fastly do exactly this.
- Application-layer cache: tools like Redis or Memcached keep expensive-to-compute results (an API response, a prepared report) in memory.
- Database query cache: the database itself briefly stores the result of the same SQL query.
- OS / disk cache: frequently read files get served straight from RAM instead of disk.
Which layer gets used depends on how often the data changes and who's going to see it. Browser cache handles static files, CDN handles images, Redis handles dynamic-but-frequently-requested data — in a real production system these layers usually run together, complementing each other.
##A Real Example: A Product Page, Before and After Cache
Picture a mid-size e-commerce site: 50,000 product page views a day, and on every single view the server hits the database separately for product info, stock status, price, and related products — 4-5 queries, averaging 180-250 milliseconds. During peak hours the database CPU climbs above 80%, and page load visibly slows down. The fix isn't complicated: product data changes a few times a day, not a few times a minute (aside from stock and price updates), so hitting the database on every single request buys nothing. You write the product's entire page data into Redis under a key like 'product-482', with a 5-minute time-to-live (TTL). The first request still hits the database and writes the result into Redis; every request for the next 5 minutes gets served straight from Redis instead, in 3-8 milliseconds. The result: database load drops sharply under the same traffic, page load time visibly shortens, and the database doesn't buckle even during the busiest campaign days. For anything that needs to be truly live, like stock count, the usual fix is to keep that piece out of the cached response and fetch it from a separate, uncached endpoint — or clear the relevant cache entry the moment stock changes.
##Cache Invalidation: The Actually Hard Part
There's an old line in computer science: 'There are two hard things: cache invalidation and naming things.' It sounds like a joke, but it points at a real problem — filling a cache is easy, knowing exactly when to clear it once the underlying data goes stale is hard. Four common strategies:
- TTL (time-to-live): automatically expire the data after a set period. Simple to set up, but risks showing stale data during that window.
- Event-based invalidation: clear the specific cache key the moment the source data changes (say, a price update). More accurate, but requires extra code on every write.
- Write-through cache: the cache gets updated at the same moment the data is written to the database, so there's never a stale moment — at the cost of a slightly slower write.
- Stale-while-revalidate: show the stale value immediately, fetch the fresh value in the background, and update the cache for the next request — the user never waits.
In practice, the scenario that causes the most headaches is this: set the TTL too long and a user might see an outdated price or an out-of-stock item that's actually back in stock — a real trust problem. Set it too short and you erase most of the benefit cache was supposed to give you, and the database ends up working constantly again. The right duration depends entirely on the data: hours are fine for a blog post, but even seconds can be too long for a live stock counter. Combining event-based invalidation with a TTL as an upper bound — clear it immediately on change, but also expire it as a safety net — is usually the most balanced approach on real projects.
##When Is Cache Risky or Unnecessary?
Cache isn't a good idea everywhere. Caching a bank balance, a payment status, or personal, frequently-changing data is risky — the user might see a wrong or outdated number, and that's a serious trust problem. When the same query is almost never repeated (a one-off report that's different for every user), adding cache buys nothing and only adds complexity and maintenance overhead. And in a small app that hasn't actually hit a real performance problem yet, building a cache layer up front is a classic case of premature optimization — measure the actual bottleneck first (which query, which endpoint is slow), and put cache exactly there. Sprinkling Redis everywhere doesn't improve performance, it just adds code complexity.
##Cache Stampede: When Thousands of Requests Hit the Database at Once
Cache creates its own interesting problem: cache stampede (also called the 'thundering herd'). The moment a heavily-requested cache key's TTL expires, every one of the hundred or thousand requests arriving that same second gets a 'not in cache' answer and all of them hit the database with the same query at once — dumping onto the database, in a single instant, the load that would normally be spread across many separate requests. On a high-traffic system, this can trigger exactly the database meltdown cache was supposed to prevent. The common fix is a 'lock' or 'single-flight' pattern: let the first request go to the database, and make every other request for that same key wait for the first one's result instead of hitting the database again themselves. Another approach is adding a small random offset to the TTL (jitter), so thousands of keys don't all expire in the same millisecond but spread out instead.
Typical response time on a cache hit
5-20 ms
Response time on a cache miss (hits the database)
100-300 ms
Database load reduction on well-cached endpoints
roughly 50-90%
##FAQ
>Should I use Redis or Memcached?
For most new projects, Redis is the more sensible choice: beyond plain key-value storage it offers data structures like lists, sets, and counters, and it can optionally persist to disk (Memcached is purely in-memory — a restart wipes everything). Memcached's advantage is being simpler and slightly lighter under a very high, pure key-value load — but in practice most projects never actually feel that difference. If you're building a new system, starting with Redis buys you flexibility you'll likely need later anyway.
>How long should the cache TTL be?
There's no fixed rule — it depends entirely on the data. A reasonable starting point: hours to days for rarely-changing data (a category list, static page content); minutes for moderately-changing data (a product price, a stock summary); seconds or no caching at all for frequently-changing data (a live counter, a notification list). Even if you get it wrong at first, there's a fix: keep the TTL short and add event-based invalidation on top — usually the safest middle ground.
>Does caching actually reduce server costs?
Usually yes, but not automatically. A cache used in the right place lets you keep your database server smaller, or delays the need to scale it up — a Redis instance is generally far cheaper than a scaled-up database. But the cache itself is a resource too: it needs memory, operating cost, and maintenance of its invalidation logic. Adding cache to a low-traffic system whose queries are already fast doesn't reduce cost — it just adds an unnecessary component.
>Does cache always make an app faster?
No — set up wrong, it can do the opposite. Checking, writing to, and invalidating a cache is itself work; adding cache to a query that's already simple and fast can add more overhead (network round-trips, invalidation logic) than benefit. Cache actually pays off when the same result gets produced repeatedly by something genuinely expensive to compute — caching a basic addition is pointless, but caching a report query that joins five tables is a real win.
Used in the right place, cache can meaningfully change both an app's speed and its server bill — but set up wrong, it quietly serves stale data instead. Rather than adding cache before understanding what's actually slow and how often the underlying data changes, it's always healthier to measure the real bottleneck first. If you want to talk through a similar performance problem, feel free to reach out via /contact.
// LET'S WORK
Planning a similar SaaS product?
We can define scope, MVP milestones, and a realistic delivery timeline together.
> CONTACT