• Monday, September 8, 2025

Site owners can effectively manage the caching engine by utilizing directives and rewrite rules within the .htaccess file located in their site's document root. This guide will detail the syntax for both directives and rewrite rules, followed by practical examples. These explanations and examples are designed to equip you with the necessary knowledge to tailor the caching system's configuration to your website's specific requirements, ensuring optimal performance.

Directives

Placement of Directives

Directives are essential configuration commands that must be enclosed within <IfModule the_web_server>...</IfModule> tags. The specific location for server-level and virtual-host-level configuration files can vary depending on the control panel being used. For site-level configurations, these directives are typically placed within the .htaccess file found in the site's document root.

While rewrite rules offer standalone capabilities for enabling or disabling caching, complex requirements often benefit from a combined approach. Utilizing both rewrite rules and directives together can provide more precise control over your caching strategy. It is important to note that CacheEnable and CacheDisable directives, when placed in the virtual host's .htaccess file, will take precedence over any server-level cache policies, allowing for granular control at the site level.

Note: For users of WHM/cPanel environments, directives such as CacheEnable and CacheDisable need to be manually added to Apache configuration files. This is because cPanel environments typically do not provide a direct option to enable mod_cache functionality.

Tip: You can further refine your caching policy by incorporating Apache mod_cache directives, such as CacheIgnoreCacheControl and CacheMaxExpire. These can be integrated into Apache configuration files (httpd.conf or .htaccess) to achieve more specific caching behaviors.

CacheEngine

The CacheEngine directive serves as the primary control for globally activating or deactivating the caching engine. In shared hosting environments, this setting is typically pre-configured by your hosting provider at either the server or virtual host level, establishing a foundational caching policy.

It is crucial to understand that, unlike many other directives, CacheEngine is not implemented within an .htaccess file. Its placement is restricted to server configuration or virtual host configuration files, whose exact locations can vary based on the specific control panel in use. The CacheEngine directive supports two main states: off or on. Additionally, it can be configured to enable functionalities such as ESI (Edge Side Includes) and the cache crawler, as demonstrated in the following example:

<IfModule the_web_server> CacheEngine on esi crawler </IfModule>

Activating the caching engine at the server or virtual host level is a prerequisite for any site to leverage the subsequent directives or rewrite rules discussed in this guide. For comprehensive details regarding the CacheEngine directive, consult the relevant server documentation.

CacheEnable

To activate public caching for your website, insert the following lines into the .htaccess file situated within your site's document root:

<IfModule the_web_server>  CacheEnable public / </IfModule>

This configuration effectively enables caching for all URLs associated with the specific virtual host. This action mirrors the functionality of selecting 'Yes' for the Enable Public Cache option within the web administration interface for the virtual host. By specifying / in your directive, you instruct the caching system to apply public caching to all content located within the website's root directory and its subdirectories.

Example: Consider a website, https://www.example.com, residing in the /home/username/public_html directory. Using CacheEnable public / would result in all content within /home/username/public_html and its subdirectories being cached. Conversely, employing CacheEnable public /blog would specifically cache all content under /home/username/public_html/blog, accessible via http://www.example.com/blog.

For enabling private caching, add the subsequent lines to your .htaccess file:

<IfModule the_web_server>  CacheEnable private / </IfModule>

This code snippet activates private caching for all URLs of the virtual host, mirroring the setting of Enable Private Cache to 'Yes' in the web administration configuration for that virtual host. Private caching is distinct in that it stores cached content specifically for individual users.

CacheDisable

To deactivate public caching for your site, include the following lines in the .htaccess file within the website's document root:

<IfModule the_web_server>  CacheDisable public / </IfModule>

Similarly, to disable private caching, apply the following code:

<IfModule the_web_server>  CacheDisable private / </IfModule>

Tip: Specifying / in the CacheDisable directive will disable caching across the entire website. To disable caching for a specific URL only, replace / with the precise path to that URL. This allows for selective control over which parts of your site are cached.

CacheLookup

The CacheLookup directive serves to instruct the application whether to perform a cache lookup or not. When CacheEnable or CacheDisable directives are explicitly utilized, the functionality of CacheLookup is automatically implied, meaning it does not need to be separately defined.

However, CacheLookup frequently comes into play when using caching plugins. These plugins often manage the enabling or disabling of the cache internally and do not rely on the CacheEnable/CacheDisable directives. In such scenarios, the CacheLookup directive becomes essential to explicitly tell the application to verify the cache for a requested resource. An example of its usage is shown below:

