Skip to content

feat: add HTTP/2 load testing infrastructure#798

Merged
jrvb-rl merged 5 commits into
mainfrom
jrvb/loadtest
Jul 10, 2026
Merged

feat: add HTTP/2 load testing infrastructure#798
jrvb-rl merged 5 commits into
mainfrom
jrvb/loadtest

Conversation

@jrvb-rl

@jrvb-rl jrvb-rl commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

User description

Summary

A loadtest/ toolkit for benchmarking the SDK's request handling, plus raw-transport baselines. The SDK harness (loadtest.ts) fires a burst of devboxes.create calls at a deliberately nonexistent blueprint (bp_nonexistent_loadtest_00000): every request fails fast server-side (HTTP 400, no devboxes created), isolating client + server request handling from provisioning — i.e. "can the stack absorb many requests at once."

What changed in this update

  • Runs against the in-repo SDK. loadtest.ts now imports ../src/sdk.ts (like the sibling loadtest scripts) instead of the published @runloop/api-client, so it always exercises the SDK code in the current checkout — not a stale build.
  • Matches HTTP/2-as-default. Transport is set explicitly: since HTTP/2 is now the default, HTTP/1.1 must be opted into with http2: false. USE_HTTP2 defaults to on; USE_HTTP2=0 benchmarks HTTP/1.1. HTTP/2 mode relabeled as native node:http2.
  • Kept the undici comparison. The raw undici / node:http2 / node:https probes are retained — comparing undici's HTTP/2 multiplexing against node:http2 is the comparison that motivated building the SDK's own node:http2 transport. undici now lives in loadtest/package.json, so these stay runnable even after the SDK drops its undici dependency (chore(deps): remove dead undici HTTP/2 adapter and dependency #817).
  • package.json: dropped type: module (it would force the shared loadtest/ dir to ESM and break push-to-loki.ts) and the @runloop/api-client file dependency.
  • README: documents the real-API comparison scripts and how to run them.

Scripts (real-API)

Script Transport under test
loadtest.ts The SDK (HTTP/1.1 vs native HTTP/2), via a bogus-blueprint create burst
undici-test.ts, undici-single-conn.ts, undici-debug.ts Raw undici HTTP/2 pool
h2-test.ts, h2-single-conn.ts Raw node:http2
raw-fetch-test.ts Raw node:https (HTTP/1.1 keep-alive)
alpn-check.ts TLS ALPN h2 negotiation check

Usage

# SDK: HTTP/2 (default) vs HTTP/1.1
source ~/env && REQUEST_COUNT=2000 npx tsx loadtest/loadtest.ts               # HTTP/2
source ~/env && REQUEST_COUNT=2000 USE_HTTP2=0 npx tsx loadtest/loadtest.ts   # HTTP/1.1

# Raw undici vs node:http2 (undici from loadtest/package.json)
cd loadtest && npm install && source ~/env && npx tsx undici-test.ts

Relationship to #815

The HTTP/2-as-default behavior (and the single shared H2 pool + idle-session unref) lands in #815. Run this harness against a checkout containing #815 to exercise the proposed transport; the comparison numbers in #815's description were gathered with this harness against that branch. On plain main (pre-#815), loadtest.ts in HTTP/2 mode will not exit on its own because idle H2 sessions aren't unref'd until #815.

Test plan

  • loadtest.ts runs against the in-repo SDK for both transports; HTTP/1.1 and (against feat: default to HTTP/2 transport on Node #815) HTTP/2 complete and exit cleanly, all requests 400 (no devboxes created).
  • eslint clean on loadtest.ts.

🤖 Generated with Claude Code


CodeAnt-AI Description

Add real API load tests for HTTP/2, HTTP/1.1, and raw client comparisons

What Changed

  • Added load test scripts that run against the real Runloop API and compare the SDK, raw HTTP/2, raw HTTP/1.1, and undici behavior
  • The SDK load test now always uses the local checkout and can switch between HTTP/2 and HTTP/1.1, with request counts, progress updates, throughput, latency percentiles, and status counts in the output
  • Added single-connection, multi-connection, and protocol-check scripts to make transport comparison and HTTP/2 negotiation checks easier
  • Load tests now fail instead of hanging when the server aborts a response, and the README explains which scripts use real API traffic and how to run them

Impact

✅ Clearer HTTP/2 vs HTTP/1.1 benchmark results
✅ Fewer stuck load tests when responses fail mid-stream
✅ Easier comparison of SDK and raw client request handling

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@codeant-ai

codeant-ai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added the size:XL This PR changes 500-999 lines, ignoring generated files label Jun 11, 2026
Comment thread loadtest/raw-fetch-test.ts Outdated
Comment thread loadtest/undici-test.ts
Comment thread loadtest/h2-test.ts Outdated
Comment thread loadtest/h2-test.ts Outdated
Comment thread loadtest/loadtest.ts Outdated
@codeant-ai

codeant-ai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

CodeAnt AI finished reviewing your PR.

jrvb-rl and others added 3 commits July 10, 2026 11:59
Adds a loadtest/ directory with scripts for benchmarking HTTP/2
transport throughput against the Runloop API. Includes baselines for
raw node:http2, undici, and the SDK client at various concurrency levels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add res.on('error', reject) so the promise settles if the server
aborts mid-response, instead of hanging indefinitely.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update the SDK load harness for the new default transport:

- `loadtest.ts` imports `../src/sdk.ts` (like the sibling loadtest scripts) so
  it always exercises the SDK code in this checkout, not a published build.
- Set `http2` explicitly: HTTP/2 is now the default, so HTTP/1.1 must be opted
  into with `http2: false`. `USE_HTTP2` defaults to on; `USE_HTTP2=0` benchmarks
  HTTP/1.1. Relabel the HTTP/2 mode as native `node:http2`.
- Drop the `@runloop/api-client` file dependency and `type: module` from
  `loadtest/package.json` (the latter would force the shared loadtest dir to ESM
  and break `push-to-loki.ts`); keep `undici` so the raw undici-vs-native
  comparison still runs — that comparison motivated the native H2 transport.
- Document the real-API comparison scripts (SDK + raw undici/node:http2/https)
  in the loadtest README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codeant-ai

codeant-ai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

CodeAnt AI is running Incremental review

@codeant-ai

codeant-ai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added size:XL This PR changes 500-999 lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels Jul 10, 2026
@codeant-ai

codeant-ai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

CodeAnt AI Incremental review completed.

Reflex and others added 2 commits July 10, 2026 12:10
The raw undici / node:http2 / node:https probes predated the repo's
prettier/eslint style (double quotes), which fails `eslint .`. Format them so
the rebased branch is lint-clean; no behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nput

Address CodeAnt review on the loadtest harness:

- undici-test / raw-fetch-test: collect per-request results instead of
  `Promise.all` fail-fast. One transient network error (or a mid-stream
  response abort in raw-fetch) no longer hangs or discards the whole run;
  failures are counted as `network_error` in the status breakdown.
- raw-fetch-test: settle each request exactly once across end / aborted /
  error / request-error paths (previously a mid-stream abort could hang the
  batch indefinitely).
- h2-test: reject NUM_CONNECTIONS < 1 up front (previously dereferenced
  clients[0] === undefined and crashed).
- All scripts: guard the latency block against zero results so an empty run
  doesn't throw on latencies[0].

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jrvb-rl
jrvb-rl merged commit ea7cc09 into main Jul 10, 2026
8 checks passed
@jrvb-rl
jrvb-rl deleted the jrvb/loadtest branch July 10, 2026 23:30
@stainless-app stainless-app Bot mentioned this pull request Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants