A shared Redis instance can serve a multi-tenant application when every application key is derived from a trusted tenant context. Enforce the prefix inside one cache abstraction; do not let feature code assemble keys or accept a tenant ID directly from request data.
Last updated: October 1, 2026.
<?php
final class TenantCache
{
public function __construct(
private Redis $redis,
private string $tenantId
) {
if (!preg_match('/\A[a-zA-Z0-9_-]+\z/', $tenantId)) {
throw new InvalidArgumentException('Invalid tenant ID');
}
}
public function get(string $name): string|false
{
return $this->redis->get($this->key($name));
}
public function set(string $name, string $value, int $ttl): bool
{
return $this->redis->setex($this->key($name), $ttl, $value);
}
private function key(string $name): string
{
return 'tenant:' . $this->tenantId . ':' . $name;
}
}Construct this wrapper only after authentication resolves the tenant. Expose tenant-scoped operations to the rest of the application rather than the raw Redis client, and keep cache names application-defined.
Prefixes prevent collisions, not resource interference
Redis has one flat keyspace per logical database and documents colon-separated segments as a naming convention in its keyspace guide. A prefix makes ownership visible and prevents accidental name collisions when the wrapper is consistently enforced.
Logical databases selected with SELECT are namespaces within the same Redis server and persistence files. They are not a scalable tenant-isolation boundary. More importantly, a shared instance applies memory pressure and eviction policy across its keyspace, so one tenant’s heavy cache use can evict another tenant’s entries.
Choose stronger isolation when the risk requires it
Use TTLs, per-tenant cache quotas in application logic, metrics by prefix, and rate limits to control ordinary shared usage. Move large or regulated tenants to a separate Redis deployment when you need independent credentials, memory limits, failure domains, or eviction behavior.
Cache misses must always fall back to the tenant-scoped system of record. Combine the wrapper with tenant isolation in SQL queries, noisy-neighbor controls, and per-tenant rate limiting.