Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/benchsdk-client-run-key.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@benchsdk/client": minor
---

`createRun` accepts an optional `runKey`: callers passing the same key (per org + benchmark) get-or-create one shared run instead of each opening its own. `BenchmarkRun.runKey` reports the key a run was created with.
11 changes: 11 additions & 0 deletions .changeset/benchsdk-runner-shapes-run-key.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@benchsdk/runner": minor
---

Verbs-only CLI: `bench run <file.bench.ts>` is the one mutating command. The benchmark is declared in the file and materialized (upserted) as a side effect of running it, and a run is opened as a side effect too — there are no imperative `bench create benchmark` / `bench create run` commands.

`bench run` gains `--shape <name>`: a bench file can declare named `shapes`, each swapping in its own platform identity (`slug`/`name`, optional `kind`) and a stable knob (`staggerDelayMs`) while reusing the same task and participants. This collapses the per-shape slug/name/knob triple that was duplicated across package scripts and CI.

`bench run` gains `--run-key <key>`: sibling processes passing the same key (per org + benchmark) get-or-create one shared run instead of each opening its own, so provider jobs running in parallel land in a single, directly-comparable run. Each process registers only the participants it runs. The key binding is permanent, so callers that need a fresh run (e.g. a CI re-run) vary the key (e.g. include `GITHUB_RUN_ATTEMPT`).

`--slug` remains a working alias for `--benchmark`.
5 changes: 0 additions & 5 deletions .changeset/benchsdk-runner-slug-flag.md

This file was deleted.

5 changes: 5 additions & 0 deletions .changeset/participant-sized-runs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@benchsdk/client": minor
---

`createRun` no longer requires `totalTasks`: omit it to open a participant-sized run, whose total is the sum of what its participants declare when they register. `BenchmarkRun.participantSized` reports which kind a run is.
126 changes: 126 additions & 0 deletions .github/workflows/git-benchmarks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: Git Benchmark

on:
push:
branches: [master]
paths:
- 'benchmarks/git/**'
- 'benchmarks/src/util/**'
- 'benchmarks/src/merge-results.ts'
- 'package.json'
- '.github/workflows/git-benchmarks.yml'
schedule:
- cron: '0 0 * * 1' # Weekly on Monday at midnight UTC
workflow_dispatch:
inputs:
iterations:
description: 'Iterations per provider'
required: false
default: '10'
provider:
description: 'Provider to run (leave empty for all)'
required: false
default: ''
dry_run:
description: 'Run without committing results'
required: false
default: false
type: boolean

concurrency:
group: git-benchmarks
cancel-in-progress: true

jobs:
bench:
permissions:
contents: read
name: Bench ${{ matrix.provider }}
runs-on: namespace-profile-default;permissions.additional_grant=vault/object:*:list;permissions.additional_grant=vault/object:*:describe
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
provider: ${{ (github.event.inputs.provider != '' && fromJson(format('["{0}"]', github.event.inputs.provider))) || fromJson('["github","gitlab","bitbucket","tensorlake"]') }}
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Clear stale results from checkout
run: rm -rf results/git/
- name: Run git benchmark
run: |
. benchmarks/scripts/load-vault-secrets.sh '^(GITHUB_GIT_REPO_URL|GITHUB_TOKEN|GITLAB_GIT_REPO_URL|GITLAB_TOKEN|BITBUCKET_GIT_REPO_URL|BITBUCKET_TOKEN|TENSORLAKE_GIT_REPO_URL|TENSORLAKE_API_KEY|BENCHMARKS_PLATFORM_API_KEY)$'

ITERATIONS="${{ (github.event_name == 'schedule' && '50') || github.event.inputs.iterations || '10' }}"

# Every provider job passes the same --run-key, so all matrix jobs
# get-or-create one shared platform run and each registers only its
# own participant. The attempt is in the key so workflow re-runs open
# fresh runs instead of rejoining the completed ones.
RUN_KEY="${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"

npx tsx packages/benchsdk-runner/dist/bin.js run benchmarks/git/git.bench.ts \
--provider ${{ matrix.provider }} \
--iterations $ITERATIONS \
--run-key "$RUN_KEY"
- name: Upload results
if: always()
uses: actions/upload-artifact@v4
with:
name: git-results-${{ matrix.provider }}
path: results/git/
if-no-files-found: ignore
retention-days: 7

collect:
name: Collect Git Results
runs-on: namespace-profile-default;permissions.additional_grant=vault/object:*:list;permissions.additional_grant=vault/object:*:describe
needs: [bench]
if: always()
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts/
pattern: git-results-*
- name: Merge results
run: npx tsx benchmarks/src/merge-results.ts --input artifacts --mode git
- name: Commit and push results
if: github.event_name != 'push' && github.event.inputs.dry_run != 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add results/git/
git diff --cached --quiet && echo "No changes to commit" && exit 0
git commit -m "chore: update git benchmark results [skip ci]"

