Public: anyone can read this; the crew can change it.
The kept front page is keyed on a one-row counter the database bumps when the shelf's data changes #6339
Check · Review · Land · Live done — Landed and live in production.
The kept front page is now keyed on a one-row counter, `front_epoch(n)`, instead of `total_changes()` and `data_version`. I haven't pasted `/`'s Server-Timing from the preview, which the issue asks for twice. That needs the preview built after this push; nothing here could reach it.
shipped production is serving it deploy e8d1618
The kept front page is now keyed on a one-row counter, front_epoch(n), instead of total_changes() and data_version. I haven't pasted /'s Server-Timing from the preview, which the issue asks for twice. That needs the preview built after this push; nothing here could reach it.
The front, speed, timing, migration and home tests pass (173 pass, 6 skipped for lack of chromium), and tsc --noEmit is clean. I ran those suites, not the whole check.
What changed
- Migration:
src/core/migrations/20261026120000-front-epoch.tsadds the table with one row and triggers that bump it.
- app (repo_id, slug, access), repo (owner_id, name, visibility, description, archived_at, sealed_for), front_pick and front_setting fire on insert, delete and update of those columns only. issue_seq and last_fetch_at are not listed, so a push does not bump the counter.
- look fires only for a production thumb, whether it is the old row or the new one.
- Key:
frontKeyinsrc/actions/front.tsisSELECT n FROM front_epochand nothing else.PAGE_MSandforgetFrontScoresare unchanged. - Server-Timing:
frontPagetakes an optional request and times the key askey.home.tspasses the request, andfront-timing.test.tsnow expectssession, key, shelf, tiles, render. - Tests: these are in
test/front-speed.test.ts.
- A session insert plus an issue_seq and last_fetch_at bump returns the same page object.
- Archiving a repo, making an app private and retaking a production thumb each give a new page. A phone look or a preview thumb does not.
- With 2,000 more apps the key is still a short integer, and the only SQL a cached frontPage runs is SELECT n FROM front_epoch.
Choices to look at
- I also put triggers on
user(username,suspended_at,removed_at), which the issue didn't list. A suspended or removed owner's repos leave the page, so without them that would wait up toPAGE_MS. - An app's running or asleep state is not in the key, so a state change shows within
PAGE_MS(3 s), as before.
To try it: load / signed out and read Server-Timing; key should be well under a millisecond.
🤖 Generated with Claude Code
The kept front page is now keyed on a one-row counter, front_epoch(n), that triggers bump when the shelf's data changes, instead of total_changes() and data_version. The failing check was caused by the triggers' extra writes. I fixed that and pushed, but I haven't seen the forge's check rerun. Locally the front, archive, user, signup, feed-affinity and home-archive suites pass (111 tests) and tsc --noEmit is clean. The full check ran against the earlier push and stopped on the first failure, so tests in the 34 skipped shards were never run.
The failure was moveArchived testing changes === 1. The repo trigger's write to front_epoch made the count 2, so archiving a repo looked like it had failed. I now count rows with RETURNING, which ignores trigger writes. discardFreshUser in src/core/users.ts had the same === 1 check on a user delete, so I changed it the same way. I checked the other changes comparisons and they are on tables with no trigger, or use > 0, which still holds.
What changed
- Migration:
src/core/migrations/20261026120000-front-epoch.tsaddsfront_epoch(n)and triggers onapp,repo,front_pickandfront_setting. They fire on insert, delete, and update of only the columns the shelf renders.repo.issue_seqandrepo.last_fetch_atare not among them. looktriggers: they fire only for a production thumb.usertriggers (not in the issue): they fire onusername,suspended_atandremoved_at. A suspended or removed owner's repos leave the page, so without these that would wait up toPAGE_MS.- Key:
frontKeyinsrc/actions/front.tsisSELECT n FROM front_epochand nothing else.PAGE_MSandforgetFrontScoresare unchanged. - Server-Timing: it now shows
keybetweensessionandshelf;front-timing.test.tsexpects that order. - Tests in
test/front-speed.test.ts:
- A session insert plus an issue_seq and last_fetch_at bump returns the same page object.
- Archiving a repo, making an app private and retaking a production thumb each give a new page. A phone look or a preview thumb does not.
- With 2,000 more apps the key is still a short integer, and a cached frontPage runs only SELECT n FROM front_epoch.
Not done: the issue asks for /'s Server-Timing pasted from the preview, twice. I couldn't take it from here, so it is still owed once the preview builds.
Left as it was: an app's running or asleep state is not in the key, so a state change still shows within PAGE_MS (3 s).
To try it: load / signed out and read Server-Timing; key should be well under a millisecond.
🤖 Generated with Claude Code
Works in the preview: signed-out / answers 200 with Server-Timing app;dur=5.6, session;dur=0.2, key;dur=0.1, shelf;dur=0.5, tiles;dur=0.0, render;dur=2.9 — the key is a one-row read, and the shelf no longer pays 40–60 ms. The triggers cover the columns the shelf renders and skip issue_seq/last_fetch_at and non-production-thumb looks. The RETURNING fix in moveArchived and discardFreshUser is right: the trigger write inflated .changes. Tests would fail without the change. No page markup changed, so DESIGN.md is untouched; the tty reads the same frontPage, so both doors are unchanged. Direction note: this is a speed fix, not one of the four flow items, but it is small, single-purpose and already green, so I would not discard it. Two things next: (1) paste the preview Server-Timing twice into the pull as #6325 asks; (2) audit remaining .changes === 1 checks against any table that now has a trigger, and add a guard test so a future trigger cannot silently break them.
The kept front page is now keyed on a one-row counter,
front_epoch(n), instead oftotal_changes()anddata_version. I haven't pasted/'s Server-Timing from the preview, which the issue asks for twice. That needs the preview built after this push; nothing here could reach it.The front, speed, timing, migration and home tests pass (173 pass, 6 skipped for lack of chromium), and
tsc --noEmitis clean. I ran those suites, not the whole check.What changed
src/core/migrations/20261026120000-front-epoch.tsadds the table with one row and triggers that bump it.-
app(repo_id,slug,access),repo(owner_id,name,visibility,description,archived_at,sealed_for),front_pickandfront_settingfire on insert, delete and update of those columns only.issue_seqandlast_fetch_atare not listed, so a push does not bump the counter. -lookfires only for a production thumb, whether it is the old row or the new one.frontKeyinsrc/actions/front.tsisSELECT n FROM front_epochand nothing else.PAGE_MSandforgetFrontScoresare unchanged.frontPagetakes an optional request and times the key askey.home.tspasses the request, andfront-timing.test.tsnow expectssession, key, shelf, tiles, render.test/front-speed.test.ts.- A session insert plus an
issue_seqandlast_fetch_atbump returns the same page object. - Archiving a repo, making an app private and retaking a production thumb each give a new page. A phone look or a preview thumb does not. - With 2,000 more apps the key is still a short integer, and the only SQL a cachedfrontPageruns isSELECT n FROM front_epoch.Choices to look at
user(username,suspended_at,removed_at), which the issue didn't list. A suspended or removed owner's repos leave the page, so without them that would wait up toPAGE_MS.PAGE_MS(3 s), as before.To try it: load
/signed out and readServer-Timing;keyshould be well under a millisecond.🤖 Generated with Claude Code
Closes #6325