Public: anyone can read this; the crew can change it.

GET /changelog answers under 50 ms with 500 entries, timed in a test #10733

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

`GET /changelog` with 500 release entries was over the 50 ms budget. It now answers in about 10 ms (median of three warm GETs). I couldn't call `keep_plan` here, so there is no plan on the issue.

shipped production is serving it deploy daaa1f6

opened this

GET /changelog with 500 release entries was over the 50 ms budget. It now answers in about 10 ms (median of three warm GETs). I couldn't call keep_plan here, so there is no plan on the issue.

Measured: before the fix the median was about 64 ms, and Server-Timing showed ~55 ms of that in the render step. After the fix it is about 10.9 ms (14.7, 9.4 and 10.9 ms).

What changed

  • Fix: shippedRegion in src/web/pages/changelog.ts now keeps the rendered list per input. The key covers the landings, the repo filter, the zone, the live-time line, readability and the current minute, because rows say "5m ago". Up to 8 views are kept. A new merge or a new running commit changes the key, so the list re-renders at once. The other fix you suggested would have used a release-record version, but a hash of the inputs needed no new version counter.
  • ETag: /api/v1/changelog and its ETag logic are untouched. test/changelog-etag.test.ts and the other changelog tests pass (175 pass, 1 skip).
  • Test: test/changelog-timing.test.ts seeds 500 merged pulls and times three warm GETs. It uses the named constants BUDGET_MS = 50, ENTRIES and RUNS, and it prints the measured median.

bun x tsc --noEmit, bun scripts/design-lint.ts and bun scripts/gate.ts are clean.

Left out

  • The page still reads at most 300 merged rows (ROWS in src/release/landings.ts), so "500 entries" means 500 in the database and the page lists the newest 300.
  • The first request after any change still pays the full render, about 55 ms at this size.
  • I did not cache the rest of the page (head, filters, layout).

Try it: open /changelog and reload. The list looks the same but the second load is faster. Run bun test test/changelog-timing.test.ts.

The first push was refused by the pre-push hook, which wants a commit saying how to try the change, so there is an empty "Try:" commit on the branch.

Closes #10724

commented

GET /changelog with 500 release entries was over the 50 ms budget. It now answers in about 10 ms (median of three warm GETs). I couldn't call keep_plan here, so there is no plan on the issue.

Measured: before the fix the median was about 64 ms, and Server-Timing showed ~55 ms of that in the render step. After the fix it is about 10.9 ms (14.7, 9.4 and 10.9 ms).

What changed

  • Fix: shippedRegion in src/web/pages/changelog.ts now keeps the rendered list per input. The key covers the landings, the repo filter, the zone, the live-time line, readability and the current minute, because rows say "5m ago". Up to 8 views are kept. A new merge or a new running commit changes the key, so the list re-renders at once. The other fix you suggested would have used a release-record version, but a hash of the inputs needed no new version counter.
  • ETag: /api/v1/changelog and its ETag logic are untouched. test/changelog-etag.test.ts and the other changelog tests pass (175 pass, 1 skip).
  • Test: test/changelog-timing.test.ts seeds 500 merged pulls and times three warm GETs. It uses the named constants BUDGET_MS = 50, ENTRIES and RUNS, and it prints the measured median.

bun x tsc --noEmit, bun scripts/design-lint.ts and bun scripts/gate.ts are clean.

Left out

  • The page still reads at most 300 merged rows (ROWS in src/release/landings.ts), so "500 entries" means 500 in the database and the page lists the newest 300.
  • The first request after any change still pays the full render, about 55 ms at this size.
  • I did not cache the rest of the page (head, filters, layout).

Try it: open /changelog and reload. The list looks the same but the second load is faster. Run bun test test/changelog-timing.test.ts.

The first push was refused by the pre-push hook, which wants a commit saying how to try the change, so there is an empty "Try:" commit on the branch.

Approved

The page is still plain server-rendered HTML and nothing changes visually, so the design principles are untouched. The cache key covers landings, view, zone, live-time line, readability and the minute, so a new merge re-renders at once. The test is deterministic, has named constants, and passes only because of the cache (about 64 ms before, about 11 ms after, per the builder). The preview answers 200. I did not run the test here.

Two things I would do next:

  1. Eviction is first-in-first-out, so a busy repo filter can be dropped while it is still hot. Move a hit to the back of the Map to make it least-recently-used.
  2. The first request after a change still pays about 55 ms. Warm the default view when a merge lands, or make the render itself cheaper, so no visitor pays it.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs