Skip to content

[6.x] Improve term/entry stache warming performance - #14816

Open
edalzell wants to merge 15 commits into
statamic:6.xfrom
edalzell:fix/term-entry-stache-warming-performance
Open

edalzell wants to merge 15 commits into
statamic:6.xfrom
edalzell:fix/term-entry-stache-warming-performance

Conversation

@edalzell

Copy link
Copy Markdown
Contributor

On our largest site, stache refreshing took 7-8 mins, which is too close to Forge's 10 mins deployment limit.

I proposed a 2 pass approach to Claude to see if it was feasible and this code results in over a 2 min decrease on my machine, from ~7:30 to ~5:15.

@jasonvarga jasonvarga left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two-pass warm approach is sound and the perf win is real, but I found two correctness regressions and a test gap that should be addressed before merge. Left inline comments on the specific spots.

No tests added. This touches core stache:warm behavior and adds a fast/cold-path split with non-trivial cache-key assumptions. A test asserting term/entry associations + value indexes match the old single-pass output — covering (a) a max_items: 1 taxonomy field and (b) an on-the-fly/fileless term — would have caught both inline issues below.

Comment thread src/Stache/Indexes/Terms/Associations.php Outdated
Comment thread src/Stache/Stores/Store.php Outdated
@edalzell

edalzell commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, both were real. Rebased on 6.x and addressed:

  • max_items: 1: Associations now reads the entries store's $handle, site and id indexes via index() and wraps scalar values. No more hand-built cache keys or separate cold path; outside warming the indexes build on demand, same cost as the old query.
  • Terms\Value: pass 1 now only takes Value indexes that don't override getItems(). Everything else (incl. all Terms\Value subclasses) builds in pass 2 as before.

Added warm tests for a max_items: 1 field and an on-the-fly term; both failed before the fix.

@edalzell
edalzell force-pushed the fix/term-entry-stache-warming-performance branch from 9f70dd6 to 476d590 Compare September 2, 2026 17:34

@jasonvarga jasonvarga left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the rebase — I've re-reviewed at 476d590. Both of my previous Critical findings are properly fixed, and the two new tests cover them well. Arr::wrap() handles the max_items: 1 shape, and the ReflectionMethod discriminator is a much better check than method_exists — I traced it through every index class in core and it classifies all of them correctly (Terms\Site in particular, which resolves to Terms\Value via same-namespace lookup, correctly stays in Pass 2). CI is green and there are no conflicts.

Four things left, all Warnings rather than blockers-in-principle — but I'd like them addressed before this goes in, since two of them are silent failures.

One broader note on the approach: the two-pass split is sound, and I confirmed the perf mechanism actually fires — CollectionEntriesStore::storeIndexes() already merges $collection->taxonomies()->map->handle(), so the taxonomy value indexes are always resolved and always built in Pass 1, even on a cold cache. So the ordering does what the docblocks claim.

Inline comments below.

Comment thread src/Stache/Stores/Store.php Outdated
Comment thread src/Stache/Stores/Store.php
Comment thread src/Stache/Stache.php Outdated
Comment thread src/Stache/Indexes/Terms/Associations.php Outdated
@edalzell
edalzell requested a review from jasonvarga September 14, 2026 21:12

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants