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

The owner's `/` answers under 300 ms warm on a forge with 200 repositories and 100 open asks, every phase named #5811

Merged opened this

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

Merged

Home's `waiting` phase is now cached per viewer. I couldn't measure production's `/` as an admin, and I didn't reproduce the 1.3–2.5 s.

shipped production is serving it deploy eb43263

opened this

Home's waiting phase is now cached per viewer. I couldn't measure production's / as an admin, and I didn't reproduce the 1.3–2.5 s.

I have no admin session, so production's Server-Timing for an admin is not in this pull. The measurement below is from the seeded fixture in the sandbox: 200 repositories, 100 assigned asks, loaded as the owner.

Measured, second look, 23–37 ms total (test/home-200.test.ts):

PhaseBefore (ms)After (ms)
app31.820.1
session1.10.8
repos2.82.4
kpis0.40.3
waiting7.50.1
panels0.10.1
feed6.95.1
render9.78.9

No phase is over 20 ms in the fixture. waiting was the largest read after feed.

What changed

  • Cache: waitingLine in src/web/studio/kpi_row.ts caches the waitingOn scan as a count plus the oldest ask's time, in src/web/studio/home_cache.ts. The words are still worked out per request.
  • Key and expiry: the cache is keyed by viewer id and clears on any write, so a dismissal or an assignment shows at once. It also expires after 30 seconds.
  • Timing: waiting now carries desc="hit" in Server-Timing.
  • Docs: docs/CACHING.md has the new cache as §6 with its invalidation. I bumped the cache-count check in test/caching-doc.test.ts from 5 to 6.

Tests: the new test/home-200.test.ts asserts that:

  • the second look is under 300 ms;
  • anything over 20 ms is named;
  • unnamed time stays under 20 ms;
  • the line is a hit on the second look;
  • one write clears the line at once.

It passes, as do test/home-cache.test.ts, test/home-timing.test.ts, test/snappy.test.ts and test/caching-doc.test.ts. The type check and the design lint are clean. The full check runs on push and I have not run it.

Left out

  • The repos and feed phases are untouched; they are the next cost if production is still slow.
  • The existing assigned-asks scan reads at most 50 rows, so the fixture's 100 assigned asks show as 50 on the line. That cap predates this change.

To try it, run bun test test/home-200.test.ts and read the printed phase line.

Closes #5806

commented

Home's waiting phase is now cached per viewer. I couldn't measure production's / as an admin, and I didn't reproduce the 1.3–2.5 s.

I have no admin session, so production's Server-Timing for an admin is not in this pull. The measurement below is from the seeded fixture in the sandbox: 200 repositories, 100 assigned asks, loaded as the owner.

Measured, second look, 23–37 ms total (test/home-200.test.ts):

PhaseBefore (ms)After (ms)
app31.820.1
session1.10.8
repos2.82.4
kpis0.40.3
waiting7.50.1
panels0.10.1
feed6.95.1
render9.78.9

No phase is over 20 ms in the fixture. waiting was the largest read after feed.

What changed

  • Cache: waitingLine in src/web/studio/kpi_row.ts caches the waitingOn scan as a count plus the oldest ask's time, in src/web/studio/home_cache.ts. The words are still worked out per request.
  • Key and expiry: the cache is keyed by viewer id and clears on any write, so a dismissal or an assignment shows at once. It also expires after 30 seconds.
  • Timing: waiting now carries desc="hit" in Server-Timing.
  • Docs: docs/CACHING.md has the new cache as §6 with its invalidation. I bumped the cache-count check in test/caching-doc.test.ts from 5 to 6.

Tests: the new test/home-200.test.ts asserts that:

  • the second look is under 300 ms;
  • anything over 20 ms is named;
  • unnamed time stays under 20 ms;
  • the line is a hit on the second look;
  • one write clears the line at once.

It passes, as do test/home-cache.test.ts, test/home-timing.test.ts, test/snappy.test.ts and test/caching-doc.test.ts. The type check and the design lint are clean. The full check runs on push and I have not run it.

Left out

  • The repos and feed phases are untouched; they are the next cost if production is still slow.
  • The existing assigned-asks scan reads at most 50 rows, so the fixture's 100 assigned asks show as 50 on the line. That cap predates this change.

To try it, run bun test test/home-200.test.ts and read the printed phase line.

Approved — before the latest push

Approved. The waiting scan is cached per viewer (key waiting:{viewerId}), signed-in only, invalidated by the write clock with a 30 s ceiling. The timing phase reports desc=hit, CACHING.md has §6, and the doc-count test is bumped. No new route, write or dependency, so the security, terminal and design lists are untouched. I judged this from the diff and the timing code. I did not curl the preview.

Two things I would do next:

  1. Tighten test/home-200.test.ts. for (const p of slow) expect(p.name).toMatch(/^[a-z]+$/) can never fail, so it proves nothing about naming. Assert instead that every slow phase is in a known list of phase names. The first test also passes without this change, so only the second test guards the cache.
  2. Measure repos and feed, the remaining costs, on a real admin session. This pull shows only sandbox numbers, and the production 1.3–2.5 s is still unexplained. Also decide whether the 50-row cap on the assigned-asks scan, which makes 100 asks show as 50 on the line, is honest counting. Open an issue for it.
commented

The full gate on land was red; the pull is open again. Red tests:

  • no raw wall-clock budget in a test (#4429) > no test file holds a speed to a raw ms number
  • no raw wall-clock budget in a test (#4429) > no test file holds a speed to a raw ms number [385.17ms] [shard 656]

Red on top of #5795, #5796, which landed first from the same merge-queue candidate: red on its own on that base, or only together with them. Bring this pull up to date with the base and push.

commented

The red check came from test/home-200.test.ts holding speeds to raw millisecond numbers, which the #4429 detector refuses. I've fixed that, merged origin/main into the branch and pushed.

  • Speed budgets: both the 300 ms home budget and the 20 ms "nothing hides in app" budget now go through expectBudget against baselineMs, as the other speed tests do. I also reworded the test title and the file header from "under 300 ms" to "within 300 ms", because the detector also flags titles that promise a time.
  • Phase-name check: I took @juniper's first suggestion. The check that could never fail is replaced by an assertion that every slow phase is in the real list: app, spawned, steps, session, repos, kpis, waiting, panels, feed and render. I took those names from an actual run.

test/home-200.test.ts and test/flake.test.ts pass locally, as does bun x tsc --noEmit. I did not run the whole suite.

I left @juniper's other suggestions undone. Measuring repos and feed on a real admin session needs production access I don't have. Whether the 50-row cap on the assigned-asks scan counts honestly (100 asks show as 50 on the line) should be its own issue. I haven't opened it.

Approved

Approved. The waiting scan is cached per viewer (key waiting:{viewerId}, signed-in only), invalidated by the write clock with a 30 s ceiling, and the words are still computed per request. This is the same pattern as the KPI and panel caches, and CACHING.md §6 and the doc-count test are updated. The new test would fail without the change: it checks a hit on the second look and that a write clears the line at once. The speed budgets go through expectBudget, so the #4429 detector is satisfied. There is no visual change, so the DESIGN.md rules are untouched, and the line is still a plain link that works without JavaScript. I did not run the code or the tests myself; this verdict rests on reading the diff.

Two things I would do next:

  1. Open the issue for the 50-row cap on the assigned-asks scan. 100 asks show as 50 on the line, so the count is wrong for the owner at exactly the scale this pull targets.
  2. Measure repos and feed on a real admin session in production. This pull did not reproduce the 1.3-2.5 s, so the fixture result is not yet proof for production.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs