Repository navigation
[6.x] Warm paginated pages without holding up the rest of static:warm - #15852
Open
DanielDarrenJones wants to merge 2 commits into
Open
DanielDarrenJones wants to merge 2 commits into
DanielDarrenJones wants to merge 2 commits into
Conversation
… the same URL When a warmed page reported pagination, static:warm started a second pool of requests for its other pages and waited for it from inside the first pool's callback. Nothing else was sent while it waited, so the first pool kept emptying out and refilling. The paginated pages are now collected and warmed in one pool once the first has finished. When query strings are ignored, every page of a paginated URL is cached under that URL, so requesting them only returned what had just been cached. Those requests are now skipped, in the command and in the queued job.
DanielDarrenJones
marked this pull request as ready for review
November 12, 2026 00:07
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
static:warmfinds out a URL is paginated from theX-Statamic-Paginationheader on its first page, then warms the rest of its pages. Two things about how it does that cost time.The other URLs wait while a paginated URL is warmed
The pages are warmed from inside the callback that handles the first page's response, with a second pool that is waited on there and then. Until that finishes, the main pool isn't topped up, so its requests drain away and nothing else is sent. A site with a lot of paginated listings spends much of the run at a fraction of
warm_concurrency.Paginated pages are now collected as responses come in, and warmed together once the main pool has finished, at the same concurrency.
Pages that can't be cached separately are requested anyway
With
ignore_query_stringson,/blog?page=2is cached under the same URL as/blog, which has just been warmed. Requesting it does nothing but serve the cached page back. The same is true of apageparameter that isn't inallowed_query_strings, or is indisallowed_query_strings.A page is now only requested when the cacher would store it under a different URL from the one that was just warmed. This uses the cacher's own
getUrl(), so it follows whatever the query string settings are. It applies to--queuetoo, where each of those pages was a job.Also
A URL that already has a query string had its page added with a second
?, as in/blog?filter=x?page=2. It's now added with&, as the queued job already did. This only affected URLs added through theadditionalhook.What changes for someone running it
?page=Nlines are gone, and so are the requests.Benchmark
A generated site of 2,888 URLs, of which 2,000 are articles and the paginated listings add another 1,049 pages. Half measure,
warm_concurrencyat its default of 25, served byphp -Swith 8 workers on an Apple M1 Pro. Each figure is one fullstatic:warmfrom an empty cache, run twice. The machine was busy with other work, so the times are rough; the request counts are exact.ignore_query_stringsonignore_query_stringsoffWith query strings ignored, about a third of the time goes: a quarter of the requests are no longer made, and the rest aren't held up. With them kept, every page still has to be rendered, so the gain is only from not stalling the pool, and is closer to 10%.
The full strategy wasn't measured.
Tests
Five tests added, four for the command and one for the job. Each fails on
6.x.