<IfModule the_web_server>  CacheLookup public on </IfModule>

This code snippet explicitly directs the application to query the public cache for the requested URL, ensuring that cached content is served when available.

Rewrite Rules

As an alternative or complement to directives, the cache-control environment variable can be effectively utilized within a series of rewrite rules. This approach offers a powerful way to manage caching behavior, typically structured as follows:

<IfModule the_web_server>  RewriteEngine On RewriteCond  CONDITION RewriteRule PATTERN - [E=cache-control:VALUE] </IfModule>

In this structure, CONDITION is a placeholder for an optional filter, allowing you to specify criteria for applying the rule. PATTERN should be replaced with a regular expression that precisely targets the URLs or pages to which the rule will apply. Finally, VALUE represents the desired content of the cache-control variable, dictating the caching behavior. When multiple values for cache-control are required, they can be expressed in two distinct ways:

RewriteRule PATTERN - [E="cache-control:VALUE1,VALUE2"]

or

RewriteRule PATTERN - [E=cache-control:VALUE1,E=cache-control:VALUE2]

The cache-control variable supports a variety of values, each serving a specific purpose in defining caching policy:

  • no-cache: Instructs the browser not to cache the content.
  • no-store: Prevents caching and ensures no sensitive information is stored.
  • max-age: Defines the maximum amount of time a resource is considered fresh.
  • max-stale: Indicates that a client is willing to accept a stale response.
  • public: Marks the response as cacheable by any cache.
  • private: Marks the response as cacheable only by a private browser cache.
  • s-maxage: Similar to max-age, but specific to shared caches.
  • no-vary: Prevents the cache from storing multiple variations of a resource.
  • esi: Enables Edge Side Includes processing.

Rewrite rules can be strategically placed in either the httpd.conf file or directly within the .htaccess file located in the relevant directory. A key distinction between enabling caching via E=cache-control and the CacheEnable directive lies in the ability to control the cache expiration time (TTL). Rewrite rules, through the max-age value, allow for precise control over how long content remains cached, a capability not available with the simpler CacheEnable directive.

Enabling Caching

To enable caching for your website, you have the flexibility to either employ rewrite rules independently or combine them with the CacheEnable directive to fulfill more intricate requirements. Regardless of the chosen method, these rules provide granular control over which content is cached and which is explicitly excluded.

Below is a straightforward example demonstrating the use of rewrite rules alone to activate caching for all URLs, with a specified cache duration of two minutes:

<IfModule the_web_server> RewriteEngine On RewriteRule .* - [E=cache-control:max-age=120] </IfModule>

Another simple illustration shows how rewrite rules can be used to enable private caching for all URLs. For private caches, specifying a max-age is often unnecessary, as its lifespan is typically managed by session control and is specific to an individual browser:

<IfModule the_web_server> RewriteEngine On RewriteRule .* - [E=cache-control:private] </IfModule>

For more sophisticated caching behaviors, a complex example using only rewrite rules is presented. The first segment of code establishes a set of conditions: it verifies for HEAD or GET requests, checks for a specific cookie value, examines the query string, and ensures the page name does not match a predefined list of strings. If all these conditions are met and the page ends in .php, it will be cached for two minutes.

If a page does not satisfy these initial criteria, the second block of code is executed. This set of conditions is identical to the first, with the crucial difference being that the cookie's value should not be 'yes'. If these conditions are fulfilled, and the page is a .php file, it will be placed in the private cache according to the virtual host's caching policy, ensuring user-specific content is handled appropriately.

<IfModule the_web_server> RewriteEngine On RewriteCond %{REQUEST_METHOD} ^HEAD|GET$ RewriteCond %{HTTP_COOKIE} page_contain_cachetoken=yes RewriteCond %{QUERY_STRING} !s=[a-fA-F0-9]{32} RewriteCond %{REQUEST_URI} !/(login|register|usercp|private|profile|cron|image)\.php$ RewriteRule (.*\.php)?$ - [E=Cache-Control:max-age=120] </IfModule>  <IfModule the_web_server> RewriteCond %{REQUEST_METHOD} ^HEAD|GET$ RewriteCond %{HTTP_COOKIE} !page_contain_cachetoken=yes RewriteCond %{QUERY_STRING} !s=[a-fA-F0-9]{32} RewriteCond %{REQUEST_URI} !/(login|register|usercp|private|profile|cron|image)\.php$ RewriteRule (.*\.php)?$ - [L,E=Cache-Control:private] </IfModule>

