Skip to content

Stress Testing

The deterministic runtime executes your system design as a step-by-step simulation. Given the same inputs, it always produces the same outputs.

  1. Entry points are identified (components with no inbound forward connections)
  2. Seed requests are injected at entry points
  3. Each step processes one topological layer of the graph
  4. Components apply their behavior (passthrough, filter, queue, delay, etc.)
  5. Output requests are routed to downstream connections
  6. Backpressure: if a downstream queue is at 80%+ capacity, delivery is delayed by one processing cycle instead of arriving instantly
  7. Queue overflow drops the oldest request (FIFO) to preserve ordering
  8. The simulation continues until all requests are consumed or a step limit is reached
  9. If the estimated duration exceeds 1 hour, time compression scales all timing values proportionally to fit within the cap (see Time compression)

The runtime uses a fixed seed (42) for any randomized behavior (e.g., filter drop rates). This means:

  • Same design + same parameters = same results every time
  • You can reproduce and debug specific failure modes
  • Comparing before/after changes is meaningful

When running Monte Carlo analysis (multiple runs with varied seeds), process times are jittered per component per run. The jitter range scales with graph depth:

  • Base jitter: +/-15%
  • Deeper topologies (4+ components): jitter increases by 1% per additional layer, up to 25%
  • Formula: 0.15 + max(0, 0.01 * (depth - 3)), capped at 0.25

This produces correlated downstream failures that are more realistic than uniform noise.

After a Monte Carlo run, you can evaluate results against Service Level Objectives. Open the SLO Targets section in the Monte Carlo tab and configure up to three targets:

TargetRangeDescription
Min Delivery Rate0-100%Minimum percentage of requests that must be successfully delivered
Max Dropped0+Maximum number of requests allowed to be dropped
Min Health0-100%Minimum average system health across the run

Leave a field empty to skip that target. Once configured, every Monte Carlo run is evaluated per-run against your SLO targets:

  • Compliance card: Shows the overall pass rate (e.g., “85% of runs met SLO”) with a visual strip of green (pass) and red (fail) blocks, one per run
  • Per-run column: The results table gains an SLO column showing pass/fail for each individual run
  • Pass criteria: A run passes only if it meets all configured targets simultaneously

SLO targets persist per project and update live when you re-run Monte Carlo.

If any components on the canvas have monthly cost values set (in the component editor’s Cost section), Monte Carlo runs include a cost breakdown:

MetricDescription
Total MonthlySum of all component monthly costs
Cost per DeliveredTotal monthly cost divided by average delivered requests across runs
Cost per DroppedTotal monthly cost divided by average dropped requests across runs (shown only when drops occur)

The cost analysis card appears below the SLO compliance card in the Monte Carlo tab. This gives a per-request cost perspective on your design: a system that drops more requests costs more per successful delivery.

Open the Runtime Panel (R key) during simulation to access three tabs:

TabWhat it shows
OverviewHealth score, request/processed/lost counts, bottleneck, component table, connection table
StabilityTemporal health trend chart, step timeline with per-component detail, fix recommendations (Pro)
Stress TestQuick scenario presets and manual injection controls

The Stress Test tab provides one-click presets:

PresetWhat it does
BaselineNormal traffic (1x), single burst, no faults
Peak Traffic5x traffic with steady arrival stream
OutageKills a random component, normal traffic
Slowdown3x traffic with steady arrival, injects +3 steps latency on a random component

Click any preset to instantly configure and enable stress controls.

ControlRangeDescription
Traffic multiplier1-5xMultiplies the seed packet count (total = seeds x multiplier)
Arrival patternSingle burst or every 1-5 passesHow traffic arrives over time

Seed packets (1-100) are set from the timeline bar at the top. You can type a value directly or use the stepper arrows. The traffic multiplier in the stress panel scales that number.

ControlDescription
Kill componentTake a component completely offline (drops all requests)
Slow down componentAdd extra processing delay to a specific component
Extra delay1-5 additional steps of latency on the slowed component

During simulation, the canvas shows:

  • Queue saturation heatmap - Components tint orange to red as queues fill
  • Queue depth badges - Numeric count when buffered items exceed 3
  • Connection weight - Pipe thickness scales with request volume
  • Bottleneck alerts - Pulsing borders and warning icons on saturated components
  • Runtime delta badges - Show requests in (+), dropped (-), and queued counts per step
  • Backpressure warnings - Events fire when a queue reaches 80% capacity
  • Rate limit drop events - Events fire when requests are dropped due to rate limiting
  • Inactive dimming - Components not involved in the current simulation dim to 30% opacity, connections to 15%

Hover any component during simulation to see live runtime stats:

  • Received - Total requests that entered the component across all frames
  • Delivered - Total requests that left the component across all frames
  • Queued - Current queue depth at this frame
  • In transit - Requests currently on connections headed to this component
  • Lost - Requests dropped by this component (capacity overflow, filter, rate limit, etc.)

Stats only appear when non-zero.

Colored pills appear above components to indicate state during playback:

PillColorWhen it appears
N deliveredGreenExit nodes (no outgoing connections) that have processed requests
N enteredBlueEntry nodes (no incoming connections) that have received requests
N processingAmberInactive delay components with items in their queue
N doneAccentThe currently active component has finished outputting requests
N waitingAccentThe currently active component has items buffered in its queue
N lostYellowRequests were dropped (filter, capacity overflow, killed component)

Pills are cumulative: delivered and entered counts accumulate across steps. Processing pills only appear on components with delay behavior that are not currently the active step.

The Stability tab in the Runtime Panel shows a CI-1T verdict:

VerdictInstability RangeMeaning
Stable<= 10%Low variance across steps, consistent behavior
Drift<= 30%Moderate variance, performance changing over time
Volatile<= 55%High variance, unpredictable behavior
Critical> 55%Extreme instability, system breaking down

Important: CI measures variance and consistency, not correctness. A component that fails consistently (e.g., a killed component that always drops requests) will appear “Stable” because its behavior is predictable. The system overrides verdicts when real problems exist:

  • Errors detected: Stable is overridden to Volatile
  • Drops detected: Stable is overridden to Drift

Recommendations explain the distinction so you know when low CI hides real failures.

The runtime respects connection directions:

  • Forward connections carry requests from source to target
  • Backward connections carry requests from target to source
  • Both connections carry traffic in both directions
  • None connections are ignored by the runtime