Caching in Pionia
This guide is for DeskFlow developers who need application-level caching — Moonlight APIs use POST for reads, so HTTP caches do not help; cache expensive task.list results in Redis or filesystem instead.
What you will learn
- How to pick a cache store in
environment/settings.ini - How to read and write keys from services with
app()->cacheInstance() - When
GenericServicelist/retrieve TTL applies to DeskFlow endpoints
- Generic services — DeskFlow
taskservice patterns - Commands —
cache:clear,cache:prune
How it works
Pionia v3 ships a native PSR-16 cache layer (PioniaCache + CacheManager).
Because Moonlight APIs use POST for reads and writes, HTTP caches do not apply — use application-level caching instead.
Choose a store
environment/settings.ini:
[cache]
STORE=filesystem
TTL=3600
[cache_filesystem]
path=storage/cache
[cache_redis]
host=127.0.0.1
port=6379
prefix=pionia:| Store | STORE value | Best for |
|---|---|---|
| Filesystem | filesystem (default) | Single server, no extensions |
| Array | array | Tests, per-worker memory |
| Null | null | Disable caching without code changes |
| Database | database | Shared cache via PDO |
| APCu | apcu | RoadRunner / FPM workers on one host |
| Redis | redis | Production clusters |
Aliases: file, memory, void, db.
Use in code
app()->cacheInstance()->set('deskflow:project:1:tasks', $rows, 300);
$value = app()->cacheInstance()->get('deskflow:project:1:tasks');
// Named store
app()->cache()->store('redis')->set('session:alex@northwind.studio', $payload, 900);CLI
php pionia cache:clear
php pionia cache:prune
php pionia cache:delete my_keyGenericService list/retrieve cache
On services extending GenericService:
public ?int $cacheListTtl = 60; // seconds, null = off
public ?int $cacheRetrieveTtl = 300;Cache keys include table, filters, pagination, and request parameters. Use for expensive list/retrieve endpoints; invalidate with recached() on the service when data changes (see Actions).
Custom adapters
Register in a Provider:
public function configureCaching(\Pionia\Cache\CacheManager $cache): void
{
$cache->extend('memcached', function ($app, array $config) {
return new MemcachedCacheAdapter(/* ... */);
});
}RoadRunner note
Each worker has its own memory. Use Redis, database, or filesystem stores when cache must be shared across workers.
Common mistakes
- Using array cache with multiple RoadRunner workers — each worker has isolated memory; use Redis or filesystem.
- Caching without invalidation — call
recached()aftertask.create/task.updateor stale lists appear. - Expecting CDN/browser cache on POST — only application-level PSR-16 caching applies to Moonlight reads.
- Forgetting
cache:clearafter deploy — old serialized payloads can linger in filesystem/Redis stores.
What’s next
Generic services
List/retrieve TTL on DeskFlow services.
Performance (Porm)
Query-level optimization.
RoadRunner
Shared cache across workers.