Re: [RFC] [Discussion] OPcache Static Cache
| From: | Larry Garfield | Date: | Mon, 18 May 2026 17:13:00 +0000 |
| Subject: | Re: [RFC] [Discussion] OPcache Static Cache | ||
| References: | 1 2 3 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-130944@lists.php.net to get a copy of this message | ||
On Mon, May 18, 2026, at 6:00 AM, Go Kudo wrote:
> Hi Larry,
>
> Thank you for the detailed feedback.
>
> I updated the RFC and the implementation to address the concrete API and
> documentation issues you pointed out.
>
> https://wiki.php.net/rfc/opcache_static_cache
>
> The main changes are:
>
> -
persistent_atomic_decrement() now creates a missing key with
> -$step,
> matching persistent_atomic_increment().
+1
> - volatile_lock() and
> persistent_lock() now have matching
> *_unlock()
> functions.
I should note that this is an excellent example of where context managers and a using
block would be helpful. :-)
> - The lock APIs also accept an optional lease value, so abandoned
> builder
> reservations can expire even in persistent-worker environments.
+1
> - The status APIs now return a read-only
> OPcache\StaticCacheInfo
> object
> instead of arrays.
+1
Though it's not entirely obvious to me which property I would need to check every single time I
want to try storing to it. enabled? available? What's the fully safe read/write code pattern
here?
> - The RFC now documents that both static-cache backends are scoped to
> the
> lifetime of the current OPcache static-cache shared-memory segment,
> and are
> not durable storage.
Ah, that's a big and important distinction! What does "lifetime of the current opcace
static-cache shared memory segment" mean to developers who don't read this list? :-) Does
it mean "persistent" also goes away if you restart FPM/Apache/whatever? Does that mean
this is all basically useless for CLI? Those should be made very clear in non-internals-speak..
So really, the distinction is more whether there's a TTL and eviction strategy, or if the
eviction strategy is just "fall over and die." In that case, I'm not sure if
"persistent" is even the right name for that part of the API, as it's not, well,
persistent.
> - The RFC now describes when __serialize() and
> __unserialize() are
> called, and
> that userland serialization keeps those object graphs off the fastest
> direct/shared-graph path.
I want to make sure I follow here.
class Test {
pubic string $a;
public string $b;
}
$t = new Test();
persistent_store('t', $t);
// Later
$loadedT = persistent_fetch('t');
If Test does not have serialize/unserialize magic methods, then the object is stored "as
is" and $t === $loadedT. If it does implement those methods, then it behaves like $loadedT =
unserialize(serialize($t));
Is that correct? (Please clarify with examples in the RFC either way.)
> - The publication rules for VolatileStatic immediate mode,
> `VolatileStatic
> tracking mode, and PersistentStatic` have been expanded.
> - VolatileStatic tracking is now documented as publishing at
> PHP
> request
> shutdown, not process shutdown, even under FPM/FrankenPHP/persistent
> workers.
+1
> Some of the broader points are open questions or design tradeoffs rather than
> direct fixes.
>
> On the default-off setting, I want to be more direct about where I actually
> stand. I would prefer this feature to be default-on. Administrator opt-in
> noticeably limits library adoption, and that significantly reduces the value
> of the API as a portable primitive that libraries can rely on being present.
>
> What is holding me back is the shared-hosting case. The cache is a single
> shared-memory trust domain, so on a host where multiple tenants share one
> OPcache segment, default-on without an isolation story could expose those
> tenants to each other through the static cache. I do not yet have a design I
> am confident makes default-on safe in that environment, and that is the only
> reason the RFC currently ships with the feature disabled.
>
> I would genuinely appreciate your input here. If you (or anyone on the list)
> see a viable path — per-pool / per-SAPI segments, a trust-domain or namespace
> mechanism enforced by the engine, a configuration model where the host opts
> in per vhost rather than per server, or something I have not considered — I
> would be very happy to rework the proposal around it. If we can land on a
> model that is safe for shared hosting, I would gladly flip the default in
> this RFC rather than defer it to a follow-up.
I suppose the question I'd ask here is how much of a factor is that these days? Shared hosting
was a huge part of PHP's early years, but... I don't remember the last time I actually ran
on a traditional shared hosting setup with shared opcache between different tenants. How much of
the market even is that these days? (I have no idea.)
> For disabled backends, the explicit APIs fail rather than silently pretending
> to be a miss-only cache. Attribute-backed state falls back to ordinary request
> local static behavior when the corresponding backend is unavailable. I can add
> a short FAQ entry for this development-mode behavior if that would make the RFC
> clearer.
Yes please.
> For multi-library key collisions, the explicit cache remains a shared namespace
> and applications/libraries still need key prefixes, similar to APCu. The new
> attribute deletion and exact-key deletion support should reduce the need for
> whole-backend clears, but this RFC does not add a separate namespace mechanism.
> I left the broader trust-domain/namespace question as an Open Issue, and it is
> closely related to the shared-hosting question above.
I don't have a good answer other than introducing "pools", which would likely make
the API much more involved. That could be good, though, I'm not sure. (Esp. if it pushes the
API toward OOP rather than global functions.)
> The memory-resident SQLite idea is interesting, but I think it is outside the
> scope of this RFC. This proposal is intentionally a small key/value and static
> state facility first.
Oh totally. It's not something that belongs in this RFC directly. I just want to see if
there's a path to extend it from here in a future RFC to enable such functionality. (I have no
idea what that would look like off hand.)
--Larry Garfield