Skip to content

docs: external perf notes + verification #14

docs: external perf notes + verification

docs: external perf notes + verification #14

Workflow file for this run

name: Performance Gate
on:
pull_request:
branches: [master]
paths:
- 'server/src/**'
- 'client/src/**'
- 'protocol/**'
jobs:
perf-benchmark:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Map local.hytopiahosting.com to localhost
run: echo "127.0.0.1 local.hytopiahosting.com" | sudo tee -a /etc/hosts
- name: Install server dependencies
run: cd server && npm ci
- name: Build SDK
run: cd server && npm run build
- name: Install perf-tools
run: cd packages/perf-tools && PUPPETEER_SKIP_DOWNLOAD=true npm ci && npm run build
- name: Restore baseline cache
id: cache-baseline
uses: actions/cache/restore@v4
with:
path: .perf-baseline/
key: perf-baseline-${{ github.base_ref }}
- name: Run idle benchmark
run: |
cd packages/perf-tools
npx hytopia-bench run --preset idle --output ../../.perf-results/idle.json --verbose
continue-on-error: true
- name: Run stress benchmark
run: |
cd packages/perf-tools
npx hytopia-bench run --preset stress --output ../../.perf-results/stress.json --verbose
continue-on-error: true
- name: Compare with baseline
if: steps.cache-baseline.outputs.cache-hit == 'true'
run: |
cd packages/perf-tools
RESULTS=""
for preset in idle stress; do
if [ -f "../../.perf-baseline/${preset}.json" ] && [ -f "../../.perf-results/${preset}.json" ]; then
echo "=== Comparing ${preset} ==="
npx hytopia-bench compare \
"../../.perf-baseline/${preset}.json" \
"../../.perf-results/${preset}.json" \
--warn 5 --fail 10 || true
fi
done
- name: Post results as PR comment
if: always()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const results = [];
const dir = '.perf-results';
if (fs.existsSync(dir)) {
for (const file of fs.readdirSync(dir)) {
if (file.endsWith('.json')) {
const data = JSON.parse(fs.readFileSync(`${dir}/${file}`, 'utf-8'));
results.push(data);
}
}
}
if (results.length === 0) {
console.log('No benchmark results to post');
return;
}
let body = '## Performance Benchmark Results\n\n';
for (const r of results) {
body += `### ${r.scenario}\n`;
body += `| Metric | Value |\n|--------|-------|\n`;
if (r.baseline) {
const b = r.baseline;
body += `| Avg Tick | ${b.avgTickMs?.toFixed(2) ?? 'N/A'}ms |\n`;
body += `| P95 Tick | ${b.p95TickMs?.toFixed(2) ?? 'N/A'}ms |\n`;
body += `| P99 Tick | ${b.p99TickMs?.toFixed(2) ?? 'N/A'}ms |\n`;
body += `| Max Tick | ${b.maxTickMs?.toFixed(2) ?? 'N/A'}ms |\n`;
body += `| Over Budget | ${b.ticksOverBudgetPct?.toFixed(1) ?? 'N/A'}% |\n`;
body += `| Avg Memory | ${b.avgMemoryMb?.toFixed(1) ?? 'N/A'}MB |\n`;
}
body += '\n';
}
body += '\n---\n*Generated by @hytopia/perf-tools*\n';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
- name: Upload results artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: perf-results
path: .perf-results/
retention-days: 30