Server test: Calendar write p95 over 10 s with 20k files #1441

Closed
opened 2026-10-08 04:21:46 +00:00 by kayg · 14 comments
Owner

Problem

The server unit test search_reconcile_calendar_write_profile (20,000 files, 32 Calendar writes) exceeded its 10 s p95 budget in two independent job runs on 2026-10-08 against origin/dev d395b6e25 / ef0aa12b1:

  • mail7c (#1340): p50 12,344 ms, p95 12,800 ms
  • mailhtml2 (#1372): p50 14,010 ms, p95 14,210 ms

Both ran on a heavily loaded build host (load 25–35), and neither touched Calendar or Search code. It may be host load or a real regression in the Search reconcile path during Calendar writes.

Work

  1. Run the test on the perf VM (quiet host; flock /root/perf.lock; copy a release test binary built on the build host) 5 times on origin/dev and on the last commit where it passed (find it with git log on the test and the reconcile code; bisect if needed). Report p50/p95 for each.
  2. If it is a regression, fix the cause (each Calendar write must not trigger work proportional to 20k files). If it is load only, make the test robust: measure CPU time or count reconcile work units instead of wall time, keeping the budget meaningful. Do not just raise the budget.

Gates: cargo fmt --check, cargo clippy --all-targets -- -D warnings, cargo test -p calternal-server. Quote verbatim.

## Problem The server unit test `search_reconcile_calendar_write_profile` (20,000 files, 32 Calendar writes) exceeded its 10 s p95 budget in two independent job runs on 2026-10-08 against origin/dev d395b6e25 / ef0aa12b1: - mail7c (#1340): p50 12,344 ms, p95 12,800 ms - mailhtml2 (#1372): p50 14,010 ms, p95 14,210 ms Both ran on a heavily loaded build host (load 25–35), and neither touched Calendar or Search code. It may be host load or a real regression in the Search reconcile path during Calendar writes. ## Work 1. Run the test on the perf VM (quiet host; `flock /root/perf.lock`; copy a release test binary built on the build host) 5 times on origin/dev and on the last commit where it passed (find it with `git log` on the test and the reconcile code; bisect if needed). Report p50/p95 for each. 2. If it is a regression, fix the cause (each Calendar write must not trigger work proportional to 20k files). If it is load only, make the test robust: measure CPU time or count reconcile work units instead of wall time, keeping the budget meaningful. Do not just raise the budget. Gates: cargo fmt --check, cargo clippy --all-targets -- -D warnings, cargo test -p calternal-server. Quote verbatim.
Author
Owner

Starting #1441 on branch job/calwrite-1441, based on origin/dev at d395b6e25da20d8c67b8b9fc1a593b813939c8a7. I am tracing the profile test and reconcile history, then I will compare five release runs of this revision with five runs at the latest passing revision on the perf VM.

Starting #1441 on branch `job/calwrite-1441`, based on `origin/dev` at `d395b6e25da20d8c67b8b9fc1a593b813939c8a7`. I am tracing the profile test and reconcile history, then I will compare five release runs of this revision with five runs at the latest passing revision on the perf VM.
Author
Owner

Finding from repo history: docs/audits/merge-round-7c2.md records the debug test at head 7522dc0bbec8d5c321cab5c5be16ee0e710e4c22 with p50 11,758 ms and p95 12,234 ms. review-1153.md records p50 12,052 ms and p95 12,373 ms, and explicitly labels the profile failure SLOW-only. Both outputs are from build-host runs; I am checking release binaries on the perf VM before deciding whether Search changed.

Finding from repo history: `docs/audits/merge-round-7c2.md` records the debug test at head `7522dc0bbec8d5c321cab5c5be16ee0e710e4c22` with p50 11,758 ms and p95 12,234 ms. `review-1153.md` records p50 12,052 ms and p95 12,373 ms, and explicitly labels the profile failure SLOW-only. Both outputs are from build-host runs; I am checking release binaries on the perf VM before deciding whether Search changed.
Author
Owner

Perf VM status check: perf-run status reported held: calternal searchperf-1425-ready ... expected_min=20. I did not run a benchmark while it was occupied. The current test binary is still building locally; I will recheck availability when both revisions are ready and use the lock-managed profile runner.

Perf VM status check: `perf-run status` reported `held: calternal searchperf-1425-ready ... expected_min=20`. I did not run a benchmark while it was occupied. The current test binary is still building locally; I will recheck availability when both revisions are ready and use the lock-managed profile runner.
Author
Owner

The perf VM remains occupied by calternal calscroll1362-baseline-23db61c69 (perf-run status reports expected_min=35). Per the shared perf rule, I will use local release runs for both revisions and record the build-host load; I will not overlap the VM phase or wait for it to become idle.

The perf VM remains occupied by `calternal calscroll1362-baseline-23db61c69` (`perf-run status` reports `expected_min=35`). Per the shared perf rule, I will use local release runs for both revisions and record the build-host load; I will not overlap the VM phase or wait for it to become idle.
Author
Owner

Build prerequisite found: cargo test --release -p calternal-server --bin calternal-server --no-run cannot compile RustEmbed because apps/web/build/ is absent (main.rs:109); the follow-on Frontend::get errors come from that missing directory. I will create the production assets with bun run build and remove the build output after the Rust gates.

Build prerequisite found: `cargo test --release -p calternal-server --bin calternal-server --no-run` cannot compile `RustEmbed` because `apps/web/build/` is absent (`main.rs:109`); the follow-on `Frontend::get` errors come from that missing directory. I will create the production assets with `bun run build` and remove the build output after the Rust gates.
Author
Owner

The required production web build then failed because Node could not resolve @excalidraw/excalidraw from apps/web/scripts/canvas-assets.mjs. I will restore the locked workspace dependencies with bun install --frozen-lockfile, rebuild assets, and retry.

The required production web build then failed because Node could not resolve `@excalidraw/excalidraw` from `apps/web/scripts/canvas-assets.mjs`. I will restore the locked workspace dependencies with `bun install --frozen-lockfile`, rebuild assets, and retry.
Author
Owner

Current-revision release measurement (local fallback; build-host load 34.92–35.75 in the first two runs): run 1 p95 was 6,446 ms, with 24.302 s whole-test CPU over 61.007 s wall. Run 2 p95 was 11,243 ms and failed the 10 s assertion, with 5.172 s whole-test CPU over 28.405 s wall. This shows substantial scheduler-sensitive wall variation, but I am completing all five samples and the historical comparison before classifying the cause.

Current-revision release measurement (local fallback; build-host load 34.92–35.75 in the first two runs): run 1 p95 was 6,446 ms, with 24.302 s whole-test CPU over 61.007 s wall. Run 2 p95 was 11,243 ms and failed the 10 s assertion, with 5.172 s whole-test CPU over 28.405 s wall. This shows substantial scheduler-sensitive wall variation, but I am completing all five samples and the historical comparison before classifying the cause.
Author
Owner

All five current-revision (d395b6e25) release runs are complete on the local fallback host. Per-run (p50_ms, p95_ms): (6238, 6446), (10890, 11243), (6675, 6990), (7724, 7920), (8828, 9343). Loads were 35.75, 34.92, 38.12, 45.56 and 35.19. Median per-run p50 was 7,724 ms; median p95 was 7,920 ms; max p95 was 11,243 ms. Only run 2 failed the wall assertion. Its whole-test CPU was 5.172 s over 28.405 s wall; other full-test CPU/wall pairs were 24.302/61.007, 34.841/85.109, 28.455/55.838 and 28.241/63.697 seconds. This is consistent with host-load-sensitive wall latency. I am measuring CPU only during the concurrent write window in the test change; historical A/B remains to run.

All five current-revision (`d395b6e25`) release runs are complete on the local fallback host. Per-run `(p50_ms, p95_ms)`: (6238, 6446), (10890, 11243), (6675, 6990), (7724, 7920), (8828, 9343). Loads were 35.75, 34.92, 38.12, 45.56 and 35.19. Median per-run p50 was 7,724 ms; median p95 was 7,920 ms; max p95 was 11,243 ms. Only run 2 failed the wall assertion. Its whole-test CPU was 5.172 s over 28.405 s wall; other full-test CPU/wall pairs were 24.302/61.007, 34.841/85.109, 28.455/55.838 and 28.241/63.697 seconds. This is consistent with host-load-sensitive wall latency. I am measuring CPU only during the concurrent write window in the test change; historical A/B remains to run.
Author
Owner

CPU-gated profile change committed as 19bd11125 (test(search): gate calendar writes on CPU work). The updated release test passed: files=20000 writes=32 p50_ms=13042 p95_ms=13721 p95_budget_ms=10000 write_window_cpu_ms=1405 cpu_work_budget_ms=20000. The wall p95 exceeded its diagnostic target on the loaded build host, while the measured concurrent write window used 1.405 CPU seconds. Next I am building the historical b8e8d8a revision and running the same five-run local comparison; the perf VM remains occupied.

CPU-gated profile change committed as `19bd11125` (`test(search): gate calendar writes on CPU work`). The updated release test passed: `files=20000 writes=32 p50_ms=13042 p95_ms=13721 p95_budget_ms=10000 write_window_cpu_ms=1405 cpu_work_budget_ms=20000`. The wall p95 exceeded its diagnostic target on the loaded build host, while the measured concurrent write window used 1.405 CPU seconds. Next I am building the historical `b8e8d8a` revision and running the same five-run local comparison; the perf VM remains occupied.
Author
Owner

Historical/current comparison is complete locally (perf VM remained held by calscroll1362-baseline-23db61c69). I used commit b8e8d8af2eb79d95012b1b5f261428d3cee34f72, which introduced this test; its parent does not contain the profile.

  • Current d395b6e25 original wall-gated test: five p95 samples 6,446 / 11,243 / 6,990 / 7,920 / 9,343 ms; median 7,920 ms, one failure. Run-start load averages were 34.92–45.56 (one run began at 35.75).
  • Historical b8e8d8a wall-gated test: five p95 samples 9,176 / 8,296 / 3,953 / 11,745 / 4,337 ms; median 8,296 ms, one failure. Run-start load averages were 28.06–39.34.
  • These samples show no wall-latency regression at current dev; both revisions have similar medians and each failed once under high, varying host load. The failure is load-sensitive.
  • Updated current release test passed with wall p95 13,721 ms and write-window process CPU 1,405 ms against a 20,000 ms budget. The assertion now gates CPU work over the concurrent write window; it retains wall p50/p95 as diagnostics.

The 20,000 ms budget is 1 ms per fixture path for the 20,000-file Home, keeping room for ordinary DB work while catching repeated full-Home work for each of the 32 writes. I will run the final per-crate gates after the required one-time merge from origin/dev.

Historical/current comparison is complete locally (perf VM remained held by `calscroll1362-baseline-23db61c69`). I used commit `b8e8d8af2eb79d95012b1b5f261428d3cee34f72`, which introduced this test; its parent does not contain the profile. - Current `d395b6e25` original wall-gated test: five p95 samples 6,446 / 11,243 / 6,990 / 7,920 / 9,343 ms; median 7,920 ms, one failure. Run-start load averages were 34.92–45.56 (one run began at 35.75). - Historical `b8e8d8a` wall-gated test: five p95 samples 9,176 / 8,296 / 3,953 / 11,745 / 4,337 ms; median 8,296 ms, one failure. Run-start load averages were 28.06–39.34. - These samples show no wall-latency regression at current `dev`; both revisions have similar medians and each failed once under high, varying host load. The failure is load-sensitive. - Updated current release test passed with wall p95 13,721 ms and write-window process CPU 1,405 ms against a 20,000 ms budget. The assertion now gates CPU work over the concurrent write window; it retains wall p50/p95 as diagnostics. The 20,000 ms budget is 1 ms per fixture path for the 20,000-file Home, keeping room for ordinary DB work while catching repeated full-Home work for each of the 32 writes. I will run the final per-crate gates after the required one-time merge from `origin/dev`.
Author
Owner

The updated CPU-gated profile also passed all five local release runs on the current source. Write-window CPU ms: 1543 / 1386 / 1098 / 1153 / 1451 (median 1386, max 1543) against the 20000 ms budget. The corresponding diagnostic wall p95 ms: 12918 / 7945 / 9997 / 7641 / 16488 (median 9997). Every run passed even where wall p95 exceeded the original 10000 ms threshold. I am now doing the single required git fetch origin && git merge origin/dev, then I will run the crate gates once.

The updated CPU-gated profile also passed all five local release runs on the current source. Write-window CPU ms: 1543 / 1386 / 1098 / 1153 / 1451 (median 1386, max 1543) against the 20000 ms budget. The corresponding diagnostic wall p95 ms: 12918 / 7945 / 9997 / 7641 / 16488 (median 9997). Every run passed even where wall p95 exceeded the original 10000 ms threshold. I am now doing the single required `git fetch origin && git merge origin/dev`, then I will run the crate gates once.
Author
Owner

#1441 is complete on branch job/calwrite-1441.

Built: Updated the ignored 20,000-file startup Search reconciliation / Calendar write profile to report wall p50/p95 but gate process CPU consumed during the 32-write overlap. The CPU budget is one millisecond per fixture path (20,000 ms total), which remains meaningful for detecting repeated full-Home work without depending on scheduler delay. The helper uses getrusage(RUSAGE_SELF), so it includes the Tokio worker threads.

Files: crates/calternal-server/src/wire.rs only.

A/B evidence (local release binaries; the perf VM was occupied): The pre-change d395b6e25 test ran five times with p95 6,446 / 11,243 / 6,990 / 7,920 / 9,343 ms (median 7,920 ms; one wall-budget failure). Historical b8e8d8a (the commit that introduced this profile; its parent has no test) ran five times with p95 9,176 / 8,296 / 3,953 / 11,745 / 4,337 ms (median 8,296 ms; one wall-budget failure). Run-start load averages ranged 28.06–45.56. The close medians and failures on both revisions point to scheduler-sensitive wall timing, not a current Search regression.

The updated current test passed five times. Write-window process CPU was 1,543 / 1,386 / 1,098 / 1,153 / 1,451 ms (median 1,386 ms; max 1,543 ms). Diagnostic wall p95 was 12,918 / 7,945 / 9,997 / 7,641 / 16,488 ms (median 9,997 ms). Each run passed the CPU budget, including runs above the former 10,000 ms wall limit.

Gates (after merging origin/dev):

  • cargo fmt --check — exit 0; no output.
  • cargo clippy -p calternal-server --all-targets -- -D warnings — output: Finished dev profile [unoptimized + debuginfo] target(s) in 19m 14s; exit 0.
  • cargo test -p calternal-server — output:
    • test result: ok. 272 passed; 0 failed; 12 ignored; 0 measured; 0 filtered out; finished in 216.06s
    • test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 53.96s
    • test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.00s
    • exit 0.

Decisions: DESIGN did not set a machine-independent work budget or measurement method for this profile. I used process CPU during the write overlap and set a fixture-scaled budget of 1 ms per file. Wall latency remains visible for diagnosis.

Known gap: The requested quiet perf-VM runs were not possible because another benchmark job held its lock. The local host was heavily loaded, so quiet-host latency numbers remain unavailable; local evidence shows both revisions have similar wall medians.

Commits: 19bd11125 (test(search): gate calendar writes on CPU work), followed by the required merge from origin/dev. Final HEAD: 93d059edcc3ab269ea55b807956e23a45994041f.

#1441 is complete on branch `job/calwrite-1441`. **Built:** Updated the ignored 20,000-file startup Search reconciliation / Calendar write profile to report wall p50/p95 but gate process CPU consumed during the 32-write overlap. The CPU budget is one millisecond per fixture path (20,000 ms total), which remains meaningful for detecting repeated full-Home work without depending on scheduler delay. The helper uses `getrusage(RUSAGE_SELF)`, so it includes the Tokio worker threads. **Files:** `crates/calternal-server/src/wire.rs` only. **A/B evidence (local release binaries; the perf VM was occupied):** The pre-change `d395b6e25` test ran five times with p95 6,446 / 11,243 / 6,990 / 7,920 / 9,343 ms (median 7,920 ms; one wall-budget failure). Historical `b8e8d8a` (the commit that introduced this profile; its parent has no test) ran five times with p95 9,176 / 8,296 / 3,953 / 11,745 / 4,337 ms (median 8,296 ms; one wall-budget failure). Run-start load averages ranged 28.06–45.56. The close medians and failures on both revisions point to scheduler-sensitive wall timing, not a current Search regression. The updated current test passed five times. Write-window process CPU was 1,543 / 1,386 / 1,098 / 1,153 / 1,451 ms (median 1,386 ms; max 1,543 ms). Diagnostic wall p95 was 12,918 / 7,945 / 9,997 / 7,641 / 16,488 ms (median 9,997 ms). Each run passed the CPU budget, including runs above the former 10,000 ms wall limit. **Gates (after merging `origin/dev`):** - `cargo fmt --check` — exit 0; no output. - `cargo clippy -p calternal-server --all-targets -- -D warnings` — output: `Finished `dev` profile [unoptimized + debuginfo] target(s) in 19m 14s`; exit 0. - `cargo test -p calternal-server` — output: - `test result: ok. 272 passed; 0 failed; 12 ignored; 0 measured; 0 filtered out; finished in 216.06s` - `test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 53.96s` - `test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.00s` - exit 0. **Decisions:** DESIGN did not set a machine-independent work budget or measurement method for this profile. I used process CPU during the write overlap and set a fixture-scaled budget of 1 ms per file. Wall latency remains visible for diagnosis. **Known gap:** The requested quiet perf-VM runs were not possible because another benchmark job held its lock. The local host was heavily loaded, so quiet-host latency numbers remain unavailable; local evidence shows both revisions have similar wall medians. **Commits:** `19bd11125` (`test(search): gate calendar writes on CPU work`), followed by the required merge from `origin/dev`. Final HEAD: `93d059edcc3ab269ea55b807956e23a45994041f`.
Author
Owner

Supplement to the #1441 report: full per-run p50/p95 pairs in milliseconds, as requested.

  • Pre-change d395b6e25 (origin/dev): 6,238/6,446; 10,890/11,243; 6,675/6,990; 7,724/7,920; 8,828/9,343.
  • Historical b8e8d8a (test-introduction revision): 7,887/9,176; 7,487/8,296; 3,947/3,953; 11,727/11,745; 4,318/4,337.
  • Updated CPU-gated current test: 12,616/12,918; 7,797/7,945; 9,840/9,997; 7,417/7,641; 16,043/16,488. All five passed; write-window CPU was 1,543/1,386/1,098/1,153/1,451 ms.
Supplement to the #1441 report: full per-run p50/p95 pairs in milliseconds, as requested. - Pre-change `d395b6e25` (origin/dev): 6,238/6,446; 10,890/11,243; 6,675/6,990; 7,724/7,920; 8,828/9,343. - Historical `b8e8d8a` (test-introduction revision): 7,887/9,176; 7,487/8,296; 3,947/3,953; 11,727/11,745; 4,318/4,337. - Updated CPU-gated current test: 12,616/12,918; 7,797/7,945; 9,840/9,997; 7,417/7,641; 16,043/16,488. All five passed; write-window CPU was 1,543/1,386/1,098/1,153/1,451 ms.
Author
Owner

Deployed to calternal.cloud in merge round 35b (build 9dc65437e, live 2026-10-09 ~11:07 IST). Closing.

Deployed to calternal.cloud in merge round 35b (build 9dc65437e, live 2026-10-09 ~11:07 IST). Closing.
kayg closed this issue 2026-10-09 05:36:31 +00:00
Commenting is not possible because the repository is archived.
No labels
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal-v0#1441
No description provided.