Perf: a leak soak scenario (#398) #435

Closed
kayg wants to merge 0 commits from issue/398-soak into dev
Owner

Part of #398, step 4: a leak soak as a harness scenario. Based on #417.

What

--soak-secs N runs once per Home size, last in the first warm run. It does two cycles. Each has a third of N of steady use, then a sixth of N idle.

  • Steady use, round after round:
    • 3 list pages;
    • a search;
    • 2 notes opened in the editor and 2 through the API;
    • 10 keystrokes typed and taken out again, with a save check;
    • a journal page.
  • Idle: nothing, measured once the rooms have closed.
  • Sampling: memory every 10 s, into soak-<notes>.tsv in the work folder.
  • What it reports:
    • soak.idle_ratchet: the second idle level minus the first, in MB. A leak shows up here.
    • soak.load_slope and soak.idle_slope, in MB per hour.
    • Levels: idle_rss_1, idle_rss_2, load_rss_max, peak.
  • Budgets: soak.idle_ratchet ≤ 5 MB and soak.idle_slope ≤ 20 MB/h. Both are targets, not gates.
  • Docs: docs/perf/budgets.md.

--soak-secs 1800 is the 30-minute soak.

Results, perf VM, 100k notes, 30 minutes, about 11,600 rounds

dev + 2 heaps all #398 PRs (#417 #418 #427 #428 #429)
idle after cycle 1 MB 120.6 65.1
idle after cycle 2 MB 144.6 73.0
idle ratchet MB +24.1 +7.9
idle slope MB/h 0 0
most under load MB 144.8 136.9

What this shows:

  • Under load, memory climbs on both builds. About 400 sample notes stay open and every keystroke stays in a note's history until its room closes.
  • With #398, memory comes back down when the rooms close. On dev it stays up.
  • Neither build moves while idle.
  • The +7.9 MB step between cycles isn't explained yet. It is a third of dev's step. The typed text also changes 400 notes and grows the search index and its typo vocabulary, so part of it is data. A follow-up soak with reading only, no typing, would separate data growth from a leak.

Checks: cargo fmt, clippy -D warnings, and the calternal-perf and workspace tests are clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T

Part of #398, step 4: a leak soak as a harness scenario. **Based on #417.** ## What `--soak-secs N` runs once per Home size, last in the first warm run. It does two cycles. Each has a third of N of steady use, then a sixth of N idle. - **Steady use, round after round:** - 3 list pages; - a search; - 2 notes opened in the editor and 2 through the API; - 10 keystrokes typed and taken out again, with a save check; - a journal page. - **Idle:** nothing, measured once the rooms have closed. - **Sampling:** memory every 10 s, into `soak-<notes>.tsv` in the work folder. - **What it reports:** - `soak.idle_ratchet`: the second idle level minus the first, in MB. A leak shows up here. - `soak.load_slope` and `soak.idle_slope`, in MB per hour. - Levels: `idle_rss_1`, `idle_rss_2`, `load_rss_max`, `peak`. - **Budgets:** `soak.idle_ratchet` ≤ 5 MB and `soak.idle_slope` ≤ 20 MB/h. Both are targets, not gates. - **Docs:** `docs/perf/budgets.md`. `--soak-secs 1800` is the 30-minute soak. ## Results, perf VM, 100k notes, 30 minutes, about 11,600 rounds | | dev + 2 heaps | all #398 PRs (#417 #418 #427 #428 #429) | |---|---|---| | idle after cycle 1 MB | 120.6 | **65.1** | | idle after cycle 2 MB | 144.6 | **73.0** | | idle ratchet MB | +24.1 | **+7.9** | | idle slope MB/h | 0 | 0 | | most under load MB | 144.8 | 136.9 | What this shows: - **Under load, memory climbs on both builds.** About 400 sample notes stay open and every keystroke stays in a note's history until its room closes. - **With #398, memory comes back down when the rooms close.** On dev it stays up. - **Neither build moves while idle.** - **The +7.9 MB step between cycles isn't explained yet.** It is a third of dev's step. The typed text also changes 400 notes and grows the search index and its typo vocabulary, so part of it is data. A follow-up soak with reading only, no typing, would separate data growth from a leak. Checks: `cargo fmt`, `clippy -D warnings`, and the `calternal-perf` and workspace tests are clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Memory: remove the whole-Home notes.list (#398)
Some checks failed
CI / server (pull_request) Successful in 33s
CI / rust (pull_request) Successful in 2m35s
CI / web (pull_request) Failing after 44m28s
44306033b1
`notes.list` without input built every note of the Home into one answer
(100,000 objects at 100k notes, hundreds of megabytes at once). The app
only asks for pages, and the form was deprecated "for one release".
Without input it now returns the first page of 50, like `{}`.

The perf harness no longer calls it: `home.first_list`, `home.list` and
`mem.after_list` are gone (`mem.after_first_page` instead), and the cold
run opens the Home with a first page (`cold.first_page`).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Perf: a leak soak scenario (#398)
Some checks failed
CI / server (pull_request) Successful in 29s
CI / rust (pull_request) Successful in 2m24s
CI / web (pull_request) Has been cancelled
c0dbe6ba9e
`--soak-secs N` adds a long stretch on one server, once per Home size:
two cycles, each a third of the time of steady use (pages, a search,
notes opened in the editor and through the API, keystrokes typed and
taken out again with a save check, a page of the journal, round after
round) and a sixth idle. Memory is sampled every 10 s into
`soak-<notes>.tsv`. A leak ratchets the idle level up from one cycle to
the next (`soak.idle_ratchet`); `soak.load_slope` and `soak.idle_slope`
show growth under load and while idle. `--soak-secs 1800` is the
30-minute soak.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Perf: a read-only soak (#398)
Some checks failed
CI / server (pull_request) Successful in 27s
CI / rust (pull_request) Failing after 2m24s
CI / web (pull_request) Failing after 41m45s
0873a7e060
`--soak-read-only` runs the soak without typing: no note, history or
search index grows, so a step in the idle level between the two cycles
is memory kept, not data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yyy8fQGxPLkLa8v8NXz7T
Author
Owner

Landed in dev via train m.

Landed in dev via train m.
kayg closed this pull request 2026-10-15 16:19:52 +00:00
Author
Owner

Added --soak-read-only: the soak opens and reads, but never types. Results at 100k on the perf VM, 30 minutes, about 53,000 rounds, with all #398 PRs:

  • idle after cycle 1: 57.0 MB;
  • idle after cycle 2: 55.9 MB, so the ratchet is −1.1 MB;
  • load slope 0.6 MB/h; idle slope 0.

The +7.9 MB step in the typing soak was data growth, not a leak.

Added `--soak-read-only`: the soak opens and reads, but never types. Results at 100k on the perf VM, 30 minutes, about 53,000 rounds, with all #398 PRs: - idle after cycle 1: 57.0 MB; - idle after cycle 2: 55.9 MB, so the ratchet is **−1.1 MB**; - load slope 0.6 MB/h; idle slope 0. The +7.9 MB step in the typing soak was data growth, not a leak.
Some checks failed
CI / server (pull_request) Successful in 27s
CI / rust (pull_request) Failing after 2m24s
CI / web (pull_request) Failing after 41m45s

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
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!435
No description provided.