Skip to content

Benchmarks

Benchmarks #5

Workflow file for this run

name: Benchmarks
on:
release:
types: [published]
workflow_dispatch:
permissions: read-all
jobs:
benchmarks:
name: Performance Benchmarks
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
- name: Cache cargo
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: bench-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}
- name: Build release binary
run: cargo build --release -p nora-registry
- name: Record binary size
id: binary
run: |
SIZE=$(stat -c%s target/release/nora)
SIZE_MB=$(echo "scale=1; $SIZE / 1048576" | bc)
echo "size_bytes=$SIZE" >> "$GITHUB_OUTPUT"
echo "size_mb=$SIZE_MB" >> "$GITHUB_OUTPUT"
echo "Binary size: ${SIZE_MB} MB"
- name: Start NORA
id: start
run: |
mkdir -p /tmp/nora-bench-data
NORA_HOST=0.0.0.0 \
NORA_PORT=4000 \
NORA_STORAGE_PATH=/tmp/nora-bench-data \
NORA_RATE_LIMIT_ENABLED=false \
NORA_AUTH_ENABLED=false \
target/release/nora serve &
NORA_PID=$!
echo "NORA_PID=$NORA_PID" >> "$GITHUB_ENV"
# Measure cold start: wall-clock from exec to first successful /health.
START=$(date +%s%N)
for i in $(seq 1 30); do
if curl -sf http://localhost:4000/health > /dev/null 2>&1; then
END=$(date +%s%N)
STARTUP_MS=$(( (END - START) / 1000000 ))
echo "startup_ms=$STARTUP_MS" >> "$GITHUB_OUTPUT"
echo "Startup time: ${STARTUP_MS}ms"
break
fi
sleep 0.1
done
- name: Record idle memory
id: memory
run: |
sleep 2
VMRSS=$(grep VmRSS /proc/$NORA_PID/status | awk '{print $2}')
echo "idle_kb=$VMRSS" >> "$GITHUB_OUTPUT"
echo "Idle VmRSS: ${VMRSS} kB"
- name: Run criterion benchmarks
run: cargo bench -p nora-registry -- --output-format bencher 2>/dev/null | tee /tmp/criterion-results.txt || true
- name: Generate summary report
id: report
run: |
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
VERSION="${GITHUB_REF_NAME:-dev}"
cat > /tmp/nora-bench-report.json << EOF
{
"version": "$VERSION",
"timestamp": "$TIMESTAMP",
"binary_size_bytes": ${{ steps.binary.outputs.size_bytes }},
"startup_ms": ${{ steps.start.outputs.startup_ms || '0' }},
"memory_idle_kb": ${{ steps.memory.outputs.idle_kb || '0' }}
}
EOF
cat /tmp/nora-bench-report.json
- name: Stop NORA
if: always()
run: kill $NORA_PID 2>/dev/null || true
- name: Upload benchmark results
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: bench-results-${{ github.sha }}
path: |
/tmp/nora-bench-report.json
/tmp/criterion-results.txt
retention-days: 90
- name: Upload to release
if: github.event_name == 'release'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release upload "${{ github.event.release.tag_name }}" \
/tmp/nora-bench-report.json \
--clobber || true