BENCHMARKS.md
This document describes the performance benchmarks available in the beads project and how to use them.
go test -tags=bench -bench=. -benchmem ./internal/storage/dolt/...
go test -tags=bench -bench=BenchmarkGetReadyWork_Large -benchmem ./internal/storage/dolt/...
go test -tags=bench -bench=BenchmarkGetReadyWork_Large -cpuprofile=cpu.prof ./internal/storage/dolt/...
go tool pprof -http=:8080 cpu.prof
Tests on graphs with different topologies (linear chains, trees, dense graphs):
| Operation | Time | Memory | Notes |
|---|---|---|---|
| GetReadyWork (10K) | 30ms | 16.8MB | Filters ~200 open issues |
| Search (10K, no filter) | 12.5ms | 6.3MB | Returns all open issues |
| Cycle Detection (5000 linear) | 70ms | 15KB | Detects transitive deps |
| Create Issue (10K db) | 2.5ms | 8.9KB | Insert into index |
| Update Issue (10K db) | 18ms | 17KB | Status change |
| Large Description (100KB) | 3.3ms | 874KB | String handling overhead |
| Bulk Close (100 issues) | 1.9s | 1.2MB | 100 sequential writes |
| Sync Merge (20 ops) | 29ms | 198KB | Create 10 + update 10 |
Benchmark datasets are cached in /tmp/beads-bench-cache/:
large.db - 10,000 issues (16.6 MB)xlarge.db - 20,000 issues (generated on demand)Cached databases are reused across runs. To regenerate:
rm /tmp/beads-bench-cache/*.db
Follow the pattern in sqlite_bench_test.go:
// BenchmarkMyTest benchmarks a specific operation
func BenchmarkMyTest(b *testing.B) {
runBenchmark(b, setupLargeBenchDB, func(store *SQLiteStorage, ctx context.Context) error {
// Your test code here
return err
})
}
Or for custom setup:
func BenchmarkMyTest(b *testing.B) {
store, cleanup := setupLargeBenchDB(b)
defer cleanup()
ctx := context.Background()
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
// Your test code here
}
}
The benchmark suite automatically enables CPU profiling on the first benchmark run:
CPU profiling enabled: bench-cpu-2025-12-07-174417.prof
View flamegraph: go tool pprof -http=:8080 bench-cpu-2025-12-07-174417.prof
This generates a flamegraph showing where time is spent across all benchmarks.
Example:
# Baseline
go test -tags=bench -bench=BenchmarkGetReadyWork_Large -benchmem ./internal/storage/dolt/...
# Make changes...
# Measure improvement
go test -tags=bench -bench=BenchmarkGetReadyWork_Large -benchmem ./internal/storage/dolt/...