Disabling and debugging caching

Last updated on
5 November 2025

This documentation needs review. See "Help improve this page" in the sidebar.

Disabling caching (render cache, dynamic page cache, Twig cache) during development is useful for seeing changes without clearing the cache.

Accessing the site as an anonymous user still makes use of caching even when local development settings have been enabled. You must be logged in to view your site with caches disabled.

Disable Twig Caching

Drupal 10.1.0 introduced a new "Development settings" page at /admin/config/development/settings that contains Twig development settings, as well as the ability to disable various caches.

Screenshot of form with Twig development settings checkboxes checked.

The settings are stored as raw key-value pairs in the key_value table—rather than as configuration, see #3437162: Move twig_debug and other development toggles into raw key/value—so the settings cannot be accidentally committed and uploaded to production environments.

The settings available are

  • Twig development mode - This checkbox exposes two Twig development checkboxes and checks them by default.
     
    • Twig debug mode - This enables Twig debug, which provides the dump() function; outputs template suggestions to HTML comments in page source; and enables Twig auto-reload, which tells Twig to reload any templates that have been modified by the developer.
    • Disable Twig cache - This completely disables the Twig cache.
  • Do not cache markup - This disables the render cache, dynamic page cache, and page cache.

From Twig debugging / caching settings added to administrative user interface. See also Mike Herchel's blog post.

Toggle Twig debug, caching and CSS/JS aggregation with Drush

The easiest method to enable Twig debugging, turn off caching and CSS/JavaScript aggregation and clear caches is with the theme:dev Drush command, added in Drush 13.6:

  • drush theme:dev on
    Disables caching, CSS/JS aggregation and enables Twig debugging.

  • drush theme:dev off
    Enables caching, CSS/JS aggregation and disables Twig debugging.

When enabled:

  • Disables render cache, dynamic page cache, and page cache.
  • Enables Twig debug mode (e.g., dump() function, template suggestions).
  • Disables Twig cache (templates always recompiled).
  • Disables CSS and JS aggregation.
  • Clears all caches.

See also the Drush theme:dev command documentation page.

Drush 13 requires PHP 8.3 or higher.

To use the same functionality on lower PHP versions, refer: Custom Drush command for managing Twig debugging and CSS/JS aggregation

Disable CSS and JS aggregation

Turning off Aggregate CSS and JavaScript files under /admin/config/development/performance can help you find the right files.

The safest method is via the settings.php file, to avoid accidentally committing it:

$config['system.performance']['css']['preprocess'] = FALSE;
$config['system.performance']['js']['preprocess'] = FALSE;

... or disable with Drush, which is the same as via the Performance form:

drush config:set system.performance js.preprocess 0 -y
drush config:set system.performance css.preprocess 0 -y

To make sure aggregation is always enabled on your live server, add this to settings.php:

$config['system.performance']['css']['preprocess'] = TRUE;
$config['system.performance']['js']['preprocess'] = TRUE;

Enable render cache debugging

The renderer can be configured to add debugging output for each rendered element. This makes it easier to see the cacheability of each rendered element.

You can debug render cache by setting the debug container parameter to true under renderer.config in your services.yml or development.services.yml file:

parameters:
  renderer.config:
    required_cache_contexts: ['languages:language_interface', 'theme', 'user.permissions']
    auto_placeholder_conditions:
      max-age: 0
      contexts: ['session', 'user']
      tags: []
    debug: true

With debugging enabled, each rendered element will be wrapped with HTML comments:

<!-- START RENDERER -->
<!-- CACHE-HIT: No -->
<!-- CACHE TAGS:
   * node:1
   * node_view
   * user:1
   * user_view
-->
<!-- CACHE CONTEXTS:
   * languages:language_interface
   * theme
   * timezone
   * url.site
   * user.permissions
   * user.roles
   * user.roles:anonymous
   * user.roles:authenticated
-->
<!-- CACHE KEYS:
   * entity_view
   * node
   * 1
   * full
-->
<!-- CACHE MAX-AGE: -1 -->
<!-- PRE-BUBBLING CACHE TAGS:
   * node_view
   * node:1
-->
<!-- PRE-BUBBLING CACHE CONTEXTS:
   * url.site
   * languages:language_interface
   * theme
   * user.permissions
-->
<!-- PRE-BUBBLING CACHE KEYS:
   * entity_view
   * node
   * 1
   * full
-->
<!-- PRE-BUBBLING CACHE MAX-AGE: -1 -->
<!-- RENDERING TIME: 1.039412022 -->

Disable Twig cache manually, "the old way"

For Drupal 10.2 and older

This method is not recommended for sites using version 10.3 or newer because the settings in a services.yml file would take precedence over settings in the admin UI, making it impossible to change debug settings in the browser.

Load local development settings

Include the local settings file as part of Drupal's settings file.

Copy sites/example.settings.local.php to sites/default/settings.local.php:

$ cp sites/example.settings.local.php sites/default/settings.local.php

Open settings.php file in sites/default and uncomment these lines:

if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
  include $app_root . '/' . $site_path . '/settings.local.php';
}

Configure development.services.yml

The development.services.yml file is located under /sites.

Your final development.services.yml should look as follows (mind the indentation):

