ProcessWire runtime page cache: safe boundary for $pages->uncache() when other loaded pages reference the target
0 reputation · 10 Dec 2023, 02:51 UTC
0 reputation · 10 Dec 2023, 02:51 UTC
In a long-running ProcessWire CLI script (an import that iterates thousands of pages via $pages->get() and $pages->find()), memory grows steadily because every loaded Page object is retained in the runtime page cache for the lifetime of the request. The documented mitigation is $pages->uncache($page) or periodic $pages->uncacheAll() calls, but I cannot find a documented constraint for one specific situation.
Many of the pages I load are referenced by other still-loaded pages: as parents, as page-reference field targets, or as children already iterated. The documentation does not state whether uncaching such a page is safe — whether dependent code silently triggers a fresh database reload, or whether remaining references keep the instance alive anyway, negating the memory saving. There also appears to be no documented cache size limit or eviction policy to rely on instead.
Assume ProcessWire 3.x; I will confirm method signatures against wire/core/Pages.php in my installed copy.
33275 reputation · 10 Dec 2023, 08:26 UTC
Yes – calling $pages->uncache($page) on a page that other loaded pages still reference is safe from a cache‑consistency viewpoint. The method only removes the entry from ProcessWire’s internal runtime cache; any existing PHP variables that hold a reference to that Page object continue to point to the same instance, so the object is not destroyed and its property values remain unchanged.
If later code executes $pages->get($id) or a find that matches the same ID, ProcessWire loads a fresh Page instance from the database, stores it in the cache, and returns that new object. The old instance that your variables still reference is not updated, so it may contain stale data unless you re‑fetch the page.
Page object while PHP references exist.$pages->uncacheAll() clears the whole cache array, yet any Page objects still referenced elsewhere remain in memory.$page, call $pages->uncache($page) to drop the cache entry.unset($page)) or avoid storing it in arrays.$pages->uncacheAll() periodically (e.g., every 500 iterations) to ensure the internal cache does not grow.limit (and optionally offset) so that only a bounded number of pages are loaded at any time.Do you retain any references to the processed pages after calling $pages->uncache() (for example, in an array, passed to a function, or stored in a property)? If yes, the memory will not drop until those references are unset; confirming this will determine whether additional uncacheAll() calls are needed.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.