docs/PERFORMANCE_TESTING.md
This guide covers beads' performance testing framework, including running benchmarks, profiling, and diagnosing performance issues.
The beads performance testing framework provides:
bd doctor --perf for end-user performance analysisPerformance issues typically only manifest at scale (10K+ issues), so benchmarks focus on large databases.
make bench
This runs all benchmarks with:
-benchtime=1s)Output includes:
ns/op - Nanoseconds per operationallocs/op - Memory allocations per operationFor faster iteration during development:
make bench-quick
Uses shorter benchmark time (100ms) for quicker feedback.
# Run only GetReadyWork benchmarks
go test -bench=BenchmarkGetReadyWork -benchtime=1s -tags=bench -run=^$ ./internal/storage/dolt/
# Run only Large (10K) benchmarks
go test -bench=Large -benchtime=1s -tags=bench -run=^$ ./internal/storage/dolt/
BenchmarkGetReadyWork_Large-8 1234 812345 ns/op 12345 B/op 123 allocs/op
| Field | Meaning |
|---|---|
-8 | Number of CPU cores used |
1234 | Number of iterations run |
812345 ns/op | ~0.8ms per operation |
12345 B/op | Bytes allocated per operation |
123 allocs/op | Heap allocations per operation |
Performance Targets:
GetReadyWork: < 50ms on 20K databaseSearchIssues: < 100ms on 20K databaseCreateIssue: < 10msBenchmarks automatically generate CPU profiles:
# Run benchmarks (generates profile)
make bench
# View profile in browser (flamegraph)
cd internal/storage/sqlite
go tool pprof -http=:8080 bench-cpu-*.prof
This opens an interactive web UI at http://localhost:8080 with:
Common hotspots in database operations:
For memory-focused analysis:
# Generate memory profile
go test -bench=BenchmarkGetReadyWork_Large -benchtime=1s -tags=bench -run=^$ \
-memprofile=mem.prof ./internal/storage/dolt/
# View memory profile
go tool pprof -http=:8080 mem.prof
Look for:
bd doctor --perfEnd users can run performance diagnostics:
bd doctor --perf
This:
When reporting performance issues:
bd doctor --perf.prof file to the bug reportPerformance Diagnostics
=======================
Database size: 15,234 issues
GetReadyWork: 45ms [OK]
SearchIssues: 78ms [OK]
CreateIssue: 8ms [OK]
CPU profile saved: beads-perf-2024-01-15-143022.prof
Status indicators:
[OK] - Within acceptable range[SLOW] - Slower than expected, may need investigation[CRITICAL] - Significantly degraded, likely a bugInstall benchstat:
go install golang.org/x/perf/cmd/benchstat@latest
Compare before/after:
# Save baseline
go test -bench=. -count=5 -tags=bench -run=^$ ./internal/storage/dolt/ > old.txt
# Make changes, then run again
go test -bench=. -count=5 -tags=bench -run=^$ ./internal/storage/dolt/ > new.txt
# Compare
benchstat old.txt new.txt
Output shows:
Example:
name old time/op new time/op delta
GetReadyWork_Large-8 812µs ± 2% 654µs ± 1% -19.46% (p=0.000 n=5+5)
A change is significant if:
-count=5 or more)| Use Case | Tool |
|---|---|
| "Is this fast enough?" | Benchmark |
| "Why is this slow?" | Profile |
| "Did my change help?" | benchstat |
| "User reports slowness" | bd doctor --perf |
append in loopsEXPLAIN QUERY PLAN for slow queriesPRAGMA optimize after large importsRemove benchmark artifacts:
make clean
This removes:
bench-cpu-*.prof)beads-perf-*.prof)/tmp/beads-bench-cache/To clear cached databases:
rm -rf /tmp/beads-bench-cache/