Benchmarks
Cross-runtime comparison of gbash against GNU bash and alternative sandboxed-shell runtimes. Each scenario is run as an independent process invocation - measuring real end-to-end latency including startup, execution, and teardown.
Runtimes
| Runtime | Description |
|---|---|
| gbash | Native Go binary - the default runtime |
| GNU bash | Host system bash (unsandboxed baseline) |
| gbash-extras | gbash with awk, html-to-markdown, jq, sqlite3, yq pre-registered |
| gbash-node-wasm | gbash compiled to WebAssembly, run in Node.js |
| just-bash | Published npm package (just-bash@2.13.0) |
Runtime Results
Test Environment
| Machine | MacBook Pro (Mac15,8) |
| Chip | Apple M3 Max |
| Cores | 16 (12 performance + 4 efficiency) |
| Memory | 64 GB |
| OS | macOS 15.5 |
| Go | go1.26.1 darwin/arm64 |
| Runs per scenario | 50 |
| Generated | March 15, 2026 |
startup echo
Process start plus one simple command.
echo benchmark
| Runtime | Min | Median | p95 | Artifact Size |
|---|---|---|---|---|
gbash | 4.8ms | 5.3ms | 7.5ms | 14.0 MiB |
GNU bash | 4.0ms | 4.8ms | 6.1ms | 875.9 KiB |
gbash-extras | 7.8ms | 8.7ms | 13.2ms | 33.0 MiB |
gbash-node-wasm | 110.0ms | 120.5ms | 154.2ms | 19.3 MiB |
just-bash | 708.2ms | 778.4ms | 991.7ms | 131.1 MiB |
workspace inventory
Process start plus a pipe-free workspace inventory.
set -- $(find . -type f); echo $#(300 files, 16.7 KiB)
| Runtime | Min | Median | p95 | Artifact Size |
|---|---|---|---|---|
gbash | 12.2ms | 12.8ms | 13.7ms | 14.0 MiB |
GNU bash | 10.9ms | 12.1ms | 13.3ms | 875.9 KiB |
gbash-extras | 15.0ms | 15.5ms | 16.0ms | 33.0 MiB |
gbash-node-wasm | 157.9ms | 162.9ms | 165.6ms | 19.3 MiB |
just-bash | 772.4ms | 816.0ms | 950.9ms | 131.1 MiB |
agentic workspace audit
Recursive workspace audit across mixed files plus jq summaries.
printf 'files=%s\nmatches=%s\nbad_jobs=%s\ntier1=%s\n' "$(find . -type f | grep -c '^')" "$(grep -RniE 'timeout|rollback' . | grep -c '^')" "$(jq -s 'map(select(.status != "ok")) | length' logs/*.jsonl)" "$(jq '.services | map(select(.tier == 1)) | length' manifests/services.json)"(300 files, 20.2 KiB)
| Runtime | Min | Median | p95 | Artifact Size |
|---|---|---|---|---|
gbash Skipped: requires jq; runtime does not bundle it | - | - | - | 14.0 MiB |
GNU bash | 29.3ms | 33.0ms | 37.5ms | 875.9 KiB |
gbash-extras | 53.9ms | 54.6ms | 55.9ms | 33.0 MiB |
gbash-node-wasm Skipped: requires jq; runtime does not bundle it | - | - | - | 19.3 MiB |
just-bash | 761.1ms | 799.9ms | 1.04s | 131.1 MiB |
Artifact Size
Total distributable size per runtime.
| Runtime | Size |
|---|---|
| gbash | 14.0 MiB |
| GNU bash | 875.9 KiB |
| gbash-extras | 33.0 MiB |
| gbash-node-wasm | 19.3 MiB |
| just-bash | 131.1 MiB |
Runtime Methodology
- Each scenario runs the command as a fresh process invocation (cold start).
- A single untimed warmup run precedes the timed trials to prime OS caches.
- Latency is measured wall-clock from process spawn to exit.
- Artifact size includes all files needed to run the runtime (e.g., for
just-bash, this includes Node.js itself plus the npm package). - Participating runtimes execute the same shell command and validate stdout matches the expected output.
- Scenarios that require optional commands can mark unsupported runtimes as
Skippedwith a reason instead of treating them as failures. - The harness source is at
scripts/bench-compare/main.go.
Note: just-bash ships significantly more functionality than gbash today - Python and lightweight JavaScript runtimes are bundled in the core - so the artifact sizes and startup costs are not directly comparable.