Service worker caching and HTTP caching

The pros and cons of using consistent or different expiry logic across the service worker cache and HTTP cache layers.

While service workers and PWAs are becoming standards of modern web applications, resource caching has become more complex than ever. This article covers the big picture of browser caching, including:

  • The use cases of and differences between service worker caching and HTTP caching.
  • The pros and cons of different service worker caching expiry strategies compared to regular HTTP caching strategies.

Overview of caching flow

At a high-level, a browser follows the caching order below when it requests a resource:

  1. Service worker cache: The service worker checks if the resource is in its cache and decides whether to return the resource itself based on its programmed caching strategies. Note that this does not happen automatically. You need to create a fetch event handler in your service worker and intercept network requests so that the requests are served from the service worker's cache rather than the network.
  2. HTTP cache (also known as the browser cache): If the resource is found in the HTTP Cache and has not yet expired, the browser automatically uses the resource from the HTTP cache.
  3. Server-side: If nothing is found in the service worker cache or the HTTP cache, the browser goes to the network to request the resource. If the resource isn't cached in a CDN, the request must go all the way back to the origin server.

Caching flow

Caching layers

Service worker caching

A service worker intercepts network-type HTTP requests and uses a caching strategy to determine what resources should be returned to the browser. The service worker cache and the HTTP cache serve the same general purpose, but the service worker cache offers more caching capabilities, such as fine-grained control over exactly what is cached and how caching is done.

Controlling the service worker cache

A service worker intercepts HTTP requests with event listeners (usually the fetch event). This code snippet demonstrates the logic of a Cache-First caching strategy.

A diagram showing how service workers intercept HTTP requests

It's highly recommended to use Workbox to avoid reinventing the wheel. For example, you can register resource URL paths with a single line of regex code.

import {registerRoute} from 'workbox-routing';

registerRoute(new RegExp('styles/.*\\.css'), callbackHandler);

Service worker caching strategies and use cases

The next table outlines common service worker caching strategies and when each strategy is useful.

Strategies Freshness rationale Use cases
Network only The content has to be up-to-date at all times.
  • Payments and checkouts
  • Balance statements
Network falling back to cache It's preferable to serve the fresh content. However if the network fails or is unstable, it's acceptable to serve slightly old content.
  • Timely data
  • Prices and rates (requires disclaimers)
  • Order statuses
Stale-while-revalidate It's okay to serve cached content right away, but updated cached content should be used in the future.
  • News feeds
  • Product listing pages
  • Messages
Cache first, fall back to network The content is non-critical and can be served from the cache for performance gains, but the service worker should occasionally check for updates.
  • App shells
  • Common resources
Cache only The content rarely changes.
  • Static content

Additional benefits of service worker caching

In addition to fine-grained control of caching logic, service worker caching also provides:

  • More memory and storage space for your origin: The browser allocates HTTP cache resources on a per-origin basis. In other words, if you have multiple subdomains, they all share the same HTTP cache. There is no guarantee that the content of your origin/domain stays in the HTTP cache for a long time. For example, a user may purge the cache by manually cleaning up from a browser's settings UI, or triggering a hard-reload on a page. With a service worker cache you have a much higher likelihood that your cached content stays cached. See Persistent storage to learn more.
  • Higher flexibility with flaky networks or offline experiences: With the HTTP cache you only have a binary choice: either the resource is cached, or not. With service worker caching you can mitigate little "hiccups" much easier (with the "stale-while-revalidate" strategy), offer a complete offline experience (with the "Cache only" strategy) or even something in between, like customized UIs with parts of the page coming from the service worker cache and some parts excluded (with the "Set catch handler" strategy) where appropriate.

HTTP caching

The first time a browser loads a web page and related resources, it stores these resources in its HTTP cache. The HTTP cache is usually enabled automatically by browsers, unless it has been explicitly disabled by the end user.

Using HTTP caching means relying on the server to determine when to cache a resource and for how long.

Control HTTP cache expiry with HTTP response headers

When a server responds to a browser request for a resource, the server uses HTTP response headers to tell a browser how long it should cache the resource. See Response headers: configure your web server to learn more.

HTTP caching strategies and use cases

HTTP caching is much simpler than service worker caching, because HTTP caching only deals with time-based (TTL) resource expiration logic. See Which response header values should you use? and Summary to learn more about HTTP caching strategies.

Designing your cache expiry logic

This section explains the pros and cons of using consistent expiry logic across the service worker cache and HTTP cache layers, as well as the pros and cons of separate expiry logic across these layers.

The Glitch below demonstrates how service worker caching and HTTP caching work in action across different scenarios:

Consistent expiry logic for all cache layers

To demonstrate the pros and cons, we'll look at 3 scenarios: long-term, medium-term, and short-term.

