Skip to main content

Browser Caching Explained: From DNS to Disk and Everything Between

A practical look at browser caching: how DNS, memory, and disk caches work, and why strong and negotiated caching are the frontend developer's best friends.

The Cache Ladder: How a Browser Really Loads a Page

When you type a URL and hit Enter, your browser doesn't just waltz over to the server and fetch the page. It goes through a series of checks, each one a potential shortcut. Most developers know that caching is good for performance, but the devil is in the details. Let's walk through the actual steps a browser takes, from the moment you press Enter to the final render.

First, the browser needs an IP address. That means DNS resolution. Then it checks its own memory cache. Then it looks at HTTP caches—both strong and negotiated. And finally, if all else fails, it goes to the server. Each of these layers can save you bandwidth, time, and a whole lot of user frustration.

DNS Caching: The First Shortcut

DNS resolution is like looking up a phone number before making a call. It takes time, and browsers hate wasting time. So after the first resolution, the IP address is stored locally. Next time you hit the same domain, the browser checks its own DNS cache first. If that's empty, it looks at your operating system's hosts file. Then it moves to your local DNS server, and eventually up to root servers if needed.

This is the kind of caching that happens automatically, without any input from you. But it's the first line of defense against slow loads. If your DNS cache is warm, you skip a whole round trip.

Memory Cache: The Short-Lived Speedster

Memory cache is a browser's internal trick. It's completely out of your control—no HTTP headers, no developer settings. When a resource is fetched, the browser might stuff it into memory. If the same resource is requested again on the same page, it's served straight from RAM, no network call needed.

But memory is precious, and it's not meant for long-term storage. Close the tab, and the cache is gone. Reopen the page, and you're back to square one. It's also limited by size—if you load too many assets, the browser will evict older entries even if the page is still open. This cache is a no-brainer for avoiding duplicate requests, like two identical images on one page.

Disk Cache: Where the Real Control Lies

Disk cache is the heavyweight champion. It's governed by HTTP response headers, and it's the one cache you can actually influence. This is where strong caching and negotiated caching come into play.

Let's say a server wants you to cache a resource for an hour. It sends back a response with Cache-Control: max-age=3600 and an Expires header for good measure. The browser stores the resource on disk, notes the request method and URL, and records the server's response time. That timestamp is crucial because it's the basis for deciding whether the cache is still fresh.

Strong Cache: The 'No Questions Asked' Cache

With strong caching, the browser doesn't even bother talking to the server. It just checks if the current time is before the calculated expiration time (max-age + Date). If it is, boom—you get the cached copy instantly. No network request, no latency.

You might see both Cache-Control and Expires in the wild. That's because Expires is from HTTP/1.0, and Cache-Control is from HTTP/1.1. Setting both ensures compatibility across older and newer servers.

Negotiated Cache: When You Ask Permission

But what happens when the cache expires? The browser doesn't just throw it away. Instead, it asks the server, "Hey, I've got this old copy. Is it still good?" It sends a conditional request with headers like If-Modified-Since and If-None-Match.

The server checks those values. If the resource hasn't changed, it responds with a 304 status and no body. The browser then knows it can keep using its cached copy. If the resource has changed, the server sends a fresh 200 response with the new content, and the browser updates its cache.

Why send both headers? Because some servers only understand one. If-None-Match (based on ETag) is generally more reliable, but If-Modified-Since (based on Last-Modified) is a good fallback. Sending both covers your bases.

Cache-Control Directives: The Fine Print

The Cache-Control header is more than just max-age. It can include several directives, each with a specific meaning:

  • public: The resource is public, so any cache can store it. This is fine for static assets that look the same for everyone.
  • private: The resource is user-specific. Browsers can cache it, but intermediate caches (like CDNs) shouldn't. Think of a personalized dashboard.
  • no-cache: The browser can cache the resource, but it must revalidate with the server before using it. It's not a ban on caching—it's a "check first" policy.
  • no-store: Absolutely no caching. The browser must fetch from the server every single time. Use this for sensitive data like bank account details.
  • max-age: How long the resource is fresh, in seconds.

You can combine them, like Cache-Control: public, max-age=3600. And note that Cache-Control can also appear in request headers. When a client sends Cache-Control: no-cache, it's telling the server, "Ignore any caches and give me the real deal." This is the modern equivalent of the HTTP/1.0 Pragma: no-cache header.

Putting It All Together

So what happens when you revisit a page you've loaded before? Here's the decision tree:

  1. Check if the resource is in the disk cache and still fresh (strong cache). If yes, use it.
  2. If not, send a conditional request to the server (negotiated cache).
  3. If the server says 304, use the cached copy.
  4. If the server says 200, fetch the new resource and update the cache.

It's a system designed to minimize network traffic while keeping content fresh. And it works—most of the time. But you have to set the headers right. Too aggressive, and users see stale content. Too lenient, and you waste bandwidth.

In practice, start with strong caching for static assets like images, CSS, and JS files, with a reasonable max-age. For HTML pages, you might want no-cache to ensure users get the latest version. And for anything sensitive, no-store is your friend.

Browser caching isn't just a performance checkbox—it's a core part of frontend optimization. Understanding how DNS, memory, and disk caches work gives you the power to make your site faster without buying more servers. And that's a win for everyone.

Share this article:

Comments (0)

No comments yet. Be the first to comment!