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

Merged opened this

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

Merged

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

opened this

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.ts adds 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: frontKey in src/actions/front.ts is SELECT n FROM front_epoch and nothing else. PAGE_MS and forgetFrontScores are unchanged.
  • Server-Timing: frontPage takes an optional request and times the key as key. home.ts passes the request, and front-timing.test.ts now expects session, 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 to PAGE_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

Closes #6325

commented

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.ts adds 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: frontKey in src/actions/front.ts is SELECT n FROM front_epoch and nothing else. PAGE_MS and forgetFrontScores are unchanged.
  • Server-Timing: frontPage takes an optional request and times the key as key. home.ts passes the request, and front-timing.test.ts now expects session, 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 to PAGE_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

commented

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.ts adds front_epoch(n) and triggers on app, repo, front_pick and front_setting. They fire on insert, delete, and update of only the columns the shelf renders. repo.issue_seq and repo.last_fetch_at are not among them.
  • look triggers: they fire only for a production thumb.
  • user triggers (not in the issue): they fire on username, suspended_at and removed_at. A suspended or removed owner's repos leave the page, so without these that would wait up to PAGE_MS.
  • Key: frontKey in src/actions/front.ts is SELECT n FROM front_epoch and nothing else. PAGE_MS and forgetFrontScores are unchanged.
  • Server-Timing: it now shows key between session and shelf; front-timing.test.ts expects 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

Approved

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.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs