Load testing a tool-using agent must measure capacity and correctness at the same time. Run against isolated accounts and reversible tools, generate arrivals independently of response time, preserve end-to-end deadlines, and verify every side effect. The goal is sustainable throughput with safe recovery—not the largest number reached before the system crashes.
Establish a test safety boundary
An agent load test can send email, modify tickets, run code, spend provider quota, or delete data faster than a human can intervene. Before generating traffic:
- use a dedicated environment, tenants, credentials, and billing limits;
- replace irreversible tools with contract-faithful simulators;
- seed synthetic data that cannot be confused with production;
- deny network destinations outside an allowlist;
- cap total model tokens, tool operations, and monetary spend;
- install a kill switch outside the system under test;
- define cleanup and reconciliation for every write;
- tell providers when their terms require authorization for load tests.
Do not point a synthetic “delete” scenario at production and depend on the prompt to behave. Enforce safety at credentials, network, and tool implementations.
Define the unit of successful work
Requests are not outcomes. A workflow can return HTTP 200 while a tool silently failed or a duplicate side effect occurred. Define a valid task, its final state, and an independent oracle.
For each scenario, specify:
scenario: create-and-verify-ticket
arrival_weight: 0.20
deadline_ms: 30000
expected_effects:
tickets_created: 1
forbidden_effects:
production_writes: 0
quality_checks:
- required_fields_present
- source_evidence_valid
cleanup: delete_synthetic_ticket
Record a stable logical task ID and a unique execution/attempt ID. The oracle should query tool state independently after completion. Model claims such as “ticket created” are not evidence that the write happened.
Build a representative workload mix
Prefer synthetic traces. Use production-derived traces only after minimizing or removing sensitive content, documenting authorization for that use, and confirming the privacy and contractual requirements that apply. Construct scenarios by task class, prompt size, tool chain, fan-out, output size, tenant class, and expected failure. Include fast reads, long model generations, slow tools, multi-step writes, cancellations, and policy rejections.
Weight the primary run to a declared traffic distribution, then run critical slices separately. A 1% destructive workflow may deserve more test volume than its natural frequency. Pin prompts, tool schemas, model identifiers, synthetic data snapshot, retry policy, and rate limits in a manifest.
Generated inputs should vary meaningfully without asking the model to create its own test oracle. Keep deterministic seeds and store the exact scenario parameters so a failure can be replayed.
Use both open- and closed-loop traffic
A closed-loop test keeps a fixed number of virtual users; each sends a new task after the previous response. When the system slows, offered load falls, which can hide queue instability.
An open-loop test schedules arrivals independently of response completion. It reveals whether work accumulates when real demand continues during a slowdown. Preserve scheduled and actual send times: if the load generator falls behind and silently sends late, measured latency excludes the waiting that users would have experienced.
Run both:
- closed-loop tests for interactive concurrency and connection behavior;
- open-loop tests for arrival-rate capacity, queue growth, and overload controls.
The load generator, network, and telemetry pipeline must have headroom. Monitor their CPU, connections, event loss, and clock behavior so a generator limit is not mistaken for server capacity.
Stage the experiment
Use a sequence that supports diagnosis:
- Single-task validation: prove every scenario and oracle.
- Baseline: low load, complete traces, no expected queueing.
- Ramp: increase arrival rate in fixed steps and hold each step.
- Steady state: sustain the intended operating point.
- Soak: detect leaks, cache churn, and quota windows.
- Burst: test admission and queue bounds.
- Fault: slow, fail, or throttle one dependency.
- Recovery: remove the fault while offered load continues.
Stop conditions should include unsafe effects, uncontrolled spend, telemetry loss, queue or memory bounds, excessive provider errors, and breach of environment agreements. Automate them outside the agent loop.
Inject realistic tool and provider failures
Test failures at precise phases:
- connection failure before a request is accepted;
- timeout with no known side effect;
- timeout after a write may have committed;
- rate limit with valid retry guidance;
- malformed or partial response;
- stale read after a write;
- duplicate delivery;
- tool latency that exceeds the parent deadline;
- model success followed by tool rejection.
The “unknown outcome” write is critical. Retrying blindly may duplicate a payment, ticket, or message. Require idempotency keys and a reconciliation read. Our durable-agent guide explains how to persist uncertain and compensating states.
Google’s SRE cascading-failure guidance warns that timeouts and retries can amplify overload. Validate that only one layer owns retries, backoff includes jitter, attempts consume the root deadline, and overload returns quickly.
Measure the whole causal graph
Collect these measures by scenario and workload class:
| Dimension | Measures |
|---|---|
| Demand | scheduled, sent, admitted, rejected, deferred |
| Outcome | correct success, safe failure, wrong success, unknown |
| Latency | queue, first useful output, completion, tool/model stages |
| Saturation | in-flight work, permits, CPU/GPU, memory, connections |
| Amplification | child agents, model calls, tools, retries per root |
| Economics | tokens, tool units, direct cost per successful task |
| Safety | unauthorized, duplicate, missing, and unreconciled effects |
| Recovery | drain time, error return-to-baseline, leaked work |
Report distributions, especially p95 and p99, not only means. Google Research’s “The Tail at Scale” shows why a workflow waiting on many components experiences tail latency more frequently than any one component.
Use traces to find the critical path, but keep content capture off unless a reviewed test case requires it. Synthetic prompts can still contain credentials or proprietary fixtures.
Find sustainable capacity
Capacity is the highest offered load the system can sustain while all declared service, quality, safety, and recovery conditions hold. It is not the peak throughput sample.
At each ramp step, wait long enough to observe stable queue age and resource utilization. If queue age grows continuously, arrival exceeds service capacity even when short-run success looks acceptable. Require headroom for bursts and dependency variance.
Backpressure should be visible as bounded rejection or deferral, not long timeouts. The backpressure guide covers admission, bulkheads, and degradation. Verify fairness: global metrics can look healthy while one tenant is starved.
Evaluate output quality under load
Load can change routing, prompt truncation, retrieval depth, timeouts, and fallback behavior. Run deterministic checks on every task and calibrated evaluation on a stratified sample. Compare quality and policy violations with the baseline using the same scenario mix.
Do not permit the system to meet latency by silently dropping required tools or safety checks. Record which degradation mode was used and grade against that mode’s documented promise. Any fallback model must be evaluated for the affected task classes before the test.
Verify recovery and cleanup
After the run, keep monitoring until queues drain and resources return to baseline. Check for orphaned subagents, stuck reservations, leaked permits, late tool writes, repeated retries, telemetry backlog, and caches filled with test data.
Reconcile expected versus actual side effects by logical task ID. Delete synthetic artifacts with a reviewed cleanup tool, and save a manifest of anything that could not be removed. Never declare the test complete from client responses alone.
Publish the workload manifest, environment, run window, trial shape, stop conditions, exclusions, provider limits, statistical summaries, and failures. Without them, a throughput number cannot be reproduced or compared.