Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,38 @@ API benchmarks use Node hosts installed with `ts-perf host install`, not the amb

To run the benchmark in CI, add it to `allScenarios` in `scripts/src/setupPipeline.ts` with `kind: "api"` and `runIn: RunType.None`, then request the `api` preset.

#### API allocations and memory

Use `ts-perf benchmark api --apiMemory` (or the CI preset `api apiMemory`) to collect client/server memory.
This requires additional compiler support for `TS_API_MEMORY_DIR`; timing-only candidates remain supported without
`--apiMemory`, but a requested memory pass fails if dumps or supported counters are missing. Run both baseline
and candidate with the same option; comparing memory-enabled and timing-only reports is rejected.

The runner first completes ordinary timing iterations with memory collection disabled, then repeats the same
consumer command, candidate, installed Node host and bundled npm in separate memory-only iterations. Memory passes
use the requested iteration count without additional warmups: each iteration starts fresh processes, and the timing
pass has already warmed OS caches. Memory passes never contribute wall-time or timing-counter samples.
The runner does not force GC. CI's API preset pins Node 24.21.0.

Memory dumps use schema version 1 and contain `client.pid`, `client.heapUsedBytes`, `client.peakRSSBytes`,
`client.sampling.{id,intervalBytes,allocatedBytes}` and
`server.{pid,heapAllocBytes,totalAllocBytes}`. These are process-wide, not per-request or per-client:

| Metric | Meaning and aggregation |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Client JS allocated (sampled estimate) | V8 inspector allocation sampling at a fixed 32 KiB interval, including allocations collected by **both major and minor GC**. Shared overlapping-client sampling windows are counted once (maximum cumulative estimate per window ID); disjoint windows are summed. This is not an exact JS allocation total, does not include all native/external allocations, and includes other JS activity in the API client's process during the profiling window. |
| Client/server heap at close | JS `heapUsed` / Go `HeapAlloc` snapshots, including uncollected garbage, not live-after-GC or peak heap. Maximum observed snapshot per PID, then summed across distinct processes; **not a simultaneous total**. |
| Client lifetime peak RSS | Maximum single-process lifetime high-water RSS, in bytes, across client PIDs; **not a sum of process peaks**. May include startup before API profiling. On Linux the producer uses `/proc/self/status` `VmHWM` (since the current executable image started), not `getrusage`'s inherited pre-exec launcher high-water mark. |
| Server Go allocated (exact cumulative) | Go runtime `TotalAlloc`, maximum per server PID then summed. Cumulative allocated Go heap bytes since process startup, not retained memory or all OS/native allocations. |

Only processes hosting an API client or its server contribute; npm and wrapper processes without API clients do
not. JS heap/allocation counters cover the main V8 isolate, not worker isolates or native/external allocations;
client RSS covers the entire client process; server RSS is not collected. Collection from a worker thread fails explicitly.
Client process counts and server process counts are reported separately. Snapshot and allocation measurements
include profiling overhead; the sampling window starts with the first overlapping API client and ends when the last
closes, rather than covering the entire consumer command. Unsupported sampling or client peak-RSS collection fails the
memory pass instead of reporting zeros. Sampling noise and allocations before client creation remain limitations.

## Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a
Expand Down
2 changes: 2 additions & 0 deletions build/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ jobs:
- TSPERF_JOB_NAMES_STARTUP
- TSPERF_JOB_NAMES_API
- TSPERF_PREDICTABLE
- TSPERF_API_MEMORY
- TSPERF_IS_CUSTOM_COMMIT_RANGE
- TSPERF_IS_COMPARISON
- TSPERF_BASELINE_COMMIT
Expand Down Expand Up @@ -393,6 +394,7 @@ jobs:
BENCH_TMP_DIR: $(Pipeline.Workspace)/bench-tmp
TSPERF_IS_COMPARISON: $[ dependencies.Setup.outputs['setupPipeline.TSPERF_IS_COMPARISON'] ]
TSPERF_PREDICTABLE: $[ dependencies.Setup.outputs['setupPipeline.TSPERF_PREDICTABLE'] ]
TSPERF_API_MEMORY: $[ dependencies.Setup.outputs['setupPipeline.TSPERF_API_MEMORY'] ]
TYPESCRIPT_COMMIT_NEW: $[ dependencies.Setup.outputs['buildTypeScriptNew.TYPESCRIPT_COMMIT'] ]
TYPESCRIPT_COMMIT_BASELINE: $[ dependencies.Setup.outputs['buildTypeScriptBaseline.TYPESCRIPT_COMMIT'] ]

