Speed up the Drupal backend with $settings['state_cache']
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
- Run the SQL check above.
- Trim any oversized values from
state
. - On Drupal 10.3 to 10.x, add
$settings['state_cache'] = TRUE;
and clear caches. - 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.