The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Enable browser caching in Nginx by returning cache headers from the location that serves each resource. Use a long-lived, immutable policy only for fingerprinted files whose URLs change when their bytes change; use no-cache with validators for HTML and other responses that can change at the same URL.
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
What browser caching on Nginx actually does
A browser decides whether it may reuse a response from its local cache by reading HTTP response headers. Nginx does not “turn on” a separate browser-cache switch. Instead, the Nginx location serving a file sends Cache-Control and, where applicable, Expires, ETag, or Last-Modified.
As an Amazon Associate I earn from qualifying purchases.
The Nginx ngx_http_headers_module provides the expires directive for generated expiration policy and add_header for explicit or arbitrary response fields. Both directives can be used in http, server, and location contexts; add_header is also valid in an if block inside a location. Put a rule as close as possible to the files it governs so unrelated responses do not receive the wrong policy.
Browser caching and Nginx proxy caching are different features. Browser caching controls what a user agent stores after receiving a response. Proxy caching stores upstream responses on the Nginx server and requires directives such as proxy_cache_path, proxy_cache, and proxy_cache_valid. Configuring one does not configure the other.
#1 Best Overall
Choose a policy before writing the configuration
The right lifetime depends on whether the URL identifies one immutable version of a file or may continue to point to changing content. A one-year lifetime is safe for a URL that changes whenever the bytes change; it is risky for a stable URL such as /index.html.
| Resource | Recommended policy | Why |
|---|---|---|
| Fingerprint-based CSS, JavaScript, images, and fonts | public, max-age=31536000, immutable |
The filename contains a content hash or version, so a deployment publishes a new URL when the bytes change. The old URL can remain cached. |
| Unversioned CSS or JavaScript | Short max-age or no-cache |
The same URL can begin serving new bytes, so a browser must not retain an old representation for a year. |
| HTML entry documents | no-cache with ETag and/or Last-Modified |
The browser may store the document but must validate it before reuse, allowing a 304 Not Modified response when unchanged. |
| Personalized or sensitive responses | An application-appropriate private or no-store policy |
Do not mark user-specific data as public merely to save bandwidth; shared caches could expose another user’s response. |
no-cache does not mean “never store.” It means that a stored response must be revalidated before it is reused. no-store is the directive intended when a response should not be stored.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Prepare Nginx and identify the correct location
Confirm which block serves the file
Nginx maps a request URI to a file using the root directive and the matching location block. A cache rule in the wrong block has no effect on the response you are inspecting. Start with the virtual host that serves the site and its document root, then identify whether assets are served by a prefix such as /assets/, a file-extension expression, or a more specific nested location.
Use the most specific applicable rule
Keep policies separated by resource type. A broad rule at server level can accidentally cache HTML, login responses, or API output. A dedicated location for hashed assets and another for documents makes the intended behavior visible and easier to test.
Understand inheritance before adding headers
Nginx header inheritance is not additive in every situation. A nested location containing its own add_header can stop inheriting add_header directives from a higher level. Review the complete effective configuration instead of assuming a new header is simply appended to the parent policy.
Apply a practical baseline configuration
The following server block keeps entry documents revalidatable and gives long-lived caching to static files only when their names contain a content hash or another version identifier. Replace the root path and host-specific details with your own values.
Rank #2
- Used Book in Good Condition
server {
root /var/www/example;
# Documents can change at the same URL.
location ~* .html$ {
expires -1;
add_header Cache-Control "no-cache";
}
# Use this only for versioned or fingerprinted filenames.
location ~* .(css|js|png|jpg|jpeg|gif|svg|webp|woff2?)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
expires 1y produces a positive max-age and a future Expires value. expires -1 produces a Cache-Control: no-cache policy. Nginx also supports the special values epoch, max, and off. Inspect the resulting headers rather than assuming the directive’s source spelling is what the browser receives.
The one-year example corresponds to 31,536,000 seconds. It is a configuration example, not a measured performance guarantee or a universal requirement. Choose a shorter lifetime when your deployment process cannot reliably change URLs as bytes change.
Use fingerprinted assets with long-lived caching
Make the URL the version identifier
A fingerprinted filename might look like app.abc123.js or styles.v42.css. Your build or release process must emit a new name whenever the content changes and update every HTML reference to that name. Once that invariant is reliable, a browser can safely reuse the old URL for its entire freshness lifetime.
Add immutable deliberately
immutable tells a cache that a fresh response will not change, avoiding unnecessary validation requests while it remains fresh. It is appropriate for a URL whose bytes are never replaced. Do not add it to index.html, an unversioned bundle, or any endpoint that can change while retaining its URL.
Free tools Windows power users keep installed
One-click scans. No signup required.
Do not hide deployment mistakes with a long TTL
If users report an old script after a release, first check whether the HTML still references the old fingerprint. Purging a browser cache is not a deployment strategy. Correct URL versioning lets old documents finish naturally while new documents point to new assets.
Keep HTML and changing resources revalidatable
HTML entry points
For an entry document that remains at the same URL, use Cache-Control: no-cache. The browser may keep the body locally, but it asks Nginx whether the representation changed before displaying it from cache. This avoids retransmitting an unchanged document while allowing a deployment to take effect promptly.
Rank #3
- Used Book in Good Condition
Unversioned assets
If a stylesheet or script is overwritten in place, use a short freshness period or no-cache. A long max-age would allow a browser to use stale bytes without contacting the server until the lifetime expires.
APIs and personalized responses
Do not apply a public static-asset rule to API responses, account pages, or other user-specific output. Decide whether the response may be shared, only stored in a private browser cache, or not stored at all. The application’s privacy requirements determine whether private, no-store, or a more specific combination is appropriate.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Choose between expires and explicit Cache-Control
When expires is convenient
expires calculates an expiration date and emits both an Expires field and a corresponding cache-control policy. Relative values such as 1y are concise when one consistent lifetime is desired, and negative values provide a simple revalidation policy.
When add_header is clearer
Use add_header when you want to state the exact policy, combine directives, or set a field that Nginx cannot derive from a duration. For example:
location /assets/ {
add_header Cache-Control "public, max-age=604800";
}
This sets a seven-day freshness lifetime in seconds. It does not make an unversioned file immutable; the URL-versioning decision remains yours.
Do not create contradictory policies accidentally
If both directives are present, inspect the actual response and remove ambiguity. A generated max-age from expires and an explicit Cache-Control field should express the same intention. The browser follows the response it receives, not the policy you intended in a different configuration file.
Rank #4
Control which responses receive a header
add_header follows Nginx’s normal status-code handling and inheritance rules. A header may appear on successful responses but not on every error response unless you request that behavior. Use the always parameter when a policy must also be added outside the module’s default status list, for example:
location /assets/ {
add_header Cache-Control "public, max-age=604800" always;
}
Use always with care. An error response should not automatically become publicly cacheable if it contains sensitive diagnostics or a user-specific message. Test both successful and failing requests when you depend on this parameter.
Make validators enable efficient revalidation
Revalidation is most useful when the response includes ETag and/or Last-Modified. After receiving a no-cache response, a browser can send If-None-Match or If-Modified-Since. If the representation is unchanged, Nginx can answer 304 Not Modified without retransmitting the body. If it changed, the server returns the new representation and updated metadata.
Do not confuse a 304 response with a cache hit that required no request. A fresh immutable asset can be used without validation; a no-cache response normally requires a conditional request before reuse.
Verify the effective behavior
Always test the response that a real browser receives. Configuration syntax alone does not prove that the request selected the expected location or that another layer did not replace a header.
- Validate the configuration with
nginx -t. - Reload Nginx through the service manager used by your host after the test succeeds.
- Inspect a representative fingerprinted asset:
curl -I https://example.test/assets/app.abc123.js. - Inspect the entry document separately:
curl -I https://example.test/. - Confirm that
Cache-ControlandExpiresmatch the intended location, and record anyETagorLast-Modifiedvalue. - For a revalidation test, send the captured validator, for example
curl -I -H "If-None-Match: ..." https://example.test/, and look for304 Not Modifiedwhen the representation is unchanged. - Test a successful response, an error response if you use
always, a fingerprinted URL, and an otherwise identical unversioned URL.
Browser developer tools can corroborate the result, but distinguish “memory cache” or “disk cache” reuse from a network response. Disable-cache options in a developer-tools panel often change the test conditions and should not be mistaken for normal visitor behavior.
Best Value
Troubleshoot a browser that keeps downloading the same asset
The URL is not actually fresh
Check the response headers with curl -I, not only the Nginx file. If the response has Cache-Control: no-cache, a conditional request on each use is expected. That is revalidation, not necessarily a full download; a 304 response carries no new body.
A different location won
Regular-expression and nested locations can select a block other than the one you edited. Compare the requested URI with the exact location pattern and inspect the complete server configuration. A rule for /assets/ will not affect a file served from another prefix.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteA nested header replaced a parent header
Adding any add_header in a child location can change which parent headers are inherited. Review all add_header directives in the selected block and its ancestors, then define the complete policy in the most specific block.
Another layer changed the response
A CDN, reverse proxy, upstream application, or hosting control panel may add, replace, or remove cache headers after Nginx generates them. Compare headers at the public URL and, when possible, at the origin. The public response is the behavior the browser follows.
The file name is stable while the bytes change
A one-year policy on a stable URL is a cache-invalidation bug. Either publish a new fingerprinted URL for each change or shorten the policy and accept more validation requests.
The test is bypassing the cache
Private-browsing modes, developer-tools “disable cache” settings, service workers, and hard-refresh actions can produce behavior unlike a normal navigation. Repeat the test in a normal profile and inspect the network request and response headers.
Recommended Free Tools
Protect private and sensitive content
Public caching is appropriate for identical static bytes that every visitor may receive. It is not a safe default for account data, checkout pages, authorization responses, or responses containing personal information. Mark such responses with an application-appropriate private or no-store policy, and avoid broad extension-based locations that could capture dynamic output merely because its URL ends in a familiar suffix.
Also consider error pages. If you use add_header ... always, verify that an error body does not contain secrets or request-specific details that a shared cache could retain.
Browser cache versus Nginx proxy cache
These layers answer different questions:
| Layer | Where bytes are stored | Main controls | Typical purpose |
|---|---|---|---|
| Browser cache | On the visitor’s device | Response headers such as Cache-Control, Expires, validators, and request conditions |
Avoid repeat transfers to the same user. |
| Nginx proxy cache | On the Nginx server or its configured cache storage | proxy_cache_path, proxy_cache, proxy_cache_valid, and bypass rules |
Reuse an upstream response for multiple requests before contacting the application. |
Enabling proxy caching does not cause a browser to cache the result, and browser headers do not create an Nginx proxy cache. Configure and verify each layer independently.
Quick Recap
A deployment checklist
- List which URLs are immutable fingerprints and which URLs can change in place.
- Assign long-lived public caching only to the immutable group.
- Use
no-cacheplus validators for HTML and other frequently changing, non-sensitive responses. - Keep personalized or sensitive output out of public caching.
- Place directives in the location that actually serves each resource.
- Review header inheritance whenever a nested location adds its own header.
- Use
alwaysonly when nonstandard status responses genuinely need the header. - Run
nginx -t, reload through the normal service manager, and inspect representative public responses. - Test conditional requests and confirm
304 Not Modifiedfor unchanged revalidated resources. - Check CDN, proxy, and application layers for header overrides.
- During every release, verify that changed bytes receive changed URLs or an intentionally short/revalidated policy.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problems