Scenarios Long-term caching Medium-term caching Short-term caching
Service worker caching strategy Cache, falling back to network Stale-while-revalidate Network falling back to cache
Service worker cache TTL 30 days 1 day 10 mins
HTTP cache max-age 30 days 1 day 10 mins

Scenario: Long-term caching (Cache, falling back to network)

  • When a cached resource is valid (<= 30 days): The service worker returns the cached resource immediately without going to the network.
  • When a cached resource is expired (> 30 days): The service worker goes to the network to fetch the resource. The browser doesn't have a copy of the resource in its HTTP cache, so it goes server-side for the resource.

Con: In this scenario, HTTP caching provides less value because the browser will always pass the request to the server-side when the cache expires in the service worker.

Scenario: Medium-term caching (Stale-while-revalidate)

  • When a cached resource is valid (<= 1 day): The service worker returns the cached resource immediately, and goes to the network to fetch the resource. The browser has a copy of the resource in its HTTP cache, so it returns that copy to the service worker.
  • When a cached resource is expired (> 1 day): The service worker returns the cached resource immediately, and goes to the network to fetch the resource. The browser doesn't have a copy of the resource in its HTTP cache, so it goes server-side to fetch the resource.

Con: The service worker requires additional cache-busting to override the HTTP cache in order to make the most of the "revalidate" step.

Scenario: Short-term caching (Network falling back to cache)

  • When a cached resource is valid (<= 10 mins): The service worker goes to the network to fetch the resource. The browser has a copy of the resource in its HTTP cache so it returns that to the service worker without going server-side.
  • When a cached resource is expired (> 10 mins): The service worker returns the cached resource immediately, and goes to the network to fetch the resource. The browser doesn't have a copy of the resource in its HTTP cache, so it goes server-side to fetch the resource.

Con: Similar to the medium-term caching scenario, the service worker requires additional cache-busting logic to override the HTTP cache in order to fetch the latest resource from the server-side.

Service worker in all scenarios

In all scenarios, the service worker cache can still return cached resources when the network is unstable. On the other hand, the HTTP cache is not reliable when the network is unstable or down.

Different cache expiry logic at the service worker cache and HTTP layers

To demonstrate the pros and cons, we'll again look at long-term, medium-term, and short-term scenarios.

Scenarios Long-term caching Medium-term caching Short-term caching
Service worker caching strategy Cache, falling back to network Stale-while-revalidate Network falling back to cache
Service worker cache TTL 90 days 30 days 1 day
HTTP cache max-age 30 days 1 day 10 mins

Scenario: Long-term caching (Cache, falling back to network)

  • When a cached resource is valid in the service worker cache (<= 90 days): The service worker returns the cached resource immediately.
  • When a cached resource is expired in the service worker cache (> 90 days): The service worker goes to the network to fetch the resource. The browser doesn't have a copy of the resource in its HTTP cache, so it goes server-side.

Pros and cons:

  • Pro: Users experience instant response as the service worker returns cached resources immediately.
  • Pro: The service worker has more fine-grained control of when to use its cache and when to request new versions of resources.
  • Con: A well-defined service worker caching strategy is required.

Scenario: Mid-term caching (Stale-while-revalidate)

  • When a cached resource is valid in the service worker cache (<= 30 days): The service worker returns the cached resource immediately.
  • When a cached resource is expired in the service worker cache (> 30 days): The service worker goes to the network for the resource. The browser doesn't have a copy of the resource in its HTTP cache, so it goes server-side.

Pros and cons:

  • Pro: Users experience instant response as the service worker returns cached resources immediately.
  • Pro: The service worker can ensure that the next request for a given URL uses a fresh response from the network, thanks to the revalidation that happens "in the background."
  • Con: A well-defined service worker caching strategy is required.

Scenario: Short-term caching (Network falling back to cache)

  • When a cached resource is valid in the service worker cache (<= 1 day): The service worker goes to the network for the resource. The browser returns the resource from the HTTP cache if it's there. If the network is down, the service worker returns the resource from the service worker cache
  • When a cached resource is expired in the service worker cache (> 1 day): The service worker goes to the network to fetch the resource. The browser fetches the resources over the network as the cached version in its HTTP cache is expired.

Pros and cons:

  • Pro: When the network is unstable or down, the service worker returns cached resources immediately.
  • Con: The service worker requires additional cache-busting to override the HTTP Cache and make "Network first" requests.

Conclusion

Given the complexity of the combination of caching scenarios, it's not possible to design one rule that covers all cases. However, based on the findings in the previous sections, there are a few suggestions to look at when designing your cache strategies:

  • Service worker caching logic doesn't need to be consistent with HTTP caching expiry logic. If possible, use longer expiry logic in the service worker to grant the service worker more control.
  • HTTP caching still plays an important role, but it's not reliable when the network is unstable or down.
  • Revisit your caching strategies for each resource to make sure your service worker caching strategy provides its value, without conflicting with the HTTP cache.

Learn more