Skip to content

Skip rewriting indexes that haven't changed on save - #5

Merged
DanielDarrenJones merged 2 commits into
mainfrom
skip-unchanged-index-writes
Nov 11, 2026
Merged

DanielDarrenJones merged 2 commits into
mainfrom
skip-unchanged-index-writes

Conversation

@DanielDarrenJones

@DanielDarrenJones DanielDarrenJones commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Saving an entry spent about 45 ms after the save itself, re-exporting indexes that hadn't changed.

What was happening

Statamic puts every index of a collection back into the Stache each time an entry is saved: 23 of them for the demo's books collection, including the two term association indexes. Flatpack buffers those and writes them at the end of the request. For each one it exported the value to PHP, hashed it, and only then saw that a file with that hash already existed. Editing a field that isn't indexed changed none of them, but all 23 were exported anyway.

The change

Before exporting a value, compare it with what this request read. If it's identical, and the pointer still names the same file (so no other process has replaced it since), skip it.

Nothing is loaded that the request hadn't already loaded, so builds and refreshes aren't affected.

Measurements

Demo site, nested page builder, 9,000 books in three languages, Statamic 6.40. Each operation runs inside a web request with OPcache on; median of 7 after a warm-up. Whole request, in ms:

Statamic (file Stache) Flatpack 1.2.0 This branch
Save a book 140 167 133
Rename a book 148 161 118
Save a page 120 94 99
Save a term 114 103 102
Create a book 128 165 154
Delete a book 95 122 124

The 1.2.0 column is from a run earlier the same day on a slightly quieter machine (the file Stache's book save was 128 ms in that run), so compare it loosely.

The end-of-request write went from about 50 ms to about 16 ms for a save that changes no index.

Not fixed here

Creating and deleting an entry are still about a quarter slower than the file Stache. Those really do change most indexes, so there's nothing to skip.

README

The README's Save column and chart are removed. They came from demo:compare, which times the first save after a build, so they included one-off costs and overstated the difference. A sentence under the table now says what a typical save costs, and that creating and deleting are slower.

Testing

bin/parity passes on Statamic 6 (latest) and Statamic 5 (latest) locally, with the YAML fuzz at 20,000 documents rather than the default 200,000 (no YAML code is touched). 5.11 wasn't run locally; CI covers it.


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

Statamic puts every index of a collection back into the Stache each time an entry is saved. Most come back exactly as they were read, but each one was exported to PHP and hashed before finding its file already existed. On a 9,000-entry collection that was about 45 ms at the end of every save request.

Compare the value with what this request read first, and skip it when nothing changed and no other process has replaced the file since.
The demo times the first save after a build, which carries one-off costs, so the Save column and chart overstated the difference. A typical save comes out about level; say that in a sentence instead, along with create and delete being slower.
@DanielDarrenJones
DanielDarrenJones merged commit bd6d8ba into main Nov 11, 2026
4 checks passed
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.

1 participant