New in Symfony 7.3: Namespaced Caches


Contributed by
Nicolas Grekas
in
#59813

Namespace-based cache invalidation is a technique where cache keys are grouped
under a logical namespace (e.g. per user, locale, or entity). Instead of deleting
individual keys, you invalidate the entire namespace, effectively removing all
related entries at once.
In Symfony 7.3, we're adding namespace-based cache invalidation to all cache
adapters in the Cache component. This is implemented via the new
Symfony\Contracts\Cache\NamespacedPoolInterface, which defines the
withSubNamespace() method:

$subCache = $cache->withSubNamespace('foo');

$subCache->get('my_cache_key', function (ItemInterface $item): string {
$item->expiresAfter(3600);

return '...';
});

In this example, the cache item uses the my_cache_key key, but it's stored
internally under the foo namespace. This is handled transparently, so you
don't need to manually prefix keys like foo.my_cache_key. In practice,
this groups cache items logically into different sets:

$subCache = $cache->withSubNamespace('foo');

$bar1 = $cache->getItem('bar1');
$bar1->set(...); $cache->save();

$bar2 = $subCache->getItem('bar2');
$bar2->set(...); $subCache->save();

$cache->getItem('bar1')->isHit(); // true
$cache->getItem('bar2')->isHit(); // false
$subCache->getItem('bar1')->isHit(); // false
$subCache->getItem('bar2')->isHit(); // true
$subCache->getItem('foo.bar2')->isHit(); // false

Namespaces can be anything that makes sense in your application. For example,
you can cache data per user, per locale, or per entity:

$userCache = $cache->withSubNamespace((string) $userId);
$localeCache = $cache->withSubNamespace($request->getLocale());
$productCache = $cache->withSubNamespace($productId);

Sponsor the Symfony project.