Performance
The Performance surface is where uploaded load runs become readable. A functional run answers “does the API behave correctly?”; a load run answers “how does it behave under concurrency?” — latency percentiles, throughput, and error rate while sustained traffic is in flight.
Performance is target-local. It has two views over the same load data:
- Trend and capacity — one target over time. Is this implementation getting faster or slower, and where does latency break as concurrency rises?
- Run comparison — compare two load runs inside the same target, plan, environment, and capacity family. What changed between run A and run B?
Use Benchmarks when the question is cross-source: Bun vs Express, Hono vs Fastify, or several implementations of the same API side by side.
| Question | Surface |
|---|---|
| Did this target regress over time? | Performance |
| What changed between two runs of the same target? | Performance |
| Which implementation or deployment wins under the same workload? | Benchmarks |
Producing load runs
Performance reads whatever glubean load uploads. A load plan is a *.load.ts file: a scenario (the workload each virtual user repeats) plus a runner (concurrency, duration, thresholds).
import { loadScenario, loadRunner } from "@glubean/sdk/load";
const shop = loadScenario("shop").step("browse", async (ctx) => {
const res = await ctx.http.get("/catalog", { searchParams: { q: "pen" } });
ctx.expect(res).toHaveStatus(200);
});
export const shopLoad = loadRunner("shop-load", {
scenario: shop,
concurrency: 500, // virtual users in flight — this is the "load level"
duration: "60s",
thresholds: {
transaction: { errorRate: "<1%", p95: "<400ms" },
},
});glubean load tests/load/ --upload # upload load artifacts to Cloud
glubean load tests/load/ --upload-target tgt_abc # override the upload targetEach upload becomes one load run on that target, carrying a rich artifact: per-endpoint and per-step latency distributions, a run timeline, threshold pass/fail, and bounded failure samples. See glubean load for the command and Load Testing for the full scenario/runner API and threshold schema.
A threshold-failed load run is still valid Performance data. Failing a p95 gate turns the run red, but the numbers it measured are real and comparable — Performance reads it like any other completed run.
For dynamic endpoints, declare the stable endpoint key in the load step with
context.glubeanRoute, for example GET /items/:id. That keeps Performance
and Benchmarks from splitting one endpoint into many literal paths such as
GET /items/1 and GET /items/2.
Trend and capacity
Open a target’s Performance tab to see its load history as a timeline:
- Latency (p50/p95/p99), throughput, and error rate plotted run over run.
- Capacity — how p95 and throughput move as you push the load level higher, so you can see where this implementation saturates.
- Breakdowns by endpoint, scenario, and step, plus threshold (SLA) verdicts per run.
Trend is longitudinal: every point is the same target, the same load plan, and the same environment at a different time. The scope picker keeps the view anchored to planId + environment, so unrelated load plans do not mix.
Run comparison — run A vs run B
Open Compare two runs on the Performance tab to compare one uploaded load run against another. Pick a Baseline (A) and Compare (B) run from the selected plan/environment scope.
Glubean only compares runs when the pair is actually comparable:
- both runs are
kind=load - both runs belong to the same target
- both runs share the same
loadRunnerplan id - both runs share the same environment label
- both runs share the same capacity family, so slot/execution/pacing shape is aligned
If a pair fails that guard, Cloud shows Not comparable instead of rendering misleading deltas. Legacy uploads that do not carry a plan or capacity family are also not comparable.
The comparison renders several tiers from the same load artifact:
- Verdict — a one-line headline that names the worst p95 regression and counts meaningful improvements/regressions.
- Scenarios — whole-transaction p95, error rate, and iteration deltas.
- Endpoints — per-endpoint p95, error rate, throughput, and request-count deltas.
- Steps — per-step timing changes inside the scenario.
- Step × endpoint attribution — the endpoint that regressed inside a specific scenario step.
- Latency distribution — side-by-side histogram shape for the two runs.
This is the target-local comparison primitive: one authored load plan, multiple uploaded runs, and a guarded A/B comparison over the evidence those runs produced.
Baselines
Cloud also supports pinned baselines:
- In run detail, Compare vs Baseline compares a run against the pinned baseline for its scope.
- For load runs, baseline scope includes the plan, load level, and capacity family. A 100-concurrency run is not silently used as the baseline for a 500-concurrency run.
- Passing runs can become auto baselines; you can also pin/unpin a run as the baseline for its own scope.
Use run-vs-run comparison when you want to choose two specific load runs. Use a pinned baseline when you want ongoing drift against a known-good run.
What this is not
Performance does not group multiple targets as named sources. A target is one source/system under test, with its own base URL and history. To compare several source targets under the same load plan, create a Benchmark.
When to reach for which
- Drift over time / CI gate → thresholds, trend, and capacity on the target’s Performance tab.
- What changed between two load runs? → Performance → Compare two runs.
- What changed against a known-good point? → pin a baseline and use Compare vs Baseline from run detail.
- Which implementation wins? → Benchmarks.
Next
glubean load— produce and upload load runs- Load Testing — runner thresholds and load artifact shape
- Dashboard — per-run detail
- Benchmarks — cross-source load comparison
- Analytics — functional-suite trends (pass rate, flakiness)