Lighttpd: Set Cache-Control: public, max-age Headers For Caching Purpose

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 Intermediate (rss)
Root privileges Yes
Requirements Lighttpd
Time N/A
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.
🐧 If you liked this page, please support my work on Patreon or with a donation.
🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
0 comments… add one

Leave a Reply

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

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.