Node Cache: Overview and Setup#
What Node Cache is and is not#
Node Cache is:
a local APCu -> SQLite cache topology;
persistent across PHP-FPM or application-worker restarts when the local SQLite file survives;
compatible with normal
Cachereads, writes, tags, batches, deferred writes, metrics, andremember();fail-open by default for APCu and SQLite runtime failures.
Node Cache is not:
a shared cache between servers or containers;
a distributed lock, queue, counter, rate limiter, or session store;
a substitute for an authoritative database;
an immediate global-revocation mechanism for security-sensitive data.
For cross-node invalidation while retaining local cached values, use Cluster Cache.
Topology and request lifecycle#
The topology is deliberately simple:
PHP request / worker
|
v
Cache facade (PSR-6 / PSR-16 / tags / remember)
|
v
APCu L1, when enabled and available
|
| miss
v
SQLite L2 on this node's local disk
|
| miss
v
application resolver / authoritative source
Read lifecycle#
APCu is checked when enabled.
On an APCu miss, SQLite is checked.
A SQLite hit is promoted to APCu with its remaining TTL.
A miss returns the caller’s default, or
remember()resolves the value.Expired rows are misses. They are left for bounded maintenance rather than being deleted on every read.
Write lifecycle#
A normal write is persisted to SQLite first.
A successful SQLite write is copied to APCu when APCu is available.
A delete or namespace clear is attempted across both layers.
Tagged entries and tag-version metadata are local to this node.
With the default failOpen: true, an L2 failure can fall back to an L1 write
so the request can continue. This is a resilience choice: the L1-only value is
lost when that PHP/APCu process is restarted. Set failOpen: false when a
storage failure must be surfaced to the application instead.
Requirements and filesystem placement#
Node Cache requires ext-pdo with the SQLite driver. APCu is optional.
APCu is used only if all of the following are true:
apcuEnabledistrue(the default);the APCu extension is loaded;
APCu is enabled for the executing PHP SAPI.
Put the SQLite database in a writable directory that is local to the node,
outside the repository and web root. SQLite creates companion -wal and
-shm files, so the directory—not merely the database file—must be writable
by the application account.
Do not use NFS, SMB, a synchronized folder, or another network/shared filesystem for the Node Cache SQLite file. The factory rejects symlinked and world-writable cache directories as a safety measure.
Recommended layout:
/var/cache/my-application/
node-cache.sqlite
node-cache.sqlite-wal
node-cache.sqlite-shm
locks/ # optional, used by remember() file locks
Configuration and bootstrap#
Create one NodeCacheConfig for each application node. The SQLite path and
lock directory should be local; the namespace names the logical cache within
that database.
use Infocyph\CacheLayer\Node\NodeCache;
use Infocyph\CacheLayer\Node\NodeCacheConfig;
$config = new NodeCacheConfig(
sqliteFile: '/var/cache/my-application/node-cache.sqlite',
namespace: 'catalog',
lockDirectory: '/var/cache/my-application/locks',
busyTimeoutMs: 1_000,
apcuEnabled: true,
failOpen: true,
);
$cache = NodeCache::create($config);
Configuration reference#
sqliteFileRequired path to the SQLite database. It must not contain a NUL byte.
namespaceLogical cache partition inside the SQLite database. It defaults to
defaultand is sanitized before use. Use a stable, application-specific name such ascatalogorbilling.lockDirectoryOptional directory for the file lock provider used by
remember(). Leave itnullto use the library default, or point it at a local writable directory for an explicit deployment layout.busyTimeoutMsSQLite busy timeout in milliseconds. The default is 1,000. Increase it cautiously only when legitimate local write contention is observed; it does not make a shared/network filesystem safe.
apcuEnabledEnables APCu L1 when the extension and SAPI support it. Set it to
falsefor deterministic SQLite-only behavior, CLI jobs, or troubleshooting.failOpenDefaults to
true. When true, recoverable layer failures are treated as cache degradation where possible. When false, APCu/SQLite failures propagate to the caller.lockProviderOptional
LockProviderInterfaceused byremember(). When omitted, Node Cache uses its local file-lock default. Supply a sharedRedisLockProviderorValkeyLockProviderwhen multiple application nodes must coordinate oneremember()resolver.
use Infocyph\CacheLayer\Cache\Lock\RedisLockProvider;
$config = new NodeCacheConfig(
sqliteFile: '/var/cache/my-application/node-cache.sqlite',
namespace: 'catalog',
lockProvider: new RedisLockProvider($redis, 'catalog:remember:'),
);