Skip to content

motel: Scenario Overrides

2026-02-11T16:00:00Z

Scenarios let you inject time-windowed behaviour changes into a running simulation. A scenario overrides operation parameters (duration, error rate) during a specific window, then reverts to baseline. This demo walks through configuration, validation, and observable impact of a database degradation scenario.

The scenario topology

This config runs two services at 50/s. At the 2-second mark, a degradation scenario activates for 3 seconds: database.query latency jumps from 5ms to 200ms and error rate spikes from 0.1% to 25%.

cat docs/examples/scenario-override.yaml
# Topology for demonstrating scenario overrides
# Short scenario windows so the demo runs quickly

version: 1
services:
  api:
    operations:
      request:
        duration: 10ms +/- 3ms
        error_rate: 0.5%
        calls:
          - database.query

  database:
    operations:
      query:
        duration: 5ms +/- 2ms
        error_rate: 0.1%

traffic:
  rate: 50/s

scenarios:
  - name: database degradation
    at: +2s
    duration: 3s
    override:
      database.query:
        duration: 200ms +/- 50ms
        error_rate: 25%

Validation

The validator checks scenario timing, override references, and duration formats.

motel validate docs/examples/scenario-override.yaml
Configuration valid: 2 services, 1 root operation

Invalid scenario references are caught. For example, overriding a non-existent operation:

cat > /tmp/bad-scenario.yaml << 'EOF'
version: 1
services:
  api:
    operations:
      request:
        duration: 10ms
traffic:
  rate: 10/s
scenarios:
  - name: test
    at: +1m
    duration: 5m
    override:
      ghost.op:
        duration: 100ms
EOF
motel validate /tmp/bad-scenario.yaml 2>&1 | head -1
Error: scenario "test": override "ghost.op" references unknown operation

Baseline: no scenario

First, a 1-second run without scenarios. With combined error rates of 0.5% (api) and 0.1% (database), errors are rare in a short run.

cat > /tmp/no-scenario.yaml << 'EOF'
version: 1
services:
  api:
    operations:
      request:
        duration: 10ms +/- 3ms
        error_rate: 0.5%
        calls:
          - database.query
  database:
    operations:
      query:
        duration: 5ms +/- 2ms
        error_rate: 0.1%
traffic:
  rate: 50/s
EOF
motel run --stdout --duration 1s /tmp/no-scenario.yaml 2>&1 >/dev/null | tail -1 | jq -r \
  '"baseline error_rate < 5%: \(.error_rate < 0.05)"'
baseline error_rate < 5%: true

With scenario: elevated errors

Running for 6 seconds covers before (0-2s), during (2-5s), and after (5-6s) the degradation window. The 25% error rate on database.query during the scenario drives the overall error rate well above baseline.

motel run --stdout --duration 6s docs/examples/scenario-override.yaml 2>&1 >/dev/null | tail -1 | jq -r '
  "scenario error_rate > 2%: \(.error_rate > 0.02)",
  "scenario has errors: \(.errors > 0)"'
scenario error_rate > 2%: true
scenario has errors: true

Latency impact

The scenario also inflates database.query duration from 5ms to 200ms. Examining individual span durations shows two distinct populations: fast spans from outside the window and slow spans from during the degradation.

motel run --stdout --duration 6s docs/examples/scenario-override.yaml 2>/dev/null | jq -rs '
  def time_secs: split("T")[1] | rtrimstr("Z") | split(":") |
    (.[0] | tonumber) * 3600 + (.[1] | tonumber) * 60 + (.[2] | tonumber);
  [.[] | select(.Name == "query") |
    ((.EndTime | time_secs) - (.StartTime | time_secs)) * 1000] |
  any(. < 50) as $fast |
  any(. >= 50) as $slow |
  "has fast spans (<50ms): \($fast)",
  "has slow spans (>=50ms): \($slow)",
  "bimodal distribution: \($fast and $slow)"'
has fast spans (<50ms): true
has slow spans (>=50ms): true
bimodal distribution: true

The fast population (~5ms) corresponds to normal operation; the slow population (~200ms) corresponds to the degradation window. This bimodal latency distribution is exactly what you would see during a real database incident, making it useful for testing alerting thresholds and SLO breach detection.