← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

PSR-6: Caching Interface

Style PHP 5.5+ Intermediate
debt(d6/e5/b5/t5)
d6 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review' (d7), slightly better at d6 — phpstan/deptrac can detect direct Redis/APCu coupling via layer rules, but spotting missing isHit() checks or absent expiry usually requires review.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5) — swapping direct cache calls for CacheItemPoolInterface requires introducing the abstraction, updating call sites, and wiring DI across the caching component.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5) — caching applies across web/cli/queue contexts and the interface choice shapes how every cache consumer is written, but it's a well-known standard so the tax is modest.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap most devs eventually learn' (t5) — the misconception that PSR-6 and PSR-16 compete, plus the isHit() gotcha where missing items return null and look like cached nulls, are documented traps developers hit once.

About DEBT scoring →

Also Known As

PSR-6 PSR-6 cache CacheItemPoolInterface

TL;DR

Standard CacheItemPoolInterface and CacheItemInterface for framework-agnostic cache integration — decouple code from specific cache backends.

Explanation

PSR-6 defines two interfaces: CacheItemPoolInterface (the cache driver — get, save, deleteItem, clear, commit) and CacheItemInterface (a cache entry — get/set value, expiry). By type-hinting CacheItemPoolInterface, application code is decoupled from the specific backend (Redis, Memcached, APCu, filesystem). Symfony Cache is the canonical implementation, supporting all backends with a unified API. PSR-16 (Simple Cache) provides a simpler single-class alternative for basic get/set/delete use cases that don't need the item object model. Libraries should accept PSR-6 or PSR-16 interfaces rather than concrete cache clients.

Common Misconception

PSR-6 and PSR-16 are competing cache standards. PSR-6 provides a full-featured pool/item model for complex cache management. PSR-16 is a simpler key-value interface for basic use. Most cache libraries implement both — use PSR-16 for simple cases and PSR-6 when you need deferred saving or item metadata.

Why It Matters

PSR-6 defines a caching interface — code that uses CacheItemPoolInterface works with APCu, Redis, Memcached, or a file cache without modification, making cache backends swappable.

Common Mistakes

  • Using cache library APIs directly instead of PSR-6 — locks the codebase to one cache implementation.
  • Not checking CacheItem::isHit() — treating a miss as a hit returns stale null data.
  • Not setting expiry on cache items — items live forever until manually deleted or evicted.
  • Serializing objects manually before caching instead of letting PSR-6 handle serialization.

Code Examples

✗ Vulnerable
// Direct Redis dependency — cannot swap to file cache:
$redis = new Redis();
$redis->get('user:' . $id);

// PSR-6 — swappable:
function getUser(CacheItemPoolInterface $cache, int $id): User {
    $item = $cache->getItem('user:' . $id);
    if (!$item->isHit()) {
        $item->set(User::find($id))->expiresAfter(300);
        $cache->save($item);
    }
    return $item->get();
}
✓ Fixed
// PSR-6 Caching Interface
use Psr\Cache\CacheItemPoolInterface;
use Psr\Cache\CacheItemInterface;

// Writing to cache
$item = $cache->getItem('user:' . $userId);
if (!$item->isHit()) {
    $user = $this->db->fetchUser($userId);
    $item->set($user)->expiresAfter(3600);
    $cache->save($item);
} else {
    $user = $item->get();
}

// Delete
$cache->deleteItem('user:' . $userId);

// PSR-6 compatible implementations:
// symfony/cache, cache/filesystem-adapter, league/flysystem-cached-adapter

// PSR-16 (Simple Cache) — simpler interface:
// $cache->get('key', 'default');
// $cache->set('key', $value, 3600);

Added 15 Mar 2026
Edited 22 Mar 2026
Views 100
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping F 0 pings S 0 pings S 0 pings M 2 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 1 ping T 0 pings W 0 pings T 2 pings F 1 ping S 0 pings S 0 pings M 1 ping T 0 pings W 0 pings T 1 ping F 2 pings S 0 pings S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S
No pings yet today
No pings yesterday
Amazonbot 15 PetalBot 10 SEMrush 8 ChatGPT 7 Ahrefs 7 Perplexity 4 Google 4 Bing 4 Scrapy 3 Twitter/X 2 Brave Search 2 Applebot 2 Claude 1 Meta AI 1 Unknown AI 1
crawler 66 crawler_json 5
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Use CacheItemPoolInterface (PSR-6) or CacheInterface (PSR-16 simpler) for all caching — swap between APCu, Redis, Memcached, or array cache without changing application code
📦 Applies To
PHP 5.5+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Direct Redis or APCu calls without PSR-6 interface; cache implementation tightly coupled to specific driver; no cache abstraction layer
Auto-detectable: ✓ Yes phpstan deptrac
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: Medium ✗ Manual fix Fix: Medium Context: File


✓ schema.org compliant