Expand Down
1 change: 1 addition & 0 deletions scripts/runBenchmarkSandbox.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ ARGS=(
--setenv TSPERF_JOB_ITERATIONS "${TSPERF_JOB_ITERATIONS:?Expected TSPERF_JOB_ITERATIONS}"
--setenv TSPERF_JOB_WARMUPS "${TSPERF_JOB_WARMUPS:?Expected TSPERF_JOB_WARMUPS}"
--setenv TSPERF_PREDICTABLE "${TSPERF_PREDICTABLE:?Expected TSPERF_PREDICTABLE}"
--setenv TSPERF_API_MEMORY "${TSPERF_API_MEMORY:?Expected TSPERF_API_MEMORY}"
--setenv TSPERF_AGENT_BENCHMARK_CPUS "${TSPERF_AGENT_BENCHMARK_CPUS:?Expected TSPERF_AGENT_BENCHMARK_CPUS}"
)
if [ -v LANG ]; then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "false",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "false",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "27047e3391323fa2d8987f46a4c42f5361d07926",
"TSPERF_BASELINE_NAME": "release-5.3",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "27047e3391323fa2d8987f46a4c42f5361d07926",
"TSPERF_BASELINE_NAME": "release-5.3",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"MATRIX_ts_perf7": "{}",
"MATRIX_ts_perf8": "{}",
"MATRIX_ts_perf9": "{}",
"TSPERF_API_MEMORY": "false",
"TSPERF_BASELINE_COMMIT": "HEAD^1",
"TSPERF_BASELINE_NAME": "baseline",
"TSPERF_IS_COMPARISON": "true",
Expand Down
1 change: 1 addition & 0 deletions scripts/src/__tests__/scenarioSetup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ exit "$PROBE_EXIT"
TSPERF_JOB_ITERATIONS: "2",
TSPERF_JOB_WARMUPS: "0",
TSPERF_PREDICTABLE: "false",
TSPERF_API_MEMORY: "true",
TSPERF_AGENT_BENCHMARK_CPUS: "2,3",
LANG: "C.UTF-8",
LC_ALL: "C",
Expand Down
22 changes: 22 additions & 0 deletions scripts/src/__tests__/setupPipeline.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,28 @@ test("API preset rejects predictable mode", async () => {
})).rejects.toThrow("does not support predictable mode");
});

test("API memory is opt-in, applies to both commits, and accounts for separate passes", async () => {
const input = {
input: "api",
baselining: false,
isPr: true,
shouldLog: false,
gitParseRev: fakeGitRevParse,
implementation: "corsa" as const,
};
const timing = await setupPipeline(input);
const memory = await setupPipeline({ ...input, input: "api apiMemory" });
expect(timing.parameters.apiMemory).toBeUndefined();
expect(timing.outputVariables.TSPERF_API_MEMORY).toBe("false");
expect(memory.outputVariables.TSPERF_API_MEMORY).toBe("true");
expect(memory.matrix).toEqual(timing.matrix);
expect(timing.compute.total).toBe("11m");
expect(memory.compute.total).toBe("17m");
expect((await setupPipeline({ ...input, input: "api apiMemory=false" })).outputVariables.TSPERF_API_MEMORY)
.toBe("false");
await expect(setupPipeline({ ...input, input: "regular apiMemory" })).rejects.toThrow("requires the api preset");
});

async function fakeGitRevParse(query: string): Promise<GitParseRevResult> {
switch (query) {
case "release-5.3...release-5.4":
Expand Down
Loading
Loading