branch="${GITHUB_REF#refs/heads/}"
for attempt in 1 2 3 4 5; do
git fetch origin "${branch}"
git rebase --autostash "origin/${branch}" || { git rebase --abort; exit 1; }
if git push origin "HEAD:${branch}"; then
echo "Pushed on attempt ${attempt}"
exit 0
fi
echo "Push rejected (attempt ${attempt}); will rebase and retry"
done
echo "Failed to push after multiple attempts" >&2
exit 1
11 changes: 10 additions & 1 deletion .github/workflows/sandbox-dax-benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:
- 'benchmarks/sandbox/providers.ts'
- 'benchmarks/src/merge-results.ts'
- 'benchmarks/scripts/dax-benchmark.sh'
- 'benchmarks/sandbox/generate-dax-svg.ts'
- 'dax.svg'
- 'package.json'
- '.github/workflows/sandbox-dax-benchmarks.yml'
schedule:
Expand Down Expand Up @@ -149,6 +151,13 @@ jobs:
pattern: results-*
- name: Merge results
run: npx tsx benchmarks/src/merge-results.ts --input artifacts
- name: Generate DAX SVG
run: |
if [ -f results/sandbox-dax/latest.json ]; then
pnpm run generate-dax-svg
else
echo "No DAX results found; skipping chart"
fi
- name: Ingest results to platform
if: github.event_name != 'push' && github.event.inputs.dry_run != 'true'
continue-on-error: true
Expand Down Expand Up @@ -248,7 +257,7 @@ jobs:
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add results/sandbox-dax/
git add results/sandbox-dax/ dax.svg
git diff --cached --quiet && echo "No changes to commit" && exit 0
git commit -m "chore: update dax benchmark results [skip ci]"

Expand Down
23 changes: 15 additions & 8 deletions .github/workflows/sandbox-tti-benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,19 +118,26 @@ jobs:
run: |
. benchmarks/scripts/load-vault-secrets.sh '^(ARCHIL_API_KEY|ARCHIL_REGION|ARCHIL_DISK_ID|ARKER_API_KEY|BEAM_TOKEN|BEAM_WORKSPACE_ID|BL_API_KEY|BL_WORKSPACE|CLOUD_RUN_SANDBOX_URL|CLOUD_RUN_SANDBOX_SECRET|CLOUDFLARE_SANDBOX_URL|CLOUDFLARE_SANDBOX_SECRET|CSB_API_KEY|CREATEOS_SANDBOX_API_KEY|DAYTONA_API_KEY|DECLAW_API_KEY|E2B_API_KEY|HOPX_API_KEY|ISORUN_API_KEY|LIGHTNING_API_KEY|MODAL_TOKEN_ID|MODAL_TOKEN_SECRET|NSC_TOKEN|NORTHFLANK_TOKEN|NORTHFLANK_PROJECT_ID|OPENCOMPUTER_API_KEY|OPENCOMPUTER_API_URL|RUNLOOP_API_KEY|SAIL_API_KEY|SANDBOX0_TOKEN|SPRITES_TOKEN|SUPERSERVE_API_KEY|TENKI_API_KEY|TENSORLAKE_API_KEY|UPSTASH_BOX_API_KEY|VERCEL_TOKEN|VERCEL_TEAM_ID|VERCEL_PROJECT_ID|COMPUTESDK_ADMIN_API_KEY|BENCHMARKS_PLATFORM_API_KEY)'

# One entrypoint, three launch shapes: the knobs come from the CLI
# and --slug/--name pick which platform benchmark each reports to.
# One entrypoint, three launch shapes selected with --shape; the scale
# knobs come from the CLI. Every provider passes the same --run-key, so
# each shape's providers get-or-create one shared run and rank against
# each other (each still registers itself and claims its own worker).
# The shapes are distinct benchmark slugs, so one key value yields one
# run per shape; the run attempt is in the key so a workflow re-run
# opens fresh runs instead of rejoining the completed ones.
BENCH=(npx tsx packages/benchsdk-runner/dist/bin.js run benchmarks/sandbox/tti.bench.ts)
COMMON=(--provider ${{ matrix.provider }} \
--iterations ${{ github.event.inputs.iterations || (github.event_name == 'push' && '10') || '100' }})
RUN_KEY="${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
COMMON=(
--provider ${{ matrix.provider }}
--iterations ${{ github.event.inputs.iterations || (github.event_name == 'push' && '10') || '100' }}
--run-key "$RUN_KEY"
)
CONCURRENCY=${{ github.event.inputs.concurrency || (github.event_name == 'push' && '10') || '100' }}
# Sequential is one-at-a-time by definition, so it never gets
# --concurrency (the config default pins it to 1).
SEQUENTIAL=("${BENCH[@]}" "${COMMON[@]}")
STAGGERED=("${BENCH[@]}" "${COMMON[@]}" --concurrency "$CONCURRENCY" --stagger-delay-ms 200 \
--slug sandbox-staggered-local --name 'Sandbox staggered TTI (local)')
BURST=("${BENCH[@]}" "${COMMON[@]}" --concurrency "$CONCURRENCY" \
--slug sandbox-burst-local --name 'Sandbox burst TTI (local)')
STAGGERED=("${BENCH[@]}" "${COMMON[@]}" --shape staggered --concurrency "$CONCURRENCY")
BURST=("${BENCH[@]}" "${COMMON[@]}" --shape burst --concurrency "$CONCURRENCY")
case "${{ github.event.inputs.mode }}" in
sequential) "${SEQUENTIAL[@]}" ;;
staggered) "${STAGGERED[@]}" ;;
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ Our partners support our independent benchmarks.

![Object Storage Snapshot & Fork](./snapshot_fork_small.svg)

### [DAX Sandbox Builds](#dax-sandbox-builds)

![DAX Sandbox Builds](./dax.svg)

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)

**TTI (Time to Interactive)** = API call to first command execution. Lower is better.
Expand Down
Loading
Loading