Change record status: 
Project: 
Introduced in branch: 
8.4.x
Introduced in version: 
8.4.0
Description: 

To keep Drupal simple to install, with simple system requirements, Drupal uses the database not only for storing content, but also for caching.

A database is not designed for caching though. A cache is by definition (see https://en.wikipedia.org/wiki/Cache_(computing)) a fixed-size storage. When it's full, data is evicted (there are many ways to choose which cache items should be evicted).

However, Drupal's database-based caching has traditionally not imposed any limitations. In Drupal 7, many actions cleared all caches (thus making caching far less effective). And many things were uncacheable due to lacking infrastructure. Those flaws have fortunately been fixed in Drupal 8, but now there's another consequence: cache bins in the database can grow to excessive sizes — many tens of thousands of entries (even hundreds of thousands), and gigabytes in size!

To curtail this, we introduced limitations. During cron runs, stale cache items are already purged. But as of now, we also limit the number of cache items in each database cache bin table to at most 5,000 rows by default.

You can override this default in settings.php, for example to 50,000:

$settings['database_cache_max_rows']['default'] = 50000;

And you can even override it for a particular cache bin in settings.php, for example to 500:

$settings['database_cache_max_rows']['bins']['config'] = 500;

To see the current size of cache tables, you can use a query like the following:

SELECT table_name AS 'Table', TABLE_ROWS as 'Num. of Rows', round(((data_length + index_length) / 1024 / 1024), 2) 'Size in MB'  FROM information_schema.TABLES where table_schema = '***DATABASE_NAME***' and table_name LIKE 'cache_%'  ORDER BY (data_length + index_length) DESC limit 10;

Note: Replace ***DATABASE_NAME*** with your actual database name, for example drupal9.

#2896473: Add monitoring/reporting of cache table pruning might add reporting about that directly into the UI from Drupal in the future.

Impacts: 
Site builders, administrators, editors
Module developers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Not done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Other updates done

Comments

mxh’s picture

For unlimited cache growth, you can use the value -1, e.g. for the page cache $settings['database_cache_max_rows']['bins']['page'] = -1;

stsharp’s picture

We do not want unlimited cache growth. Our cache is growing at half a gig a day on a single simple site. We want to keep the database cache down below a few hundred MB

ethelburga’s picture

Given that most hosting companies set maximum limits on cache sizes, (it's 1Gb on siteground) the defaults need to be lowered.

tcibah’s picture

Hello,

I have added following line to settings.php of a Drupal 8.8.5 site in order to limit cache_page table size:
$settings['database_cache_max_rows']['bins']['page'] = 1000;

It did not work the cache_page is growing as before, already passed 2000 in less than two hours and that seems to keep a heavy constant load on cpu usage.

Also tried earlier to limit size of all cache tables using:
$settings['database_cache_max_rows']['default'] = 500;

It also did not work.

Are those settings still valid in Drupal 8.8.5?

Are there any other workarounds? Thanks

GiorgosK’s picture

@tcibah this settings take effect on cron run, did you check that you cron runs properly ?

------
GiorgosK
Web Development

jastraat’s picture

Edit: if you are testing this functionality locally, make sure you haven't disabled the backend cache in your settings file. That was the reason that cron was not emptying the tables during system_cron in our case.

Shenron_segamag’s picture

Hi, I have tried these settings :

$settings['database_cache_max_rows']['bins']['dynamic_page_cache'] = 2000;
  $settings['database_cache_max_rows']['bins']['render'] = 10000;

Doesn't work for me either, even after cron.

Stephen Ollman’s picture

Can you please clarify what you mean by "make sure you haven't disabled the backend cache in your settings file".

I've also tried these settings and ran CRON several time, but the rows keep increasing above the set limit.

Am running core 8.9.18

Certified Drupal Site Builder 7 & 8

pbattino’s picture

I don't know if it's intentional or not, but the underscore in the query
...LIKE 'cache_%'...
is a special character, it stands for "any character". Result: that query matches also the table "cachetags" , that does not have an underscore in the name.
Is it intentional? If the idea is to match only tables starting with 'cache_', the query should probably escape the underscore:

SELECT table_name AS `Table`, TABLE_ROWS as 'Num. of Rows', round(((data_length + index_length) / 1024 / 1024), 2) `Size in MB`  FROM information_schema.TABLES where table_schema = '***DATABASE_NAME***' and table_name LIKE 'cache\_%'  ORDER BY (data_length + index_length) DESC limit 10;
'
GiorgosK’s picture

I think this type of issue/question it is better created in the drupal/core issue queue https://www.drupal.org/project/issues/drupal

------
GiorgosK
Web Development