# Local development services.
#
# To activate this feature, follow the instructions at the top of the
# 'example.settings.local.php' file, which sits next to this file.
parameters:
  http.response.debug_cacheability_headers: true
  twig.config:
    debug: true
    auto_reload: true
    cache: false
services:
  cache.backend.null:
    class: Drupal\Core\Cache\NullBackendFactory

Twig cache: We added a twig.config section in the development.services.yml disabling the cache.

Open settings.local.php and make sure development.services.yml is enabled.

$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/development.services.yml';

Beware of scaffolding

Depending on your composer.json, development.services.yml may be overwritten from during scaffolding. To prevent certain scaffold files from being overwritten every time you run a Composer command you need to specify them one by one in the "extra" section of your project's composer.json. See the docs on Excluding scaffold files.

The following snippet prevents the development.services.yml from being regularly overwritten:

"drupal-scaffold": {
    "locations": {
        "web-root": "web/"
    },
    "file-mapping": {
        "[web-root]/sites/development.services.yml": false
    }
},

Configure settings.local.php

Change the following to be TRUE if you want to work with enabled css- and js-aggregation:

$config['system.performance']['css']['preprocess'] = FALSE;
$config['system.performance']['js']['preprocess'] = FALSE;

Uncomment these lines to disable the Render Cache, disable the Internal Page Cache and disable Dynamic Page Cache:

$settings['cache']['bins']['render'] = 'cache.backend.null';
$settings['cache']['bins']['page'] = 'cache.backend.null';
$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';

If you do not want to install test modules and themes, set the following to FALSE:

$settings['extension_discovery_scan_tests'] = FALSE;

Rebuild cache

Rebuild the Drupal cache, otherwise your website will encounter an unexpected error on page reload. This can be done with Drush:

drush cache:rebuild

Or via the alias: 

drush cr

... or by visiting the following URL from your website:

https://example.org/core/rebuild.php

Other solutions and tips

Disable Browser cache

After implementing all of the above, are you still clearing the cache to see changes? Browsers do their own caching, which is getting more aggressive, and CSS changes may not be reflected on refresh. Try disabling browser cache:

Open Developer Tools (F12) --> Network --> Disable Cache (toggle).

Tested in Chrome, Firefox and Brave.

Use Mix module

You can install the Mix module, and switch between Dev/Prod mode by toggling the "Enable development mode" checkbox.

Find cache bins

To find all available (but not necessarily enabled) cache bins:

find . -type f -name *.services.yml | \
xargs sed -E -n 's/.*cache\.(.*):.*/\1/p' | \
grep -v "backend\|html.twig" | \
sort -u | \
awk -vORS=\',\' '{ print $1 }' | \
sed "s/,'$//" | sed "s/^/'/"

Note that in MacOS you might need to install and run 'gawk' instead of 'awk' in order for the above command to work. You can use brew to install gawk:

brew install gawk

Alternate option to find the list of cache bins:

SELECT TABLE_NAME, SUM(TABLE_ROWS) as rows_count FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbname' AND TABLE_NAME like 'cache_%' group by table_name order by rows_count DESC Limit 50;

Then you could copy/paste it into your settings.php file and disable caching like this:

$cache_bins = ['access_policy', 'advagg', 'bootstrap', 'cachetags', 'config', 'container', 'data', 'default', 'discovery', 'discovery_migration', 'dynamic_page_cache', 'entity', 'jsonapi_memory', 'jsonapi_normalizations', 'jsonapi_resource_types', 'menu', 'migrate', 'page', 'render', 'rest', 'static', 'toolbar'];

foreach ($cache_bins as $bin) {
  $settings['cache']['bins'][$bin] = 'cache.backend.null';
}

Note: The cache bins in your Drupal project may differ depending on the modules that are installed, as each module can introduce or modify specific cache bins.

Alternative: develop with caching enabled

Disabling caching has some drawbacks. Site response time will be slower, and rebuilding all caches takes a while too. When done frequently, all those seconds waiting for a response add up. For an approach to developing with the cache enabled, see Drupal 8 development with caching on.

Sendfile Settings

Sometimes local installed environments will have Sendfile enable in their server configuration. Sendfile is used by the server to cache static files, and can greatly improve performance on production environments. However, during development, this can cause CSS and Javascript files to be served from the cache, rather than a fresh copy. You can set Sendfile to off, depending on the environment's web server (Apache or Nginx).

Apache requires an update in the httpd.conf (or sometimes apache.conf)
EnableSendfile off
Nginx requires an update in the nginx.conf
sendfile off

PHP OpCode Caches

Sometimes your latest changes within your PHP files might not be reflected on your webpage due to caches via PHP extensions. One popular PHP code cache is the PHP OpCode extension. Drupal recommends you to enable the PHP OpCode extension for faster code execution. However, it can sometimes be confusing when you want to see the latest changes in your PHP code reflected in your browser or any command line script (e.g. Drush command). So if you are unsure about your code execution during your development process, disabling or configuring the PHP OpCode extension might be a solution. Be aware that the PHP OpCode extension isn't mostly the reason for caches in your development process. Read more about PHP OpCode caches in the following blog article: PHP Performance I: Everything You Need to Know About OpCode Caches.

Help improve this page

Page status: Needs review

You can: