diff --git a/docs/configuration.md b/docs/configuration.md index 0eb5715ee..000f27e89 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -637,7 +637,13 @@ is synchronous, so it blocked the server's event loop — which also delayed dynamic tool call and before registering every interactive request. One slow thread therefore slowed agent work on _every_ thread on the host. -A window is capped at `BB_FF_TIMELINE_WINDOW_EVENT_BUDGET` events (default 1500) and returns however many whole turns fit. Older turns load automatically +A window is capped at `BB_FF_TIMELINE_WINDOW_EVENT_BUDGET` events (default 1500) and returns however many whole turns fit. The default assumes roughly +0.06ms per event; that cost varies widely with hardware, and on a small VPS it +can be closer to 0.5ms, making a full window ~720ms of blocked event loop +instead of ~100ms. If `Thread timeline build blocked the event loop` appears +often, divide a logged build's `totalDurationMs` by its `eventRowCount` to get +your real per-event cost and lower this budget until a full window fits your +latency target. Older turns load automatically as you scroll toward the top of the loaded window; a manual "Load older messages" button remains on surfaces that render no scroll body, and after a failed page so a broken fetch is retried on request rather than in a loop. diff --git a/packages/domain/src/feature-flags.ts b/packages/domain/src/feature-flags.ts index 7f1902f91..e0fdcce75 100644 --- a/packages/domain/src/feature-flags.ts +++ b/packages/domain/src/feature-flags.ts @@ -33,6 +33,13 @@ export const defaultFeatureFlags: FeatureFlags = { * Measured on real threads a build costs ~0.06ms/event across the SQLite * read, JSON decode, and projection. 1500 keeps a cold build near 100ms; the * 10k-event thread that motivated the bound was ~670ms unbounded. + * + * That per-event cost is hardware dependent and the spread is wide: on a + * 4-core / 4.9 GiB VPS it measures 0.479ms/event at p50 (p90 0.964, + * max 5.55) across 541 samples, roughly 8x the figure above, which puts a + * full 1500-event build near 720ms of blocked event loop rather than 100ms. + * Operators on modest hardware should lower this via + * BB_FF_TIMELINE_WINDOW_EVENT_BUDGET; see docs/configuration.md. */ timelineWindowEventBudget: 1_500, };