Skip to content

Benchmarks

Benchmarks are for performance-sensitive code paths where regressions are easy to miss in correctness tests: repoindex search, CAS storage, DB scan helpers, execution setup, domain builders, and shared time utilities.

Terminal window
bun run bench:go

The runner writes a timestamped copy of the output under /private/tmp/foxctl-benchmarks/ and prints the path at the end.

Use environment variables to keep local experiments repeatable:

VariableDefaultPurpose
BENCH_COUNT3Number of benchmark samples per package
BENCH_TIME1sPer-benchmark timing target passed to go test
BENCH_PATTERN.Regex for matching benchmark names
BENCH_OUTtimestamped file in /private/tmpOutput capture path

Example focused run:

Terminal window
BENCH_COUNT=5 BENCH_TIME=2s BENCH_PATTERN=Repoindex bun run bench:go ./internal/intelligence/indexing/repoindex

The default suite covers packages that already contain benchmarks:

PackageWhy it is included
./internal/domain/agentAgent profile and builder allocation behavior
./internal/intelligence/indexing/repoindexSearch, scoring, fallback, and query paths
./internal/platform/timeutilShared time formatting and parsing helpers
./internal/runtime/execution/execCommand execution setup and hot-path overhead
./internal/storage/casContent-addressed storage write/read behavior
./internal/storage/dbutilScan helper overhead for storage rows

Add a package to scripts/run-go-benchmarks.sh only when the benchmark protects a known hot path or a previously regressed operation. Keep benchmark inputs deterministic, avoid network access, and prefer explicit fixtures over host machine state.

The benchmark suite is organized around concrete performance risks:

SolutionProtected behaviorSignal to watch
Curated runnerKeeps benchmark invocation repeatable across local agents and CI-style checksCommand exits cleanly and captures output path
Repoindex search benchmarksProtects zero-result fallback, scored search, syntax fallback, and query allocation behaviorns/op, B/op, and allocs/op drift
CAS buffer benchmarksProtects write/read buffering and large artifact handlingThroughput and allocation drift
Slice preallocation benchmarksGuards against accidental allocation regressions in hot storage loopsAllocation count changing from zero
Context cancellation benchmarksMakes cancellation checks visible in storage loopsUnexpected overhead or behavior drift
DB scan helper benchmarksProtects timestamp and JSON row scan helper costB/op and allocs/op drift
Time utility benchmarksKeeps common time format/parse helpers honestAllocation-free parsing stays allocation-free

When a benchmark fails or drifts, fix the underlying hot path first. Update the benchmark only when the new behavior is intentional and the docs explain the new expected cost.

The latest local benchmark evidence is saved under /private/tmp/foxctl-benchmarks/. These numbers are homepage-ready only with the caveats shown here. Add future rows to this table when a run has a saved artifact, a product signal, and an explicit caveat.

The current shell-output artifact is /private/tmp/foxctl-benchmarks/command-output-counts-20260514T0725-broader-command-output-counts.json. Each row runs the native binary and foxctl shell reduction on the same task.

BinarySame taskNative outputfoxctl outputOutput reduction
lsls -la internal483 tokens / 1,002 bytes30 tokens / 106 bytes93.8% less
findfind internal/tooling -name '*.go'825 tokens / 3,061 bytes66 tokens / 237 bytes92.0% less
catcat go.mod7,520 tokens / 19,723 bytes1,011 tokens / 2,216 bytes86.6% less
headhead -n 80 cmd/foxctl/cmd/shell.go679 tokens / 2,680 bytes580 tokens / 2,245 bytes14.6% less
tailtail -n 80 cmd/foxctl/cmd/shell.go655 tokens / 2,376 bytes623 tokens / 2,245 bytes4.9% less
grepgrep -rn 'func ' internal/tooling/shellreduce4,779 tokens / 18,632 bytes53 tokens / 209 bytes98.9% less
sedsed -n '1,120p' cmd/foxctl/cmd/shell.go1,148 tokens / 4,617 bytes556 tokens / 2,216 bytes51.6% less
git statusgit status --short1,422 tokens / 5,095 bytes72 tokens / 215 bytes94.9% less
git diffgit diff --stat1,760 tokens / 6,458 bytes182 tokens / 503 bytes89.7% less
git diffgit diff --name-only1,313 tokens / 4,755 bytes225 tokens / 768 bytes82.9% less
git loggit log --stat -53,303 tokens / 11,464 bytes89 tokens / 337 bytes97.3% less
go testgo test ./internal/tooling/shellreduce22 tokens / 68 bytes14 tokens / 41 bytes36.4% less
TotalTwelve command-output rows where foxctl reduced output23,910 tokens / 79,932 bytes3,501 tokens / 11,338 bytes85.4% less

These are output-size numbers, not a cold latency claim. The product table is limited to command rows with measured output reductions. The broader run also exposed a router gap: rg -m / rg --max-count is not accepted yet even though the equivalent grep case works.

SurfaceCurrent resultSignalCaveat
Context gather31.4x faster evidence path6.50s, path recall 0.86, fact recall 1.00One dirty-worktree case; comparison artifact is kept in the eval notes
Runtime hot path96.5ns runner, around 4us shell route, around 415ns shell summaryHot in-process overhead stays allocation-visibleSeparate from cold CLI startup and subprocess cost
Repoindex / DAGSub-millisecond search fallback, around 691us DAG structural grepGraph retrieval latency stays visible in Go benchesFixture result, not full-workspace indexing time
Repoindex refresh30.96s-54.20s samples, 1,813 files, 31,665 nodes, 141,648 edgesRepoindex freshness verified current after each runIncremental detection works; global-edge rebuild still falls back to full

Use the conservative version of these claims on the homepage: foxctl can make agent context smaller and more auditable, and the Go hot paths are cheap. Do not claim every foxctl wrapper is faster than native shell. Treat the local context gather row as a narrow evidence-path smoke. Baseline accounting and provider-backed comparison artifacts live in docs/general/code-search-evals.md#native-subagent-baselines.