These powerful rewrite rules can be implemented in several key locations:

  • Within the .htaccess file located in the site's document root.
  • In the virtual host section of the Apache configuration file.
  • Under the Configurations > Virtual Hosts > Rewrite section of the web administration console for native configurations.

Note: Any modifications made to the Apache configuration file necessitate a restart of the web server to take effect. This can be performed through the WebAdmin Console (Actions > Graceful Restart) or by executing /path/to/server/bin/lswsctrl restart or service the_web_server restart from the command line. However, if your changes are confined to the .htaccess file, a server restart is not required, as these changes are applied immediately.

Disabling Caching

For scenarios where caching needs to be explicitly disabled, a straightforward approach involves using rewrite rules independently. Below is a simple example demonstrating how to disable caching for all requests using this method:

<IfModule the_web_server> RewriteEngine On RewriteRule .* - [E=Cache-Control:no-cache] </IfModule>

This rule effectively instructs the caching system not to store any content for the specified pattern, ensuring that requests are always handled directly by the backend.

Combining Directives and Rewrite Rules

For more sophisticated caching requirements, a powerful strategy involves combining directives with rewrite rules. This approach allows for a highly granular control over caching behavior, enabling complex logic to be applied.

Consider the following example: the CacheDisable public / directive is initially used to turn off all public caching for the entire site. However, subsequently defined rewrite rules then specify that all content should be cached for a duration of two minutes. In this specific scenario, the CacheDisable directive effectively has no impact, as the rewrite rules take precedence and override its general instruction, demonstrating the hierarchy of these caching mechanisms.

<IfModule the_web_server> CacheDisable public / RewriteEngine On RewriteRule .* - [L,E=cache-control:max-age=120] </IfModule>

Usage Examples

Let's explore several practical examples that you can readily adapt and integrate into your own web applications to fine-tune caching behavior.

Cache Everything for Two Minutes

This example demonstrates how to specifically cache PHP files located within a directory named cacheablefolder. It highlights a best practice in caching strategies: target only those files that genuinely benefit from caching, rather than indiscriminately caching all files. This selective approach optimizes resource usage and ensures efficiency.

<IfModule the_web_server>   RewriteEngine On   RewriteRule cacheablefolder/(.*\.php)?$ - [E=cache-control:max-age=120] </IfModule>

Cache Pages That Have a Certain Signature

This example illustrates how the caching system's rewrite rules can be integrated with an existing application's rewrite rules. The second part of the example, taken from a typical application like Joomla!, shows how all requests are routed through a central index.php file for processing.

Public cache example:

# Caching system rules for public cache <IfModule the_web_server> RewriteEngine On RewriteCond %{REQUEST_METHOD} ^HEAD|GET$ RewriteCond %{HTTP_COOKIE} !cookiename  RewriteCond %{ORG_REQ_URI} !^/administrator RewriteRule .* - [E=Cache-Control:max-age=300] </IfModule>  # application's original rewrite rules RewriteEngine On RewriteCond %{REQUEST_URI} !^/index\.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.*) index.php [L]

The variable %{ORG_REQ_URI} is a specific server variable that retains the value of %{REQUEST_URI} before the application's rewrite directs it to index.php. In the caching system's portion of the ruleset, requests are only cached if they satisfy all of the following conditions:

  • The request method is either HEAD or GET.
  • The HTTP_COOKIE header does not contain cookiename.
  • The original request URI (%{ORG_REQ_URI}) does not begin with /administrator/.

Should all these conditions be met, the page will be cached for a duration of 300 seconds (equivalent to 5 minutes).

Now, let's consider a parallel set of rules designed for private caching:

Private cache example:

# Caching system rules for private cache <IfModule the_web_server> RewriteCond %{REQUEST_METHOD} ^HEAD|GET$ RewriteCond %{HTTP_COOKIE} loginuser RewriteCond %{ORG_REQ_URI} !^/index\.php$ RewriteRule .* - [E=Cache-Control:private] </IfModule>  RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} !^/index.php RewriteCond %{REQUEST_URI} (/|\.php|\.html|\.htm|\.feed|\.pdf|\.raw|/[^.]*)$  [NC] RewriteRule (.*) index.php [L]

This ruleset dictates that the caching system will only privately cache requests if they meet every one of the following criteria:

  • The request method is either HEAD or GET.
  • The HTTP_COOKIE header contains loginuser.
  • The original request URI (%{ORG_REQ_URI}) is not /index.php.
  • The original request URI (%{ORG_REQ_URI}) ends with extensions such as .php, .html, .htm, etc.

