Caching
In this page:
Cache-Control and Expires
Cache-Control: max-age=604800 tells the browser it can reuse a file for 7 days without asking the server again. The older Expires header does a similar job with an absolute date instead of a duration. Modern configs mostly use Cache-Control, often alongside Expires for compatibility with very old clients.
mod_expires
mod_expires generates these headers automatically by file type, rather than hand-writing a Header rule for every extension. ExpiresByType image/jpeg "access plus 1 month" tells Apache to add caching headers to every JPEG response automatically, valid for a month from when it was accessed.
What Should (and Shouldn't) Be Cached Long-Term
Static assets that rarely change -- images, fonts, and especially versioned/hashed filenames like app.a3f9c1.js -- are safe to cache for a long time, since a new deploy simply produces a new filename. The main HTML document, and any API responses with data that changes, generally shouldn't be cached long, or at all, since a stale cached copy would show outdated content.
Validators: ETag and Last-Modified
Even after a cached copy expires, the browser doesn't necessarily have to re-download the whole file -- it can send a conditional request with the If-None-Match/If-Modified-Since headers, and Apache replies with a cheap 304 Not Modified if the file (identified by its ETag or modification timestamp) hasn't actually changed, saving the bandwidth of re-sending it.
Example: Caching static assets with mod_expires
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType text/css "access plus 1 week"
ExpiresByType application/javascript "access plus 1 week"
</IfModule>
{# Flagged by hand after confirming a runner can't handle this example
(a shell command / go.mod file stored as a TopicExample, a language
feature the configured runner version doesn't support, or output
that blows a runner's sandbox limit) -- see TopicExample.norun.
Never render the run button for these, regardless of language,
since it would just fail at execute_code (or worse, hang the
Judge0 queue on a submission that can never finish cleanly). #}
- Caching the main HTML page for a long time, so visitors keep seeing an old version of the site after it's updated.
- Setting a long cache lifetime on a non-versioned filename that does change, leaving visitors stuck with a stale file until the cache expires.
- Forgetting mod_expires needs to be enabled before ExpiresByType/ExpiresDefault directives have any effect.
Chapter Quiz — Complete all 4 topics to unlock
0/4 topics done
Complete these topics first: