Problem/Motivation
The Redis report at admin/reports/redis analyses cache variations for the render bin only (line 121 of ReportController.php). The data bin (used by Drupal's dynamic_page_cache) is counted in "Keys per cache bin" but never analysed for variation patterns.
This blind spot can hide a critical Redis memory issue: when a page embeds a View or Facets block without max-age = 0, the url.query_args cache context bubbles up to the page level, creating one data bin entry per unique URL including every query parameter combination. On sites with faceted search (e.g. recipe or product listing pages), this leads to hundreds of thousands of Redis keys accumulating with long TTLs, filling Redis memory until the allkeys-lru eviction policy starts evicting cache tag checksum keys — causing a cascading cache miss rate increase and potential site outage.
This issue was discovered in a real production incident where 394,443 keys matching *data:route*query_parameters*recipes* and 595,589 keys total with query_parameters context were consuming ~86% of available Redis memory (3.46 GB / 4 GB). The render cache report showed nothing unusual because the problem was entirely in the data bin.
Steps to reproduce
- Install a Drupal site with the Redis module, Search API, Views, and Facets.
- Create a View embedded in a page (e.g. taxonomy term) using the
url.query_argscache context (e.g. viaviews_embed_view()inside an ExtraField or Block plugin) without settingmax-age = 0on the parent render element. - Visit multiple URLs with different query parameter combinations (e.g.
/recipes?f[0]=diet:vegan,/recipes?f[0]=diet:vegan&f[1]=time:30min, etc.). - Visit
admin/reports/redis. - Observe that "Render cache entries with most variations" shows nothing related to these pages, despite each URL creating a separate Redis key in the
databin.
Proposed resolution
Extend the scan loop in ReportController::overview() to also analyse the data bin, applying the same variation-detection logic already used for the render bin. Keys in the data bin containing query_parameters in their cache ID are grouped by URL path (extracted
from the last segment of the cache key) and counted.
A new "Dynamic page cache entries with most variations (query_parameters)" section is added to the report output, with severity levels:
- Warning when any URL exceeds 1,000 variations.
- Error when any URL exceeds 10,000 variations, with a description pointing to the likely cause (missing
max-age = 0on ExtraField or Block plugins embedding Views with facets).
Remaining tasks
- Add tests.
- Review whether other bins (e.g.
page) should receive the same treatment. - Consider whether the scan cap mentioned in the existing
@todo(line 154) should be enforced to prevent timeouts on large Redis instances.
User interface changes
A new row "Dynamic page cache entries with most variations (query_parameters)" is added to the admin/reports/redis status report, showing the top 50 URLs by number of cached query parameter variations and the cache contexts responsible. The row displays a warning or error severity when thresholds are exceeded.
API changes
None.
Data model changes
None.
Comments
Comment #2
eduardo morales albertiComment #3
eduardo morales alberti