Drupal is a registered trademark of Dries Buytaert
Protected Pages 3.0.0 Major update available for module protected_pages (3.0.0). Commerce Core 3.3.8 Minor update available for module commerce (3.3.8). Search API HTML Element Filter 1.0.7 Minor update available for module search_api_html_element_filter (1.0.7). Layout Builder Reorder 2.0.1 Minor update available for module layout_builder_reorder (2.0.1). Ban 1.1.0 Minor update available for module ban (1.1.0). Field Formatter Range 2.0.0 Major update available for module field_formatter_range (2.0.0). Field Formatter Range 8.x-1.8 Minor update available for module field_formatter_range (8.x-1.8). UI Patterns (SDC in Drupal UI) 2.0.18 Minor update available for module ui_patterns (2.0.18). Search API Solr 4.3.11 Module search_api_solr updated after 14 months of inactivity (4.3.11). Provus Mega Menu Module provus_mega_menu crossed 1,000 active installs.

Cache Register

11 sites Security covered
View on drupal.org

Cache Register simplifies caching custom data by organizing cache entries into named "Drawers," "Slots," and "Registers." This system reduces boilerplate code and helps developers avoid manually managing cache IDs. It provides an intuitive API for setting, retrieving, and invalidating cached data.

Tired of looking up tutorials or parsing old code every time you need to cache some arbitrary data? Not sure how to name your cache entries? Cache Register to the rescue! Cache Register aims to simplify the developer experience of caching custom data.

Cache Register introduces the concept of Drawers, Slots, and Registers to help keep your cache entries organized and manageable. Let's say you hit an API for a batch of users and want to cache that information. Here's how you'd do it.

// ==================================
// Cache your data
// ==================================
$manager = \Drupal::service('cache_register.manager');
$user = \Drupal::entityTypeManager->getStorage('user')->load(1337);
$slot = $manager->openSlot('my_module', 'some_api', $user->id());

if (!$slot->isCached() { 
  $api_data = some_api_request($user->id());
  $slot->setCache($api_data);
  $slot->addCacheTags($user->getCacheTags());
  // or optionally provide cache expiry and cache tags as normal
  $slot->setCache($data, strtotime('+7 days'), $user->getCacheTags());
} 

// ==================================
// Retrieve your data from anywhere
// ==================================
$slot = $manager->openSlot('my_module', 'some_api', $uid);
$data = $user_slot->getCacheData();

// ==================================
// Invalidate/delete the cache
// ==================================
$slot->invalidateCache();
$slot->deleteCache();

// or to invalidate all cache entries associated with a drawer
$drawer = $manager->openDrawer('my_module', 'some_api')->invalidate();

How it works

It's important to note that drawers and slots do not actually "exist" in the cache -- they just provide wrappers for interacting with a specific cache entry without so much boilerplate. It helps to stop needing to add so much boilerplate to classes like this to define your cache interactions, and to avoid passing around/keeping track of $cid variables.

// This
$slot = $manager->openSlot('my_module', 'some_api', $uid);
if(!$slot->isCached()) {
  $slot->setCache($some_data, strtotime('+1day'), $user->getCacheTags());
  $slot->addCacheTags($node->getCacheTags());
}

// is like doing
$cid = "my_module.some_api:$uid";
if(!$this->cache->get($cid)) {
  $this->cache->set($cid, $some_data, strtotime('+1day'), $user->getCacheTags());
  $cache_item = $this->cache->get("my_module.some_api:$uid");
  $existing_tags = $cache_item->tags;
  $all_tags = Cache::mergeTags($existing_tags, $node->getCacheTags());
  $this->cache->set($cid, $cache_item->data, $cache_item->expiry, $all_tags);
}

Cache Bins

Cache Register does not replace cache bins. On the contrary, it can be effectively used alongside them. PCB provides a so-called permanent cache bin to allow data to persist regular cache clears. Cache Register can interact with this or any other cache bins by injecting them into a custom service like:

// In my_module.services.yaml
cache.my_module_pcb:
  class: Drupal\Core\Cache\CacheBackendInterface
  tags:
    - { name: cache.bin, default_backend: cache.backend.permanent_database }
  factory: cache_factory:get
  arguments: [ my_module_pcb ]

my_module.cache_manager:
  class: Drupal\cache_register\Manager
  arguments: [ '@cache.my_module_pcb' ]

my_module.some_service:
  class: Drupal\my_module\Service\SomeService
  arguments:
    - '@my_module.cache_manager'

// Then in my_module.some_service, invoke as normal
$this->cacheManager->openSlot(...);

Shameless Self Promotion

A list of modules that I maintain:

  • Cache Register: A module aimed at improving developer quality of life surrounding caching.
  • Enum Generator: A developer utility that generates enums and class constants from a site's entities.
  • Views Hooks Extras: Extends Views' native hooks to more specifically target particular views and their displays
  • Media Entity Remote Image: Provides a simple media type + field for remote image urls

Activity

Total releases
5
First release
Jan 2026
Latest release
5 months ago
Releases (12 mo)
5 ▲ from 0
Maintenance
Active

Release Timeline

Releases

Version Type Release date
1.1.x-dev Dev Jan 26, 2026
1.1.1 Stable Jan 26, 2026
1.1.0 Stable Jan 26, 2026
1.0.4 Stable Jan 23, 2026
1.0.3 Stable Jan 23, 2026