the write-latency bench takes the repos to write to, and records a repo with many writes
Signed-off-by: dawn <90008@klbr.net>
70 unmodified lines717273747575767778798071 unmodified lines70 unmodified lines
ks() { "$bin" --config "$1" "${@:2}"; }# one issue to comment on in each of up to five repos the owner can write astouch "$fx/issues"for repo in $(ks "$fx/quiet.toml" repo list | awk '{ print $4 }'); do# BENCH_REPOS picks them, e.g. a repo seeded with many writes firstfor repo in ${BENCH_REPOS:-$(ks "$fx/quiet.toml" repo list | awk '{ print $4 }')}; do number=$( (ks "$fx/quiet.toml" issue new "$repo" --title "write latency" --body bench 2>/dev/null || true) | sed -n 's|.*org.tangled.track.ticket/\([^"]*\)".*|\1|p' | head -n 1) [ -n "$number" ] && echo "$repo $number" >>"$fx/issues" [ "$(wc -l <"$fx/issues")" -lt 5 ] || break71 unmodified lines16 unmodified lines17181920212223242526272821 unmodified lines505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989916 unmodified lines- 2 / 5 concurrent: writes started together to different repos (up to 5 that take an owner issue) or all to one.- huge repo (a kernel-sized knot): not run. prod hosts nothing near that size.
`BENCH_REPOS="r1 r2 ..."` picks the repos (the first takes the single-writer scenarios). before eachrun here, `gc --force` cleared what earlier runs retired: every write retires a generation, anduntil gc can tell nothing still reads them they wait out the drain window and pile up.
## 2026-11-10, mac (Apple M5, 10 cores, 24 GB, apfs), fc741ae release, no mbx
3-repo fixture (`--fixture 3`):
21 unmodified lines| 5 concurrent, same | 5604 | 28598 | 43230 |
concurrent writes queue on the output lock, behind each other's builds and each write's detachedgc + hook diff.
## 2026-11-10, chernobog (Ryzen 5 5600, 12 threads, btrfs), fc741ae nix build, 6G fence, nice 19
92-repo clone of site-work:
| scenario | med ms | p95 ms ||---|---|---|| quiet | 651 | 670 || mid-render | 868 | 873 || during-drain | 737 | 909 || first-after-deploy | 747 | 781 || 2 concurrent, different | 1715 | 2232 || 2 concurrent, same | 1541 | 1624 || 5 concurrent, different | 4515 | 4626 || 5 concurrent, same | 4134 | 4323 |
## a repo that took many writes, chernobog
a 5-repo fixture whose r1 took N owner comments one write at a time (`seed.sh`, not committed),nix builds of 5f72bd9 (before) and c79f9ca (after: an export merges the packs past its framedreplies geometrically). each write used to add a pack to r1's export for good.
| | before | after ||---|---|---|| r1 export packs at 500 writes | 807 | 7 || r1 export packs at 2000 writes | 2036 | 7 || one comment on r1 at 500 writes | 0.77-0.83 s | 0.48-0.64 s |
the scenario bench at 2000 writes, r1 first:
| scenario | before med / p95 ms | after med / p95 ms ||---|---|---|| quiet | 2591 / 2760 | 1180 / 1189 || mid-render | 3049 / 3155 | 1190 / 1219 || during-drain | 3258 / 3349 | 1223 / 1462 || first-after-deploy | 3524 / 3665 | 1266 / 1297 || 2 concurrent, different | 2560 / 5599 | 1606 / 2501 || 2 concurrent, same | 4187 / 4299 | 2393 / 2468 || 5 concurrent, different | 5954 / 7647 | 4069 / 5143 || 5 concurrent, same | 5555 / 5684 | 3672 / 3802 |
a comment on r1 still costs more than on a fresh repo (1.2 s against 0.23 s): what else grows with arepo's write count is the next thing to profile.
concurrent writes share builds already: of five at once, some build and the rest find their changebuilt by a later one. they wait out about two builds, so they speed up with the build itself.