Bird
Raised Fist0
Nginxdevops~5 mins

Cache-Control headers in Nginx - Commands & Configuration

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Web browsers and proxies can store copies of your website files to load pages faster. Cache-Control headers tell these browsers how long to keep these copies before asking for fresh ones. This helps your site load quickly while showing updated content when needed.
When you want browsers to keep images and stylesheets for a day to speed up page loading.
When you update your website often and want browsers to check for new content every time.
When you serve files that rarely change and want to reduce server load by letting browsers cache them longer.
When you want to prevent sensitive pages from being stored in browser cache for security reasons.
When you want to control how proxies cache your content between your server and users.
Config File - nginx.conf
nginx.conf
http {
    server {
        listen 80;
        server_name example.com;

        location /static/ {
            root /var/www/html;
            add_header Cache-Control "public, max-age=86400" always;
        }

        location /api/ {
            proxy_pass http://backend_server;
            add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0" always;
        }
    }
}

This configuration sets Cache-Control headers for two paths:

  • /static/ serves static files with caching allowed for 86400 seconds (1 day).
  • /api/ disables caching to ensure fresh data on every request.

The add_header directive adds the Cache-Control header to HTTP responses.

Commands
Check the nginx configuration file for syntax errors before applying changes.
Terminal
sudo nginx -t
Expected OutputExpected
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Reload nginx to apply the new Cache-Control header settings without stopping the server.
Terminal
sudo systemctl reload nginx
Expected OutputExpected
No output (command runs silently)
Check the HTTP headers for a static file to verify the Cache-Control header is set correctly.
Terminal
curl -I http://example.com/static/image.png
Expected OutputExpected
HTTP/1.1 200 OK Server: nginx Content-Type: image/png Cache-Control: public, max-age=86400
-I - Fetch only HTTP headers without the body
Check the HTTP headers for an API response to verify caching is disabled.
Terminal
curl -I http://example.com/api/data
Expected OutputExpected
HTTP/1.1 200 OK Server: nginx Content-Type: application/json Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0
-I - Fetch only HTTP headers without the body
Key Concept

If you remember nothing else from Cache-Control headers, remember: they tell browsers and proxies how long to keep copies of your files to balance speed and freshness.

Common Mistakes
Forgetting to reload nginx after changing the configuration.
The new Cache-Control headers won't take effect until nginx reloads the config.
Always run 'sudo nginx -t' to test and then 'sudo systemctl reload nginx' to apply changes.
Setting Cache-Control headers globally without exceptions for dynamic content.
Dynamic pages might be cached and show outdated information to users.
Set different Cache-Control headers per location, disabling caching for dynamic API routes.
Using incorrect syntax in add_header directive.
Nginx will ignore invalid headers or fail to start if syntax is wrong.
Use quotes around the header value and verify with 'nginx -t' before reloading.
Summary
Use the add_header directive in nginx.conf to set Cache-Control headers per location.
Test configuration syntax with 'nginx -t' before reloading nginx to apply changes.
Verify headers with 'curl -I' to ensure caching behaves as expected.

Practice

(1/5)
1. What is the purpose of the Cache-Control header in nginx?
easy
A. To set the server's IP address
B. To configure SSL certificates
C. To tell browsers how to cache files
D. To define the server's hostname

Solution

  1. Step 1: Understand HTTP headers role

    HTTP headers communicate instructions between server and browser.
  2. Step 2: Identify Cache-Control header function

    Cache-Control tells browsers how and when to cache content.
  3. Final Answer:

    To tell browsers how to cache files -> Option C
  4. Quick Check:

    Cache-Control = caching instructions [OK]
Hint: Cache-Control controls browser caching behavior [OK]
Common Mistakes:
  • Confusing Cache-Control with server IP settings
  • Thinking Cache-Control manages SSL
  • Mixing Cache-Control with hostname configuration
2. Which is the correct nginx directive to add a Cache-Control header that caches content for 1 hour?
easy
A. add_header Cache-Control "max-age=3600";
B. cache_control add "max-age=3600";
C. set_header Cache-Control "max-age=3600";
D. header_add Cache-Control "max-age=3600";

