Repository navigation
Cache cooldown metadata rewrites for a minute - #566
Merged
Merged
Conversation
With cooldown on, every npm, Composer and Chef metadata request rewrote the whole document, because a cached rewrite could keep hiding a version after its cooldown ended. For a 24.5 MB packument that is about 45 ms and 31 MB of allocations per request, and the result was served uncompressed and without Last-Modified, so Composer, which revalidates p2 files with If-Modified-Since only, never got a 304. The rewrite cache now keeps cooldown rewrites with an expiry of one minute, so a version leaving cooldown shows up at most that late. Concurrent requests share one rewrite, clients get the gzip copy, and the rewrite is dated through metadataDate like any other. Its ETag is the hash of its output, so replicas agree on it. The cache is keyed by the digest the metadata cache already recorded, instead of hashing the document again, which also lets storedRewrite serve cooldown rewrites without reading the stored document. Without the rewrite cache, cooldown rewrites behave as before.
andrew
approved these changes
Oct 23, 2026
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.
With cooldown on, the rewrite cache was skipped, so every npm, Composer and Chef metadata request rewrote the whole document. A cached rewrite could have kept hiding a version after its cooldown ended. The cost was:
If-Modified-Sinceonly, so with cooldown on it never got a 304.The fix:
metadataDatelike any other.storedRewriteserve cooldown rewrites without reading the stored document.metadata_rewrite_cache_size: 0), cooldown rewrites behave as before.I chose a fixed expiry over computing when the next filtered version leaves cooldown. The exact time would mean threading it out of every handler's filter. One rewrite per package per minute already removes almost all of the cost.
Benchmark with a 24.5 MB synthetic packument (
benchPackument(5000)), cooldown 3d, 20 requests with the same upstream digest:The 3.8 ms includes the first rewrite, spread over the 20 requests, plus dating each response in the database.
The tests that pinned the old behaviour now check the new one:
Last-Modifiedand a 304 forIf-Modified-Sincewith cooldown on;The ETag-from-inputs test now runs without the rewrite cache, which is where that path remains.