If all these conditions are satisfied, the page is then stored in the private cache, ensuring personalized content delivery for logged-in users or specific user sessions.

Enable Cache for Mobile View

This example illustrates how to configure cache variations based on the %{HTTP_USER_AGENT} variable using rewrite rules. This technique is particularly useful for serving optimized content to different device types, such as mobile and desktop users.

<IfModule the_web_server> RewriteEngine On CacheDisable public / RewriteCond %{HTTP_USER_AGENT} "iPhone|iPod|BlackBerry|Palm|Mobile|Opera Mini|Fennec|Windows Phone" RewriteRule .* - [E=Cache-Control:vary=ismobile] RewriteCond %{REQUEST_METHOD} ^HEAD|PURGE|GET$ RewriteCond %{ORG_REQ_URI} !/news RewriteCond %{ORG_REQ_URI} !/admincp RewriteRule .* - [E=Cache-Control:max-age=120] </IfModule>

The configuration begins by explicitly disabling public caching by default through the CacheDisable public / directive. Following this, caching is selectively re-enabled for requests that fulfill all specified conditions:

  • The request method must be either HEAD or GET.
  • The original request URI (%{ORG_REQ_URI}) must not be /news or /admincp.

Furthermore, if a mobile user agent is detected, the ismobile vary value is set. This vary value is critical for enabling the storage and retrieval of multiple cache copies for a single URL. Consequently, this setup allows for one public cache copy of the page to be served to users on mobile devices, while a separate public cache copy is provided to all other users, ensuring an appropriate experience for each audience.

Important: It is imperative that your rewrite rules for mobile detection precisely align with your application's backend mobile detection logic. A mismatch can lead to scenarios where the rewrite rules incorrectly classify a device as mobile (or vice-versa), resulting in the desktop version of a page being cached and erroneously flagged as the mobile version. This misconfiguration can then cause the wrong content to be served to mobile viewers, degrading the user experience.

Instructions for Specific Applications

Beyond the general configuration guidelines provided, this section offers tailored suggestions for optimizing caching with several popular web applications. These configurations aim to enhance performance specific to each platform.

Tip: For the most precise and effective caching control, utilizing dedicated plugins is highly recommended. If a caching plugin is available for your web application, we strongly advise integrating it, as it can often provide deeper and more accurate cache management than manual configurations alone.

Joomla!

Note: While a dedicated Joomla! plugin exists for versions 3.0 and above, the following instructions are specifically tailored for earlier Joomla! versions, where direct plugin integration might not be applicable.

For Joomla! installations, rewrite rules should be inserted into your .htaccess file, situated within your website's document root. It is best practice to place these server rules immediately before the line indicating the start of Joomla!'s core SEF (Search Engine Friendly) section: ## Begin - Joomla! core SEF Section.

Example 1:

<IfModule the_web_server>   RewriteEngine On   CacheDisable public /   RewriteCond %{REQUEST_METHOD} ^HEAD|GET$   RewriteCond %{ORG_REQ_URI} !/administrator   RewriteRule .* - [E=Cache-Control:max-age=120] </IfModule>

In this first example, the configuration is set to cache all non-administrative URLs for a duration of two minutes. The CacheDisable public / directive is an optional but recommended measure to safeguard against inadvertently enabling global caching. Ideally, you should verify the server's overarching cache settings to ensure that caching is not broadly active. It is generally advisable to disable all caching by default and then selectively enable it only for the URLs that require it, rather than broadly enabling and then disabling.

Example 2:

<IfModule the_web_server>   RewriteEngine On   CacheEnable public /   RewriteCond %{REQUEST_METHOD} ^HEAD|GET$   RewriteCond %{ORG_REQ_URI} /administrator/   RewriteRule .* - [E=Cache-Control:no-cache] </IfModule>

This second example takes an inverse approach to Example 1. Here, public caching is broadly enabled across the site, with specific rules then dictating that caching should be explicitly disabled for pages within the /administrator path. It's important to note that when using this method, a max-age cannot be specified, meaning pages will be cached for the duration defined by the server or virtual host's global cache policy.

Example 3:

