Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteiTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
Set Apache’s Expires and Cache-Control: max-age response headers with the mod_expires module. Turn the module on with ExpiresActive On, define a fallback with ExpiresDefault, and add MIME-type rules with ExpiresByType. Then inspect an actual response to confirm that Apache matched the intended Content-Type and duration.
A practical starting policy is to revalidate HTML immediately, give versioned CSS, JavaScript, and images a longer lifetime, and use a conservative fallback for everything else. The correct duration depends on how often each URL changes and whether deployments change asset filenames.
Free tools Windows power users keep installed
One-click scans. No signup required.
What Apache expire headers do
HTTP caching uses two related pieces of information. The Expires header contains an absolute HTTP date. The Cache-Control header can contain a relative max-age value in seconds. Apache’s mod_expires module calculates both values for matching responses. The Apache HTTP Server documentation describes the module as controlling the Expires header and the max-age directive in Cache-Control.
These headers tell a browser or an intermediary how long a response may be considered fresh. They do not change the file, compress it, or invalidate copies already stored by a cache. They also do not make a resource immutable by themselves: if the same URL serves new bytes after a deployment, a cache can continue using the old response until its freshness lifetime ends.
#1 Best Overall
The module is disabled by default. A configuration containing only ExpiresActive On enables processing, but it does not necessarily create a header for every response. At least one matching expiration rule—an ExpiresDefault fallback or an ExpiresByType rule—must supply the calculation.
Check the configuration scope before editing
The three directives used for a normal policy are valid in server configuration, a virtual-host configuration, a directory context, and (when the host permits it) .htaccess:
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 reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchExpiresActiveswitches generation on or off.ExpiresDefaultdefines the fallback calculation.ExpiresByTypedefines a calculation for a response MIME type.
Apache documents these directives with the Indexes override class for .htaccess. That means a hosting provider can allow or deny them independently of whether the file itself is readable. If Apache reports that a directive is not allowed, move the rule into the virtual-host or server configuration, or ask the administrator to permit the required override class. Do not assume that placing a file named .htaccess in the document root gives it permission to change every Apache setting.
The module must also be loaded. On a server managed by an administrator, the relevant module is normally enabled in the main Apache configuration and made available to the virtual host. If Apache returns an error such as an unknown ExpiresActive directive, the problem is module availability rather than the duration syntax. A shared host may not allow you to load modules yourself.
A safe baseline configuration
Place the following in the applicable virtual-host, directory, or permitted .htaccess context:
ExpiresActive On
# Conservative fallback for responses without a type-specific rule
ExpiresDefault "access plus 1 hour"
# Revalidate document markup frequently
ExpiresByType text/html "access plus 0 seconds"
# Longer lifetime for assets whose URLs change when their contents change
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/* "access plus 1 month"
# A more specific rule overrides the image wildcard
ExpiresByType image/gif "access plus 1 week"
The fallback prevents an unclassified response from silently receiving no expiration rule. The HTML rule makes the freshness lifetime zero, so clients must revalidate rather than treating the document as fresh for a period. The CSS, JavaScript, and image rules use a month in this example because those resources are assumed to be versioned at deployment. The GIF rule demonstrates that a specific MIME type can replace the broader image/* rule.
These are policy examples, not universal values. Apache’s documentation does not prescribe one cache duration for every site. Choose each lifetime from the resource’s change frequency and your deployment’s invalidation method.
Rank #2
- Used Book in Good Condition
How the three directives interact
ExpiresActive
ExpiresActive On enables expiration processing in the current configuration scope. Its default is Off. Use ExpiresActive Off in a narrower scope when a broader server or virtual-host policy must be disabled for a directory.
ExpiresDefault
ExpiresDefault supplies the algorithm used when no matching ExpiresByType rule exists. It is a fallback, not a second header that is added alongside a type rule. A response matching a type-specific rule uses that rule instead.
ExpiresByType
ExpiresByType matches the response’s MIME type and sets both the calculated Expires value and the Cache-Control max-age. It works only while ExpiresActive is on. Matching is based on the MIME type Apache sends in Content-Type, not simply on the filename extension.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →A wildcard major type such as image/* is considered before Apache falls back to ExpiresDefault. A more specific entry such as image/gif takes precedence over that wildcard. Keep the wildcard and specific entries together in the configuration so the intended policy is easy to audit.
Expiration syntax and the choice of base time
Apache accepts a readable expression or a numeric-seconds expression. The readable form is easier to review; the numeric form is useful when an exact number of seconds is required.
| Form | Meaning | Example |
|---|---|---|
access or now |
Calculate from the time the response is served. | ExpiresByType text/html "access plus 0 seconds" |
modification |
Calculate from the resource’s modification time. | ExpiresByType text/css "modification plus 1 month" |
| Readable interval | Use units such as years, months, weeks, days, or hours after the base. | ExpiresDefault "access plus 1 hour" |
A followed by seconds |
Use access time as the base and add the stated number of seconds. | ExpiresByType text/html A0 |
M followed by seconds |
Use modification time as the base and add the stated number of seconds. | ExpiresByType text/html M604800 |
The first character in the numeric form is significant: A means access time and M means modification time. For example, M604800 represents seven days after modification, while A604800 represents seven days after the response is accessed. The readable form can express the same policy without requiring you to convert the interval to seconds.
Access-based rules are predictable for generated responses because they do not require a filesystem modification timestamp. Modification-based rules can be useful for files whose mtime reflects publication, but they need a meaningful and correctly maintained mtime. If a deployment copies every file while preserving an old timestamp, a modification-based expiration date may not reflect the actual release. If a response is generated dynamically and has no useful file mtime, prefer an access-based rule.
Design a policy around URL invalidation
The central decision is not whether one month or one week sounds reasonable; it is how a client learns that a URL now serves different bytes.
Versioned static assets
If each release changes the CSS, JavaScript, or image URL—for example, by adding a content hash or release version—an old URL can safely remain cached after deployment because new pages point to a new URL. A longer lifetime reduces revalidation traffic. The example configuration uses one month for this case, but you can choose a longer value when your release process and storage strategy support it.
Stable asset URLs
If a file keeps the same URL while its contents change, a long freshness lifetime delays discovery of the update. Use a shorter access-based lifetime or change the URL when publishing. Do not advertise a long lifetime for an unversioned URL merely because the file is an image or stylesheet; the MIME type says what the resource is, not how often it changes.
HTML documents
HTML commonly contains the links to the newest asset URLs. A zero-second rule in the example asks clients to revalidate the document on each use while still allowing normal HTTP validation mechanisms. If your application intentionally serves rarely changing documents, a nonzero HTML lifetime may be appropriate, but it should be an explicit publishing decision.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Fallback content
A fallback is useful for responses that do not have a dedicated type rule, but it should be conservative. A broad fallback can accidentally cache an endpoint, download, or administrative response for longer than intended. Add explicit rules for important types rather than relying on a wildcard that obscures the behavior of new responses.
Where to put the rules
Server or virtual-host configuration
In centrally managed Apache, place the directives inside the relevant virtual host or directory block. This is the clearest option because the administrator can load the module, validate the complete configuration, and apply one policy to many sites or paths. A server-level default can be narrowed in a virtual host or directory context.
Directory configuration
A directory block can apply a policy to one part of a site. This is useful when static assets and application responses are served from different paths. Make sure the directory’s effective Content-Type values are what your ExpiresByType rules expect.
Rank #4
.htaccess
Use .htaccess only when you cannot edit the main configuration and the host permits the directives. Put the file in the directory whose responses should inherit the policy. A rule in a parent directory can affect descendants unless a narrower configuration changes it. Keep comments that explain the invalidation assumption, especially when a long lifetime depends on versioned filenames.
Step-by-step: configure and verify in .htaccess
- Confirm that overrides are permitted. Ask the server administrator or inspect the site’s existing configuration process. If Apache rejects the directives as forbidden, no edit inside
.htaccesswill bypass that restriction. - Confirm that
mod_expiresis available. An unknown-directive error indicates that the module is not loaded in the Apache instance serving the request. - Create or edit the applicable file. Place the baseline policy in the correct document directory. Preserve any existing directives and avoid adding a second, conflicting policy in a child directory without a reason.
- Start with a fallback and a few explicit types. Enable processing, add
ExpiresDefault, then add only the MIME rules you can justify. Expand the list after checking actual response types. - Validate Apache’s configuration before reloading. Use the configuration-test procedure provided by your operating system or hosting control panel. Correct quotation, spelling, and context errors before applying the change.
- Request a real resource. Test an HTML page, a stylesheet, a script, and an image that are actually served by the target virtual host. A request to a different host or an upstream proxy can produce headers from another configuration.
- Inspect the response headers. Confirm the
Content-Type,Expires, andCache-Controlvalues. Check thatmax-agecorresponds to the intended interval and that the date is plausible for the chosen base. - Test after a deployment change. If the policy relies on versioned URLs, verify that the page references the new names. If URLs remain stable, verify that the selected lifetime gives users an acceptable update window.
How to inspect the result
Browser developer tools show the response headers for an individual request. Open the browser’s Network panel, reload the page, select the resource, and inspect the response-header section. Look for all three values:
Content-Typetells you whichExpiresByTyperule could match.Expiresis the absolute expiration date generated by Apache or another component.Cache-Controlshould contain the expectedmax-agewhenmod_expiressupplied the policy.
For a command-line check, request headers without downloading the body:
curl -sSI https://example.com/path/to/app.css
Use the final response after redirects when necessary, and test the hostname that maps to the virtual host you edited. Compare the response’s Content-Type with the exact type in your rule. For example, a rule for application/javascript will not match a response sent as text/javascript; add the type that Apache actually emits if that distinction is intentional.
A correct header does not prove that every cache will immediately discard an older object. Existing browser, proxy, or CDN entries retain their prior metadata until they revalidate or expire. Test a fresh request and account for any intermediary that may add, replace, or preserve headers.
Why the headers are missing or unchanged
ExpiresActive is missing or disabled
Without ExpiresActive On, the module does not generate the policy. A broader configuration may also have turned it off in the directory serving the resource. Check the effective scope rather than only the file you edited.
No rule matches
Turning the module on is not enough if neither ExpiresDefault nor an applicable ExpiresByType rule exists. Add a conservative fallback, or add a rule for the response’s actual MIME type.
Best Value
- Used Book in Good Condition
The MIME type is different from the filename assumption
ExpiresByType uses the response MIME type. A file named script.js can fail to match a rule if Apache sends an unexpected Content-Type. Inspect the header and correct either the MIME mapping or the expiration rule.
Another component already generated the header
If the server, a CGI script, or a proxied origin response has already generated an Expires header, mod_expires does not replace it or add a competing Expires or Cache-Control value. Find the component that owns the existing header and change the policy there, or remove the conflicting generation so Apache can apply the intended rule.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →The request is reaching a different configuration
DNS, redirects, a reverse proxy, or a second virtual host can send the request somewhere other than the directory you changed. Inspect the final URL and the server-specific response headers. Verify that the test hostname, protocol, and path select the expected virtual host.
The configuration was not reloaded or contains an error
Main and virtual-host configuration changes normally require a successful configuration test and reload. A syntax error can leave the old configuration active or prevent the service from reloading. With .htaccess, Apache reads the file per request, but a malformed directive still causes an error response; check the Apache error log.
A cache is showing an older response
Use a fresh request and compare headers from the origin and any intermediary. A browser’s memory or disk cache can hide a server-side change. A proxy can also retain an older Expires or Cache-Control header. The fix is to identify which hop supplied the observed response, not to keep adding duplicate expiration directives.
Common policy mistakes
- Using a long fallback for everything. A fallback also applies to newly introduced response types, including endpoints that should be revalidated quickly. Keep it conservative and add intentional type rules.
- Assuming an extension controls matching. Apache matches
Content-Type, so verify the MIME header rather than relying on.css,.js, or.jpgin the URL. - Choosing modification time for generated content. If there is no reliable file modification time, an
Mrule may not represent publication time. Use an access-based expression or set headers in the application that owns the response. - Long-caching stable URLs that change in place. A cache cannot know that the bytes changed until the freshness lifetime ends or the URL changes. Add versioning to the URL or shorten the lifetime.
- Adding overlapping wildcard rules without checking specificity. A specific type such as
image/gifoverridesimage/*. Document the exception so a later editor does not mistake it for a duplicate. - Expecting
ExpiresActive Onto override application headers. Existing expiration generated by a CGI script or proxied origin remains authoritative to the extent thatmod_expiresdeclines to replace it.
Example policies for different release models
Versioned frontend assets
ExpiresActive On
ExpiresDefault "access plus 1 hour"
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/* "access plus 1 month"
Use this shape when every asset change produces a new URL. The HTML is checked frequently, while old asset URLs can remain fresh without preventing the page from selecting the newest versions.
Recommended Free Tools
Unversioned files that must update promptly
ExpiresActive On
ExpiresDefault "access plus 0 seconds"
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType text/css "access plus 5 minutes"
ExpiresByType application/javascript "access plus 5 minutes"
ExpiresByType image/* "access plus 5 minutes"
This policy favors timely revalidation when URLs stay unchanged. The five-minute values are an example of a short operational window, not an Apache requirement.
Different treatment for one image type
ExpiresActive On
ExpiresDefault "access plus 1 hour"
ExpiresByType image/* "access plus 1 month"
ExpiresByType image/gif "access plus 1 week"
The wildcard covers image responses that have no more specific rule. The GIF entry narrows the lifetime for that exact MIME type.
Operational checklist
- Is
mod_expiresloaded in the Apache instance serving this host? - Is
ExpiresActive Oneffective in the directory or virtual host? - Does a fallback or matching MIME rule exist?
- Does the response’s
Content-Typeexactly match the intended rule? - Is the base time—access or modification—appropriate for this resource?
- Does the lifetime match the way deployments invalidate URLs?
- Is another server, script, proxy, or origin already setting
ExpiresorCache-Control? - Did you inspect a response from the final hostname and path after applying the configuration?
When those checks pass, Apache will calculate the expiration date and corresponding max-age for each response that matches the policy. The durable solution is not one universal number; it is a documented relationship between resource type, change frequency, and URL versioning.
Quick Recap
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.

