Back to Blog

Speed up the Drupal backend with $settings['state_cache']

2025-08-136 min read

On a large Gov Drupal site I work on, /admin/reports/status and /admin/config were slow. After enabling $settings['state_cache'], the pages loaded much faster. Editors noticed immediately.

If your admin area feels slow, this may help. Drupal makes many small State API reads per request, and caching them cuts database trips. In Drupal 10.3 you can turn it on with $settings['state_cache'] = TRUE in settings.php. In Drupal 11 state caching is always on and the setting has been removed. If your site stores a large number of big items in State, review that first before enabling it in 10.3.

What the State API stores

Drupal keeps small, site specific values in a key value collection named state. Examples: last cron time, maintenance flags, helper toggles used by core and modules. Without caching, every read can hit the database.

Why state_cache helps

Admin screens do a lot of tiny checks. Caching these values removes many database calls. The result is quicker pages and lower database load. Simple change, clear win.

Availability

  • Drupal 10.3+: opt in with $settings['state_cache'].
  • Drupal 11+: on by default; the setting was removed.

How it works

Drupal loads a value once, stores it in cache, and reuses it on later requests. When a value changes, Drupal updates storage and invalidates the cache entry. Reads stay fast and data stays correct.

Enable in Drupal 10.3+

Add this to settings.php:

$settings['state_cache'] = TRUE;

Then clear caches.

Quick check before you enable

If your site keeps too many or too large values in state, caching them can waste memory. Run this query:

SELECT COUNT(*) AS num_items,
       SUM(LENGTH(value)) AS total_bytes
FROM key_value
WHERE collection = 'state';

You can run the same with Drush:

drush sql:query "SELECT COUNT(*) AS num_items, SUM(LENGTH(value)) AS total_bytes FROM key_value WHERE collection = 'state';"

PostgreSQL:

drush sql:query "SELECT COUNT(*) AS num_items, SUM(OCTET_LENGTH(value)) AS total_bytes FROM key_value WHERE collection = 'state';"

Rules of thumb:

  • num_items up to about 100 and total_bytes around 100 KB is usually fine.
  • If you see large blobs, move them elsewhere (a cache bin, config, or a custom table) before enabling.

Problems this can ease

  • Slow admin pages after log in.
  • High database load during editorial work, batch runs, or heavy cron usage.
  • Latency spikes on shared database servers.

If your cache backend is the database

Yes, it still helps. You will do fewer reads from key_value. Admin pages may load faster. But reads still hit the database, so gains are smaller than with Redis or Memcached. It is safe to enable now and plan a move to an in memory cache later.

Good pairings

  • Redis or Memcached for cache storage so state hits live in memory. Check your cache backend in settings.php and watch hit ratios.
  • Keep state small. Use it for flags and lightweight values, not big blobs.
  • Measure before and after. Locally, try Webprofiler or Devel to compare query counts. In production, use your APM.

Caveats

  • Very large state values can bloat cache. Fix the data first, then enable.
  • Cache clears do not delete state values; they only invalidate cached copies.
  • On Drupal 11, there is nothing to configure. You already get the gain.

Short checklist

  1. Run the SQL check above.
  2. Trim any oversized values from state.
  3. On Drupal 10.3 to 10.x, add $settings['state_cache'] = TRUE; and clear caches.
  4. Confirm fewer queries on admin pages and watch database load drop.

Bottom line

Small change. Noticeable lift for editors. Turn it on, test, and enjoy snappier admin pages.