-
Notifications
You must be signed in to change notification settings - Fork 0
156 lines (140 loc) · 5.81 KB
/
Copy pathbenchmark.yml
File metadata and controls
156 lines (140 loc) · 5.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
name: Benchmarks
# Manual + weekly only — NOT per-PR. Benchmarks are noisy and slow; we run them
# on demand and on a schedule, compare against the like-for-like ubuntu baseline
# (informational-first), and upload the results + generated docs as artifacts.
on:
workflow_dispatch:
inputs:
full_size:
description: 'Run full-size sweeps (slower; the representative capture, NOT the like-for-like gate baseline)'
type: boolean
default: false
schedule:
- cron: '0 6 * * 1' # Mondays 06:00 UTC
jobs:
benchmark:
name: Run benchmark suite
runs-on: ubuntu-latest
# Postgres is started as a step (below), not a service: the connection-budget
# and churn tiers deliberately push past 50 tenant connections, so the stock
# service cap of 100 throws "too many clients". Service containers can't set
# the postgres command or mount a post-checkout config, so we run it manually
# with benchmarks/postgres.bench.conf (max_connections=300), mirroring local.
services:
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 5s
--health-timeout 5s
--health-retries 10
env:
TZ: UTC
# development (not test) so the rate-limit middleware runs its real Redis
# pipeline instead of the test-env bypass.
NODE_ENV: development
BENCH_CI: '1'
HOST: 127.0.0.1
APP_KEY: a-32-character-long-secret-key!!
LOG_LEVEL: error
TENANT_HEADER_KEY: x-tenant-id
DB_HOST: 127.0.0.1
DB_PORT: '5432'
DB_USER: postgres
DB_PASSWORD: postgres
DB_DATABASE: lasagna_bench
REDIS_HOST: 127.0.0.1
REDIS_PORT: '6379'
QUEUE_REDIS_HOST: 127.0.0.1
QUEUE_REDIS_PORT: '6379'
QUEUE_REDIS_DB: '1'
CACHE_REDIS_HOST: 127.0.0.1
CACHE_REDIS_PORT: '6379'
CACHE_REDIS_DB: '2'
steps:
- uses: actions/checkout@v4
# Raised max_connections (300) so the cap=100 churn sweep × tenant poolMax
# plus central/backoffice connections stays under the limit. Mounts the same
# benchmarks/postgres.bench.conf the local docker-compose uses.
- name: Start Postgres (bench tuning, max_connections=300)
run: |
docker run -d --name bench-postgres \
-e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=lasagna_bench \
-p 5432:5432 \
-v "$GITHUB_WORKSPACE/benchmarks/postgres.bench.conf:/etc/postgresql/postgresql.conf:ro" \
postgres:16-alpine -c config_file=/etc/postgresql/postgresql.conf
echo "Waiting for Postgres to accept connections…"
for i in $(seq 1 30); do
if docker exec bench-postgres pg_isready -U postgres -d lasagna_bench >/dev/null 2>&1; then
echo "Postgres ready (max_connections=$(docker exec bench-postgres psql -U postgres -tAc 'show max_connections'))"
exit 0
fi
sleep 2
done
echo "Postgres did not become ready in time"; docker logs bench-postgres; exit 1
# Default run is CI-sized (fast, stable, like-for-like with the committed
# ci-ubuntu baseline). A `full_size=true` dispatch overrides each BENCH_*
# knob with the production-ish sweep (budget to 2000 tenants, catalog to
# 5000 schemas, full churn). Explicit BENCH_* vars win over the CI defaults
# in src/harness/config.ts, so BENCH_CI stays 1 either way.
- name: Configure bench sizes
run: |
if [ "${{ github.event.inputs.full_size }}" = "true" ]; then
echo "Running FULL-SIZE sweeps (representative capture)"
{
echo "BENCH_DB_TENANTS=50"
echo "BENCH_DB_ROWS=1000"
echo "BENCH_CHURN_CAPS=25,50,100"
echo "BENCH_CHURN_CONCURRENCY=16"
echo "BENCH_CHURN_OPS=2000"
echo "BENCH_BUDGET_COUNTS=100,500,2000"
echo "BENCH_CATALOG_COUNTS=100,1000,5000"
echo "BENCH_HTTP_TENANTS=50"
echo "BENCH_HTTP_ROWS=200"
echo "BENCH_HTTP_CONNECTIONS=25"
echo "BENCH_HTTP_DURATION=10"
} >> "$GITHUB_ENV"
else
echo "Running CI-size sweeps (gate default)"
fi
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '24'
- name: Install dependencies
env:
npm_config_ignore_scripts: 'false'
run: npm install --legacy-peer-deps --include=optional
# The bench fixture imports the built core via the workspace symlink, so a
# fresh build of the core is mandatory. The satellites are not used.
- name: Build core
run: npm run build
- name: Tier 1 — micro
run: npm run bench:micro
- name: Tiers 2-3 — DB + HTTP, per driver
run: |
for driver in schema-pg database-pg rowscope-pg; do
echo "::group::$driver"
BENCH_DRIVER=$driver npm run bench:db
BENCH_DRIVER=$driver npm run bench:http
echo "::endgroup::"
done
- name: Tier 4 — memory + budget (schema-pg)
run: BENCH_DRIVER=schema-pg npm run bench:mem
- name: Regenerate report
run: npm run bench:report
# Informational by default. Once the ci-ubuntu baseline has stabilized,
# set BENCH_GATE_ENFORCE=1 here to make a regression fail the job.
- name: Regression check vs ci-ubuntu baseline
run: npm run bench:check -- --baseline=ci-ubuntu
- name: Upload results + generated report
if: always()
uses: actions/upload-artifact@v4
with:
name: benchmark-results
path: |
benchmarks/results/
docs/docs/performance.md
if-no-files-found: warn