Solution

  1. Step 1: Recall nginx syntax for headers

    nginx uses add_header directive to add HTTP headers.
  2. Step 2: Match correct syntax for Cache-Control

    The correct syntax is add_header Cache-Control "max-age=3600"; to set caching for 3600 seconds (1 hour).
  3. Final Answer:

    add_header Cache-Control "max-age=3600"; -> Option A
  4. Quick Check:

    add_header + Cache-Control + max-age=3600 = correct [OK]
Hint: Use add_header directive for Cache-Control in nginx [OK]
Common Mistakes:
  • Using incorrect directive names like set_header
  • Wrong order of words in directive
  • Missing quotes around header value
3. Given this nginx config snippet:
location /images/ {
  add_header Cache-Control "public, max-age=86400";
}
What will the Cache-Control header instruct browsers for requests to /images/logo.png?
medium
A. Do not cache the image
B. Cache the image for 1 day and allow shared caches
C. Cache the image only privately for 1 hour
D. Cache the image forever without expiration

Solution

  1. Step 1: Analyze Cache-Control directives

    "public" means cache is allowed by browsers and shared caches. "max-age=86400" means cache for 86400 seconds (1 day).
  2. Step 2: Apply to /images/logo.png request

    Requests to /images/ get this header, so browsers and proxies cache the image for 1 day.
  3. Final Answer:

    Cache the image for 1 day and allow shared caches -> Option B
  4. Quick Check:

    public + max-age=86400 = 1 day shared cache [OK]
Hint: "public" + max-age seconds means shared cache allowed [OK]
Common Mistakes:
  • Thinking "public" disables caching
  • Confusing max-age seconds with hours
  • Assuming private caching only
4. You added this line in nginx config:
add_header Cache-Control "max-age=3600";
But browsers still cache content longer than 1 hour. What is the likely problem?
medium
A. Cache-Control header is ignored by browsers
B. The max-age value is too low
C. You need to restart nginx for add_header to work
D. The add_header directive is inside a location block but response code is 304

Solution

  1. Step 1: Understand add_header behavior with response codes

    By default, nginx does not add headers with add_header on 304 Not Modified responses.
  2. Step 2: Identify why caching is longer

    If response is 304, Cache-Control header may be missing, causing browsers to use old cache rules.
  3. Final Answer:

    The add_header directive is inside a location block but response code is 304 -> Option D
  4. Quick Check:

    add_header skips 304 responses by default [OK]
Hint: add_header skips 304 responses unless configured [OK]
Common Mistakes:
  • Assuming max-age value controls server cache
  • Thinking browsers ignore Cache-Control
  • Believing nginx restart fixes header issues
5. You want to configure nginx to prevent caching of API JSON responses but allow caching of static CSS files for 7 days. Which configuration is correct?
hard
A. location /api/ { add_header Cache-Control "no-store, no-cache, must-revalidate"; } location /css/ { add_header Cache-Control "public, max-age=604800"; }
B. location /api/ { add_header Cache-Control "max-age=604800"; } location /css/ { add_header Cache-Control "no-cache"; }
C. location /api/ { add_header Cache-Control "public, max-age=0"; } location /css/ { add_header Cache-Control "private, max-age=604800"; }
D. location /api/ { add_header Cache-Control "max-age=0"; } location /css/ { add_header Cache-Control "no-store"; }

Solution

  1. Step 1: Prevent caching for API JSON responses

    Using "no-store, no-cache, must-revalidate" ensures browsers do not cache API responses.
  2. Step 2: Allow caching for CSS files for 7 days

    "public, max-age=604800" allows shared caches and browsers to cache CSS for 604800 seconds (7 days).
  3. Final Answer:

    location /api/ { add_header Cache-Control "no-store, no-cache, must-revalidate"; } location /css/ { add_header Cache-Control "public, max-age=604800"; } -> Option A
  4. Quick Check:

    no-cache API + public 7-day CSS = correct config [OK]
Hint: Use no-cache for API, public max-age for static files [OK]
Common Mistakes:
  • Mixing cache directives for API and static files
  • Using private instead of public for CSS caching
  • Setting max-age=0 for static files incorrectly