Recommended Free Tools
Set Apache’s mod_expires rules in the configuration scope that serves your files, turn generation on with ExpiresActive On, then define a fallback and MIME-type-specific lifetimes. A practical starting policy is a short lifetime for HTML and longer lifetimes for versioned CSS, JavaScript, and images.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
The module writes both an HTTP Expires date and the corresponding max-age value in Cache-Control. The exact result depends on the response’s MIME type, the rule that matches it, and whether another component has already supplied cache headers.
As an Amazon Associate I earn from qualifying purchases.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsWhat Apache Expires headers do
Browsers and intermediary caches use response freshness information to decide whether a stored response can be reused or must be requested again. Apache’s mod_expires module controls two related response fields:
Expires, an absolute date and time after which the response is considered stale.Cache-Control: max-age, a relative lifetime in seconds.
The Apache Software Foundation describes the module as controlling “the setting of the Expires HTTP header and the max-age directive of the Cache-Control HTTP header in server responses.” The two values are generated from the same rule, so you normally configure them together rather than writing separate header expressions.
#1 Best Overall
Expiration is not the same as invalidation. A cache can continue to hold an object after its freshness lifetime, but it should revalidate or fetch a fresh response before using it as current. Your policy therefore needs to reflect how often a resource changes and how quickly clients must see a change at the same URL.
Prerequisites and configuration scope
Enable mod_expires where the response is generated
The directives in this guide require Apache’s mod_expires module. The module can be configured in the main server configuration, a virtual-host configuration, a directory context, or an .htaccess file. Apache documents ExpiresActive as accepting those contexts, with the Indexes override class applying when it is used in .htaccess.
Free tools Windows power users keep installed
One-click scans. No signup required.
Whether you can use an .htaccess file depends on the host’s permitted overrides. If the server rejects the directive or returns a configuration error, move the rule to the virtual host or directory configuration, or ask the administrator to permit the required override class. Do not assume that a rule in one virtual host affects another.
Turn generation on explicitly
ExpiresActive is Off by default. Put this directive in the scope that handles the files for which you want generated expiration metadata:
ExpiresActive On
Turning the module on does not by itself choose a useful lifetime for every response. You still need an ExpiresDefault rule, matching ExpiresByType rules, or both.
A minimal working configuration
This example establishes a one-hour fallback, asks clients to revalidate HTML immediately, and gives versioned static assets a month of freshness:
ExpiresActive On
# Fallback for responses without a type-specific rule
ExpiresDefault "access plus 1 hour"
# Documents should be checked frequently
ExpiresByType text/html "access plus 0 seconds"
# Use longer lifetimes when deployment changes the asset URL
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/* "access plus 1 month"
# A specific type can override the image wildcard
ExpiresByType image/gif "access plus 1 week"
The quoted interval is an algorithm, not a literal header value. Apache calculates the expiration date for each response and emits the equivalent Cache-Control: max-age value. The fallback applies only when no more specific type rule matches.
Understanding ExpiresDefault
ExpiresDefault supplies the default expiration algorithm for responses handled in the current configuration scope. It is the safety net for content that does not match an ExpiresByType entry.
Rank #2
For example:
ExpiresActive On
ExpiresDefault "access plus 1 hour"
With this policy, a response that reaches this scope and has no matching type-specific rule receives an expiration one hour after the request access time. A default is useful because it makes the policy explicit, but it should be conservative: an unclassified response may be a page, an API response, or a file whose update pattern you have not reviewed.
A default does not override a matching ExpiresByType entry. Once Apache identifies a matching MIME type, that type-specific algorithm determines the result.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Using ExpiresByType for MIME-specific lifetimes
ExpiresByType sets the Expires value and Cache-Control: max-age for responses with the selected MIME type. It works only when ExpiresActive On is enabled in the applicable scope.
The basic form is:
ExpiresByType MIME-TYPE "algorithm"
Examples:
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
Matching is based on the response’s Content-Type. If a file is being served with an unexpected type, the rule you intended may never be selected. Always inspect the actual response type while troubleshooting.
Wildcard major types
You can use a major-type wildcard such as image/* to cover image subtypes without listing each one:
ExpiresByType image/* "access plus 1 month"
A specific entry takes precedence over the wildcard. In the following example, GIF files receive one week while other image subtypes covered by the wildcard receive one month:
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 →Clear out junk files and repair common Windows errorsFree Scan →ExpiresByType image/* "access plus 1 month"
ExpiresByType image/gif "access plus 1 week"
If neither a specific entry nor a wildcard matches, Apache falls back to ExpiresDefault, if one is configured.
Choosing access time or modification time
Apache supports two bases for calculating an expiration date:
Rank #3
- Access time: the interval is measured from the request time. Readable forms use
accessornow, such as"access plus 1 hour". - Modification time: the interval is measured from the file’s modification time. Readable forms use
modification.
The numeric form makes the base explicit with a leading letter. For example:
ExpiresByType text/html M604800
Here, M means modification time and 604800 is the lifetime in seconds. The access-time equivalent uses A:
ExpiresByType text/html A604800
Use the readable form when maintainers need to understand the policy at a glance. Use the numeric form when a fixed number of seconds and an explicit base make the rule easier to audit. Whichever form you choose, keep the base consistent with your deployment and invalidation strategy.
Designing a cache policy that will not surprise users
HTML and other frequently changing documents
HTML often contains navigation, prices, account state, or links to newly deployed assets. A short lifetime or immediate revalidation reduces the time a client can use an old document. The example policy expresses that intent with:
ExpiresByType text/html "access plus 0 seconds"
That rule still generates expiration metadata; it does not mean Apache refuses to cache the response. The client receives a zero-second freshness lifetime and should check with the origin before reusing a stored copy.
Versioned static assets
CSS, JavaScript, and image files can safely receive longer lifetimes when every content change also changes the URL, for example by adding a version or content hash to the filename. A new URL is a cache miss, so clients retrieve the new bytes without waiting for the old URL to expire.
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/* "access plus 1 month"
If your deployment overwrites the same URL, a long lifetime can leave users with stale assets until the cache expires. In that case, shorten the interval or adopt URL versioning before increasing it.
Fallback content
A fallback should be deliberately conservative because it covers every response not classified by a more specific rule. The one-hour example is only a starting policy; Apache’s documentation does not prescribe a universal duration. Select a value according to the resource’s update frequency and the consequences of stale content.
Rank #4
Precedence: which rule wins
Apache evaluates the configured rules in a predictable order:
- If a matching specific
ExpiresByTypeentry exists, it supplies the algorithm. - If no specific entry matches but a wildcard major-type entry applies, the wildcard supplies the algorithm.
- If no type-specific rule applies,
ExpiresDefaultsupplies the algorithm.
For example:
ExpiresActive On
ExpiresDefault "access plus 1 hour"
ExpiresByType image/* "access plus 1 month"
ExpiresByType image/gif "access plus 1 week"
A GIF response receives one week because the specific image/gif rule overrides image/*. A PNG response receives one month from the wildcard. A response such as text/plain receives one hour from the default, assuming no other matching rule exists.
Configuring the rules in .htaccess
When directory-level overrides are permitted, place the directives in the .htaccess file governing the requested files:
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"
The directory scope matters. A rule in a parent directory can apply to descendants, while a rule in another virtual host or unrelated directory does not. If a host has disabled the necessary overrides, Apache will not apply these directives from .htaccess; configure the virtual host or server instead.
Keep one authoritative policy where possible. Splitting overlapping rules among several directory files makes it harder to identify the effective default and the type-specific override.
How to verify the headers
Always test a real response after changing configuration. Use browser developer tools or an HTTP header inspection command and check all three items together:
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 minute- The response’s
Content-Type. - The
Expiresdate. - The
Cache-Controlheader and itsmax-agevalue.
Testing different resource classes is more useful than testing only the home page. Inspect one HTML document, one stylesheet or script, and one image so that you can confirm both the fallback and the type-specific rules.
Compare the observed lifetime with the rule you intended. A one-month rule should produce a max-age measured in roughly that interval, while an HTML rule of 0 seconds should produce a zero-second maximum age. The exact absolute Expires timestamp changes with the request time, so the relative max-age is usually the easiest value to audit.
Best Value
Why Expires headers may be missing or unchanged
The module is not active in the serving scope
If ExpiresActive On is absent, misspelled, or placed in a configuration scope that does not handle the request, mod_expires will not generate the fields. Confirm the directive is present in the active server, virtual host, directory, or permitted .htaccess context.
No default or MIME rule matches
Turning the module on does not guarantee a header for every response. A response needs a matching ExpiresByType rule or an applicable ExpiresDefault. If you configured only rules for CSS and images, an unclassified response may have no generated expiration metadata.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →The response has an unexpected Content-Type
ExpiresByType matches the MIME type Apache sends, not the filename extension you had in mind. Inspect Content-Type and add a rule for the actual type, or correct the type mapping if it is wrong.
Another component already supplied headers
When an Expires header has already been generated by the server, a CGI script, or a proxied origin response, mod_expires does not change or add an Expires or Cache-Control header. An apparently unchanged value can therefore be evidence that another layer owns the policy.
Check the response at the client-facing endpoint, not only at the origin. A reverse proxy or application may add, replace, or preserve headers after Apache’s module has run.
The edited file is not the file being served
Virtual hosts, directory inheritance, and proxies can make a different configuration or origin responsible for the response. Verify the hostname, path, and deployment environment you tested, then inspect the effective response headers again.
Common configuration mistakes
- Forgetting activation: defining
ExpiresDefaultorExpiresByTypewithoutExpiresActive Onleaves generation disabled. - Expecting a default to override a type rule: a matching
ExpiresByTypeentry always takes precedence overExpiresDefault. - Using a long lifetime on unversioned URLs: clients can retain old CSS, JavaScript, or images after a deployment that reused the same filename.
- Reading only one header: verify both
ExpiresandCache-Control: max-age; they are generated together by the module. - Assuming every response is eligible: pre-existing headers from the server, CGI, or a proxied origin are not replaced by
mod_expires. - Testing only the browser cache: use the actual response headers to distinguish an Apache rule from a locally stored result.
A repeatable setup procedure
- Choose the serving scope. Decide whether the policy belongs in the main server configuration, a virtual host, a directory, or an allowed
.htaccessfile. - Confirm module availability. Ensure the Apache instance serving the request has
mod_expiresavailable and that the chosen scope accepts the directives. - Enable generation. Add
ExpiresActive On. - Add a conservative fallback. Set
ExpiresDefaultfor responses without a type-specific rule. - Classify important MIME types. Add
ExpiresByTypeentries for HTML, stylesheets, scripts, images, or other resource classes whose update patterns differ. - Decide the time base. Use
access/nowfor a lifetime measured from the request, ormodification(or the numericMform) when file modification time should be part of the calculation. - Account for invalidation. Give long-lived assets stable freshness only when deployments change their URLs or otherwise provide a reliable way for clients to obtain new content.
- Reload through your normal Apache change process. A configuration edit must be accepted by the running server before it can affect responses.
- Inspect real responses. Check
Content-Type,Expires, andCache-Control: max-agefor each resource class. - Trace conflicts. If a value is missing or unchanged, look for an unmatched type, a disabled override, a different serving scope, or headers already supplied by Apache, CGI, or a proxy.
Reference policy patterns
Conservative mixed-content policy
ExpiresActive On
ExpiresDefault "access plus 1 hour"
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType text/css "access plus 1 week"
ExpiresByType application/javascript "access plus 1 week"
ExpiresByType image/* "access plus 1 week"
This pattern limits the fallback and keeps common assets relatively fresh. It is appropriate when URLs are reused and deployments need changes to appear without a long waiting period.
Versioned-asset policy
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"
ExpiresByType image/gif "access plus 1 week"
This pattern gives versioned static files a longer lifetime while retaining immediate HTML revalidation. The GIF exception demonstrates how a specific rule can shorten the wildcard lifetime for one subtype.
What the directives do not decide
These directives do not determine whether a response is public or private, whether an application should be cached, or how a proxy handles every other cache-control directive. They calculate expiration metadata for responses that match the configured criteria. Existing headers and other server components can remain authoritative.
They also do not provide a universally correct duration. A one-hour fallback, one-week asset rule, or one-month asset rule is a policy choice illustrated by the syntax, not a requirement imposed by Apache. Review each resource’s change frequency, URL-versioning practice, and tolerance for stale data before selecting the interval.
Free tools Windows power users keep installed
One-click scans. No signup required.
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.

