See all Lighttpd related FAQ
I would like to use the Cache-Control header field to specify directives that MUST be obeyed by all caching mechanisms such as a proxy server and browsers. This will help to reduce latency and network traffic for my static assets served by lighttpd web-server. How do I set Cache-Control: public, max-age=SEC using Lighttpd web-server under Unix like operating systems?

You can use lighttpd web-server to send the following and many other types of caching control headers:
Tutorial details
Difficulty level Intermediate
Root privileges Yes
Requirements Lighttpd
Est. reading time 3 minutes
public : Force caching for all static assets even if it would normally be non-cacheable.

max-age=number-of-seconds : Specifies the maximum amount of time that a representation will be considered fresh.

must-revalidate : Force the cache to obey any freshness information you give them about an object.

proxy-revalidate : Same as must-revalidate, except that it only applies to proxy caches.

All of the above directives affects the following web caches:

  1. Your web browser such as Firefox and others.
  2. Gateway and CDN networks such as Cloudfront, Akamai and others.
  3. Proxy server and reverse proxy servers such as squid, nginx, and others.

Example: mod_expire and mod_setenv

The mod_expire to set the Expire and Cache-Control: max-age headers in the Response Header of HTTP/1.0 and HTTP/1.1 messages under Lighttpd web server. The mod_setenv module allows influencing the environment external applications are spawned in and the response headers the server sends to the clients.
Edit lighttpd.conf file, enter:
# vi lighttpd.conf
Activate the mod_expire and mod_setenv:

server.modules              = (
WARNING! It is known that mod_expire may not work due to an incorrect order of loading of modules. You must load mod_expier before mod_fastcgi. It is safe to load mod_expire BEFORE all other modules.

For example, make all images stored in /images/ expire 1 month after being accessed, by default:

expire.url = ( "/images/" => "access plus 1 month" )

The syntax is as follows:

<access|modification> plus <number> <years|months|days|hours|minutes|seconds>

To make all images stored on sub-domain expire 1000 days after being accessed, by default:

$HTTP["url"] =~ "^/" {
    expire.url = ( "" => "access 1000 days" )

To add a public header to the HTTP request, enter:

setenv.add-response-header += (
    "Cache-Control" => "public"

To add both public and must-revalidate to the HTTP request, enter:

setenv.add-response-header += (
    "Cache-Control" => "public, must-revalidate"

Working example from my setup

### config for static assets by nixCraft for ###
$HTTP["host"]  == ""{
  server.document-root = "/var/www/static-files"
  accesslog.filename   = "/var/log/lighttpd/"
  $HTTP["url"] =~ "^/" {
         expire.url = ( "" => "access 5000 days" )
  setenv.add-response-header += (
        "Cache-Control" => "public, must-revalidate, proxy-revalidate"

Save and close the file. Reload or restart the lighttpd web server:
# service lighttpd restart
# service lighttpd reload

How do I see and test HTTP headers?

The syntax is:

curl -I
curl -I

In this example, examines HTTP resources for the url called to find out how they will interact with Web caches:

curl -I

Sample outputs:

HTTP/1.0 200 OK
Content-Type: image/png
Content-Length: 8852
Connection: keep-alive
Server: nginx
Date: Fri, 09 Nov 2012 10:06:32 GMT
X-Whom: l3-com-cyber
Cache-Control: public, must-revalidate, proxy-revalidate, max-age=432000000
Expires: Sun, 19 Jul 2026 10:06:32 GMT
Accept-Ranges: bytes
ETag: "732144214"
Last-Modified: Wed, 14 Jan 2009 18:47:39 GMT
Age: 15
X-Cache: Hit from cloudfront

#1: Understanding the Date: Fri, 09 Nov 2012 10:06:32 GMT http web cache headers

  1. The date send by server i.e. server’s clock.
  2. The clock is used to calculate freshness of the recourses.

#2: Understanding the Last-Modified: Wed, 14 Jan 2009 18:47:39 GMT http web cache header

  1. The resource last changed almost 3.5+ years ago.

#3: Understanding the Cache-Control: public, must-revalidate, proxy-revalidate, max-age=432000000 http web cache header

  1. This server allows all caches to store this image file (public).
  2. This image file is fresh until 13.5+ years days from now (max-age=432000000).
  3. This image file cannot be served by a cache once it becomes stale (must-revalidate, proxy-revalidate).

#4: Understanding the Age: 15 http web cache header

  1. This image file has been cached for 15 seconds.

🥺 Was this helpful? Please add a comment to show your appreciation or feedback.

nixCrat Tux Pixel Penguin
Hi! 🤠
I'm Vivek Gite, and I write about Linux, macOS, Unix, IT, programming, infosec, and open source. Subscribe to my RSS feed or email newsletter for updates.

0 comments… add one

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre> for code samples. Your comment will appear only after approval by the site admin.