Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Performance

Two load paths: contextforge-load-test measures the Rust dataplane alone, and the cf-integration harness measures the full nginx-to-control-plane-to-dataplane stack with Locust. Use the first to profile gateway changes and the second to measure what users would see.

Dataplane-Only Load Testing

crates/contextforge-load-test is a Goose-based traffic driver that speaks the full streamable HTTP MCP flow against a running gateway. Start the local stack with seeded user config first, then:

cargo run --release --bin contextforge-load-test -- \
  --host 'http://127.0.0.1:8001' \
  -u 120 -r 40 --run-time 120s \
  --report-file report.html

-u is concurrent users, -r is the spawn rate per second, and --report-file writes an HTML report. This measures the Rust dataplane alone, without a control plane or front door in the path. Curated run reports live in the repository’s reports/ directory.

Full-Stack Load With Locust

The cf-integration harness runs Locust against the public nginx route with a streamable-HTTP-aware locustfile:

CommandWhat it runs
scripts/cf-integration.sh smoke1 user for 10 seconds — a quick sanity pass.
scripts/cf-integration.sh locustThe full load run, default 100 users for 5 minutes.

Tune with environment variables:

LOCUST_USERS=20 LOCUST_SPAWN_RATE=5 LOCUST_RUN_TIME=2m \
  scripts/cf-integration.sh locust

MCP_VIRTUAL_SERVER_ID targets a UI-created virtual server instead of the auto-registered Fast Time one, and MCP_TOOL_NAMES picks the tools to call. Locust HTML/CSV output lands under .integration/mcp-context-forge/reports/; curated run reports live in the harness reports/ directory.

Headless Versus Locust Web UI

The harness runs Locust headless by default (LOCUST_MODE=headless): a timed run that writes the HTML and CSV reports and prints only the summary. Setting LOCUST_MODE to any other value (for example web) switches the Locust service to interactive mode: a master with the web UI on port 8089 and a class picker (LOCUST_EXPECT_WORKERS controls the expected worker count). The one-off locust command does not publish container ports, so for the web UI start the Locust service through the stack’s testing Compose profile — the upstream stack maps 8089:8089 — then open http://localhost:8089 and drive the run from the browser.

Benchmark Settings

The harness tunes config propagation for functional runs, not throughput:

VariableFunctional defaultBenchmark value
CF_DATAPLANE_PUBLISHER_INTERVAL_SECONDS2 (fast config publish)60 (upstream default)
CF_DATAPLANE_USER_CONFIG_CACHE_EXPIRY_SECONDS0 (cache disabled)60 (upstream default)

Restore both to 60 before measuring throughput, or the fast publish loop and per-request Redis reads distort the numbers.

Control-Plane Baseline Load

To compare against the stack without the dataplane in the path:

scripts/cf-integration.sh down                # frees the shared host ports
scripts/cf-integration.sh controlplane-locust

The baseline run defaults to the non-UI Locust class subset (health, Fast Time, Fast Test, version/meta). CONTROLPLANE_LOCUST_CLASSES=all adds the admin/UI/mutating surfaces. LOCUST_USERS, LOCUST_SPAWN_RATE, and LOCUST_RUN_TIME apply here too.