<IfModule the_web_server>  RewriteEngine On  RewriteCond %{REQUEST_METHOD} ^HEAD|GET$  RewriteCond %{HTTP_HOST} ^domain.com [NC] [OR]  RewriteCond %{HTTP_HOST} ^www.domain.com [NC]  RewriteCond %{ORG_REQ_URI} !/administrator  RewriteRule .* - [E=Cache-Control:max-age=120] </IfModule>

For enhanced workflow and to prevent caching issues, it is advisable to use a distinct domain for your administrative backend. This separation allows you to manage, edit, or preview website content through the admin domain without the risk of these changes being cached and prematurely displayed to public visitors. For instance, you might configure admin.domain.com for internal administrative use, while domain.com and www.domain.com serve the general public. Example 3 illustrates how to precisely specify which domains should be included in the caching mechanism. In this setup, only domain.com and www.domain.com are targeted for caching, while admin.domain.com is explicitly excluded. This example assumes that caching has already been disabled at the server and virtual host levels as a default, aligning with recommended best practices.

Drupal

Note: While a dedicated Drupal plugin is available for version 8.x, the following configuration guidelines are specifically applicable to other Drupal versions, where a plugin might not be the primary caching solution.

For Drupal installations, rewrite rules should be inserted into your .htaccess file, situated within your website's document root. These server rules should be added immediately after the standard Drupal rewrite rules.

Example:

<IfModule the_web_server>   CacheDisable public /   RewriteEngine On     RewriteCond %{REQUEST_METHOD} ^GET|HEAD|PURGE$   RewriteCond %{HTTP_HOST} ^(www.)?domain.com [NC]   RewriteCond %{REQUEST_URI} !admin|register|login [NC]   RewriteCond %{HTTP_COOKIE} !SESS [NC]   RewriteCond %{QUERY_STRING} !nocache   RewriteRule .* - [E=Cache-Control:max-age=120] </IfModule>

It is important to understand that the CacheDisable public / directive is included as a precautionary measure to counteract any globally enabled caching, and its use is optional. Best practice suggests reviewing your server's global cache settings to confirm that caching is not broadly active. It is generally more effective to disable caching by default and then precisely enable it for the URLs that specifically require it, rather than attempting to disable it after a broad enablement. This method prevents unintended caching of administrative or dynamic content.

Similar to Joomla!, we highly recommend setting up a distinct domain for your administrative backend. This strategy allows you to perform content additions, edits, or previews through the admin domain without the concern of these changes being cached and immediately visible to public visitors. For instance, an arrangement could involve admin.domain.com for administrators and domain.com or www.domain.com for the general audience.

Tip: To access a non-cached version of a page, you can simply append the ?nocache query string to the URL. For example, both https://www.domain.com/about?nocache and https://www.domain.com/about?some_other_query_string&nocache will bypass the cache, ensuring you receive the most current content.

Concrete5

Implementing caching for a Concrete5 site presents a unique challenge due to the absence of a distinct administrative directory. Consequently, when the site is cached for public visitors, the same cached content may inadvertently be served for administrative functions and during development, which is generally undesirable.

A practical solution to this involves establishing a dedicated subdomain for administrative tasks. This subdomain should be configured to share the same document root as the main site's domain (e.g., public_html), and then explicitly excluded from caching within the .htaccess file. This setup effectively provides two distinct access points to the identical site content: www.domain.com for viewing cached content, and admin.domain.com for accessing uncached content to perform administrative work. Both domains point to the same physical location, but their caching behaviors are differentiated.

Rewrite rules for Concrete5 should be integrated into your .htaccess file, located in the website's document root. This typically involves two sets of rules: one to activate caching for the primary public domains, and another to specifically exclude the administrative subdomain from caching.

Example:

<IfModule the_web_server> RewriteEngine On RewriteCond %{REQUEST_METHOD} ^HEAD|GET$ RewriteCond %{HTTP_HOST} ^domain.com [NC] [OR] RewriteCond %{HTTP_HOST} ^www.domain.com [NC] RewriteRule .* - [E=Cache-Control:max-age=120]  RewriteCond %{REQUEST_METHOD} ^HEAD|GET$ RewriteCond %{HTTP_HOST} ^admin.domain.com$ [NC] RewriteRule .* - [E=Cache-Control:no-cache] </IfModule>

Tip: Given the dual-domain setup for main and admin access, it is highly beneficial for SEO purposes to prevent search engines like Google from indexing the administrative domain. Failing to do so could result in penalties for duplicate content, negatively impacting your site's search engine ranking. Ensure your robots.txt file or meta tags properly disallow indexing of the admin subdomain.