Discipline for performance investigations. Ramp up from cheap experiments to expensive ones. Profile before patching. Isolate hypotheses with standalone probes before touching production code. Numbers gate every decision. Use when the user says `/perf`, asks to speed up code, or asks why something is slow.
Ramp up. Every investigation starts with the cheapest experiment that can falsify your current theory and moves to more invasive ones only when the cheap ones are exhausted or inconclusive. The bottleneck is almost never where you first guess. Numbers gate every decision.
strace -f -c -p $PID for ~10 s during the workload. Gives a syscall histogram. Confirms whether the op is syscall-bound and which call dominates.perf record -g for CPU attribution; bpftrace histograms for syscall latency tails.When an investigation completes, report in the /simple shape:
Problem: [root cause from baseline + trace + probe].
Evidence: [numbers. baseline, probe, and any confirming traces].
Proposal: [one concrete change].
Mechanism: [why the change moves the number].
Test: [bench that confirms or falsifies the fix, with failure criteria].If you have not reached Problem yet, you are still on the ladder. Keep measuring.
Baseline + concurrency sweep (bash, no deps):
DIR=/mnt/$fs/bench
for par in 1 4 16 64; do
rm -rf "$DIR/par$par" && mkdir "$DIR/par$par"
t=$(date +%s%3N)
for w in $(seq 1 $par); do
( mkdir -p "$DIR/par$par/w$w" && cd "$DIR/par$par/w$w"
for i in $(seq 1 $((1000/par))); do echo x > f$i; done ) &
done
wait
echo "par=$par: $(($(date +%s%3N) - t))ms"
doneStrace the daemon during a workload:
PID=$(pgrep -f <daemon-name>)
sudo strace -f -c -p $PID -o /tmp/strace.out &
STRACE=$!
# ... run workload ...
sudo kill -INT $STRACE && wait $STRACE 2>/dev/null
cat /tmp/strace.outIsolated probe shape: a standalone Cargo project in /tmp/<name>/ with the same pragmas, schema, or config as production. Three to five regimes, each timed with Instant::now(), report median of three runs plus min/max. Commit to scripts/bench/<name>/ only if the probe earns a spot in regular CI.
Baseline: dedalus-fs 1K seq creates = 470 ms vs ext4 18 ms (26×).
Concurrency sweep: par=1 → 532 ms, par=4 → 311 ms, par=16 → 251 ms, par=64 → 262 ms. Floor at ~260 ms. Serial penalty ~270 ms, parallel floor ~260 ms: two distinct cost buckets.
Strace of daemon during 1K creates: 24 pwrite64 per create (WAL frame writes), 28 futex per create (mutex + tokio). Syscall-bound.
Hypothesis: per-op SQL transaction is the parallel floor (each op writes its own WAL commit frame). Fast-op reference: ls -la (9 ms for 1000 files) wins by doing one big SQL query — batching is the borrowed technique.
Isolated probe (/tmp/tx-probe/): same WAL+NORMAL pragmas, same schema, N=1000 creates under per-op-tx vs batch-of-8/32/64/128/256 vs one giant tx. Per-op = 99 ms. Any batched = 22–26 ms. One giant tx = 22 ms. Ceiling: 4.5× speedup, flat past batch=8.
Proposal: wrap each coalescer batch drain in one SQL transaction; per-op work uses SAVEPOINT for rollback isolation.
Stopped-because: parent-mtime coalescing probe added <5% further; not worth the complexity.
/perfmake-interfaces-feel-better.