Drupal - Cache Form table size is enormous

The {cache_form} table is a little funny, and behaves in a slightly different manner than other cache tables.

If you take a look at drupal_flush_all_caches() you will see that {cache_form} isn't cleared. This is to protect in-progress forms from being nuked.

The system_cron() function does take care of pruning out old data from {cache_form} along with the other cache tables.

You really should run cron on all Drupal sites. If you {cache_form} table is ginourmous, then I bet your {watchdog} and {session} tables are, too. Many other modules run housekeeping activity as part of their own hook_cron() functions.

You may also want to poke around the issue queue. There have been some bugs with {cache_form}, and you may be running into one.


Thumb Rule: Cron should be run regularly for the housekeeping of your website.

You mentioned in your comment to MPD that in-spite of setting up the cron and running them regularly your cache_form table is growing up quickly.

One solution to that is to run your cron more frequently. Say every six hours or lesser? If you cannot afford to do it read further.

Alternate Solution :

mymodule_cron() {
    cache_clear_all(NULL, 'cache_form');
}

Install Elysia Cron and now you can run the cron function of your module separately. You can keep the frequency of the Elysia cron for you module to run every six hours. So that your cache_form table is pruned every six hours.

During this pruning process the entries which are not older than 6 hours will not be deleted. The reason being, if all the entries are deleted then any forms which are being submitted at the time of deleting the entries can behave weirdly.

Look at the code in https://api.drupal.org/api/drupal/includes!form.inc/function/form_set_cache/7

function form_set_cache($form_build_id, $form, $form_state) {
  // 6 hours cache life time for forms should be plenty.
  $expire = 21600;

As the comment reads they are assuming it should be plenty and in your case it is becoming too plenty for you. So the trick is to either clear the cache_form table more frequently and reduce the value of $expire to a lower value, if you want to clear the cache_form entries more frequently than the default value of 6 six hours then you need to alter the TTL of the cache_form entries.

You can do that by installing cacheboject and then implementing the hook_cacheobject_presave within which you can alter the TTL to may be 2 or 3 hours.

mymodule_cacheobject_presave()($object, $cid, $bin) {
  // Extend the expiry period for prototype forms used in ajax enabled forms.                                                                  
  $cache_ttl = 1 ; // Change it to any number of hours
  if ($bin == 'cache_form') {
    $object->expire = REQUEST_TIME + $cache_ttl * 3600;
  }
}

One downside of this approach is if the forms are not submitted within 2 hours(the RTL value you set) the the form data can be lost and you might get some form expired issues.