Developer Tutorial
    6 steps · ~10 minutes

    Simulation API Walkthrough

    A complete, copy-paste-ready guide that chains every core simulation call in sequence — from creating your first environment to reading right-sizing recommendations.

    What this walkthrough covers

    #Step
    01Create a simulation
    02Advance the simulation one step
    03Register a traffic pattern
    04Inject a traffic spike
    05Fetch the metrics history
    06Get a right-sizing hint
    01
    POST/api/simulations
    Create a simulation

    Start by creating a simulation with a few cloud resources. Here we build a minimal AWS web-app: a load balancer, an auto-scaling compute tier, and a database. The response contains the simulation ID — copy it, you will use it in every subsequent step.

    Request
    Bash
    curl -X POST https://www.cloudworldmodel.ai/api/simulations \
    -H "Authorization: Bearer cwm_live_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "name": "My First Simulation",
    "traffic": 5000,
    "resources": [
    {
    "id": "r1",
    "name": "ALB",
    "type": "network",
    "provider": "aws",
    "serviceFamily": "elb",
    "region": "us-east-1",
    "config": { "tier": "standard", "targetCapacity": 10000 }
    },
    {
    "id": "r2",
    "name": "App Server",
    "type": "compute",
    "provider": "aws",
    "serviceFamily": "ec2",
    "region": "us-east-1",
    "config": {
    "instanceType": "t3.large",
    "instances": 4,
    "autoScaling": true,
    "minInstances": 2,
    "maxInstances": 12
    }
    },
    {
    "id": "r3",
    "name": "Primary DB",
    "type": "database",
    "provider": "aws",
    "serviceFamily": "rds",
    "region": "us-east-1",
    "config": { "instanceType": "db.r5.large", "multiAZ": true }
    }
    ]
    }'
    Expected response
    JSON
    {
    "id": "sim-abc123",
    "name": "My First Simulation",
    "status": "running",
    "provider": "aws",
    "region": "us-east-1",
    "traffic": 5000,
    "resources": [
    { "id": "r1", "name": "ALB", "type": "network", "status": "healthy" },
    { "id": "r2", "name": "App Server", "type": "compute", "status": "healthy" },
    { "id": "r3", "name": "Primary DB", "type": "database", "status": "healthy" }
    ],
    "createdAt": "2024-01-15T10:00:00Z"
    }

    What to copy: Copy the id field (sim-abc123). Every request below uses it as {simulationId} in the path.

    02
    POST/api/simulations/{simulationId}/step
    Advance the simulation one step

    A step runs the capacity model: it applies active traffic patterns, calculates CPU usage, latency, and error rate for each resource, fires autoscaling logic, and records events. Call this endpoint repeatedly to move the clock forward. The response includes a metrics snapshot for this instant.

    Request
    Bash
    curl -X POST https://www.cloudworldmodel.ai/api/simulations/sim-abc123/step \
    -H "Authorization: Bearer cwm_live_YOUR_KEY"
    Expected response
    JSON
    {
    "simulation": {
    "id": "sim-abc123",
    "status": "running",
    "traffic": 5000,
    "stepCount": 1
    },
    "metrics": {
    "simulationId": "sim-abc123",
    "cpuUsage": 72.4,
    "latencyP50": 45,
    "latencyP95": 120,
    "errorRate": 0.3,
    "throughput": 4850,
    "costPerHour": 2.40,
    "timestamp": "2024-01-15T10:01:00Z"
    },
    "events": [
    {
    "id": "evt-001",
    "severity": "info",
    "message": "Step 1 complete — 4 app-server instances healthy"
    }
    ]
    }

    What to copy: Note the metrics values (cpuUsage, latencyP95, costPerHour). After several steps these feed the right-sizing analysis in Step 6.

    03
    POST/api/simulations/{simulationId}/patterns
    Register a traffic pattern

    A traffic pattern modifies traffic load on every subsequent step. Patterns can be sine waves (daily cycles), ramps (gradual load builds), step functions (sudden jumps), or spikes. Multiple patterns can coexist — their effects are composed. Once registered, a pattern is automatically applied on every future step. Step 4 shows the one-shot spike alternative — set up the sustained pattern here first so your autoscaler has a realistic baseline before the spike hits.

    Request
    Bash
    curl -X POST https://www.cloudworldmodel.ai/api/simulations/sim-abc123/patterns \
    -H "Authorization: Bearer cwm_live_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "type": "sine",
    "amplitude": 0.3,
    "period": 24
    }'
    Expected response
    JSON
    {
    "id": "pat-xyz789",
    "simulationId": "sim-abc123",
    "type": "sine",
    "amplitude": 0.3,
    "period": 24,
    "isActive": true
    }

    What to copy: The sine pattern is now active. Every step call will apply ±30% traffic oscillation with a 24-step period, simulating a daily load cycle.

    04
    POST/api/simulations/{simulationId}/inject-traffic
    Inject a traffic spike

    For a more immediate stress test — without configuring a full pattern — hit the inject-traffic endpoint. It multiplies the current traffic by a random 2×–5× factor and records a warning event. Run a few more step calls afterwards to see how the autoscaler responds to the surge.

    Request
    Bash
    curl -X POST https://www.cloudworldmodel.ai/api/simulations/sim-abc123/inject-traffic \
    -H "Authorization: Bearer cwm_live_YOUR_KEY"
    Expected response
    JSON
    {
    "simulation": {
    "id": "sim-abc123",
    "traffic": 18500,
    "status": "running"
    },
    "event": {
    "id": "evt-spike-001",
    "simulationId": "sim-abc123",
    "severity": "warning",
    "message": "Traffic spike injected: 5000 → 18500 RPS"
    }
    }

    What to copy: Traffic jumped from 5 000 to 18 500 RPS. Call POST /step two or three more times to watch autoscaling add instances and latency stabilise.

    05
    GET/api/simulations/{simulationId}/metrics
    Fetch the metrics history

    Read back the full time-series of every metrics snapshot recorded so far. Each entry corresponds to one step call and includes CPU, latency percentiles, error rate, throughput, and cost. Use this to chart how your architecture behaved across the entire scenario.

    Request
    Bash
    curl https://www.cloudworldmodel.ai/api/simulations/sim-abc123/metrics \
    -H "Authorization: Bearer cwm_live_YOUR_KEY"
    Expected response
    JSON
    [
    {
    "simulationId": "sim-abc123",
    "cpuUsage": 72.4,
    "latencyP50": 45,
    "latencyP95": 120,
    "latencyP99": 198,
    "errorRate": 0.3,
    "throughput": 4850,
    "costPerHour": 2.38,
    "timestamp": "2024-01-15T10:01:00Z"
    },
    {
    "simulationId": "sim-abc123",
    "cpuUsage": 88.1,
    "latencyP50": 72,
    "latencyP95": 210,
    "latencyP99": 380,
    "errorRate": 2.1,
    "throughput": 6200,
    "costPerHour": 2.85,
    "timestamp": "2024-01-15T10:02:00Z"
    },
    {
    "simulationId": "sim-abc123",
    "cpuUsage": 41.3,
    "latencyP50": 31,
    "latencyP95": 88,
    "latencyP99": 142,
    "errorRate": 0.1,
    "throughput": 5100,
    "costPerHour": 2.85,
    "timestamp": "2024-01-15T10:03:00Z"
    }
    ]

    What to copy: Three steps recorded. The middle entry (cpuUsage 88.1%) shows peak stress during the spike. After autoscaling added instances, utilisation fell back to 41.3% — possibly over-provisioned. Step 6 will check.

    06
    GET/api/simulations/{simulationId}/right-sizing-hint
    Get a right-sizing hint

    The right-sizing endpoint analyses the most recent metrics and resource configuration to detect over-provisioning. When it finds under-utilised resources it returns a recommended smaller size slug, the estimated hourly rate, the potential savings percentage, and a trade-off note so you can make an informed decision before resizing.

    Request
    Bash
    curl https://www.cloudworldmodel.ai/api/simulations/sim-abc123/right-sizing-hint \
    -H "Authorization: Bearer cwm_live_YOUR_KEY"
    Expected response
    JSON
    {
    "hasHint": true,
    "hints": [
    {
    "resourceType": "compute",
    "reason": "low_cpu",
    "affectedResourceId": "r2",
    "affectedResourceName": "App Server",
    "recommendedSlug": "t3.medium",
    "hourlyRate": 0.052,
    "estimatedSavingsPct": 35,
    "tradeOffNote": "t3.medium has half the vCPU of t3.large — monitor p95 latency closely after resize",
    "currentUtilization": 22.4
    }
    ]
    }

    What to copy: App Server is running at 22.4% CPU — well below the efficient range. Downsizing to t3.medium would save ~35% on compute costs. The tradeOffNote flags the reduced headroom so you can decide whether the savings are worth it.

    RL Quickstart
    aurora-serverless · Python

    Aurora Serverless v2 episode-loop quickstart

    Aurora Serverless v2 (aurora-serverless) scales ACUs continuously between minCapacity and maxCapacity, so cost tracks actual load rather than peak provisioned size. The simulation engine models a 2–4 step ACU ramp delay after add_resource — during those steps cpu_util reads 0 and cost_usd_hr reflects only the minCapacity floor (~$0.06/hr at 0.5 ACUs). Once the workload is routed to the resource, cost_usd_hr climbs incrementally over 3–6 steps to the steady-state ACU-proportional rate. The snippet below handles both phases so your reward function avoids false latency penalties during ramp-up.

    Full episode loop
    import requests
    BASE = "https://www.cloudworldmodel.ai/api"
    HEADERS = {"Authorization": "Bearer <your-api-key>", "Content-Type": "application/json"}
    # 1. Create an RL environment linked to an existing simulation that already contains
    # at least one AWS database resource (the engine clones it for the new step).
    env = requests.post(f"{BASE}/rl/environments",
    json={"simulationId": "<sim-id>",
    "episodeConfig": {"maxSteps": 40, "tick_seconds": 60}},
    headers=HEADERS).json()
    env_id = env["environment"]["id"]
    # 2. add_resource action — adds an AWS database resource to the running simulation.
    # The engine models a 2-4 step ACU scale-out delay for aurora-serverless targets.
    # Step request shape: {"action": {"type": "...", "parameters": {...}}, "tick_seconds": N}
    step1 = requests.post(f"{BASE}/rl/environments/{env_id}/step", headers=HEADERS, json={
    "action": {
    "type": "add_resource",
    "parameters": {"resourceType": "database", "provider": "aws"}
    },
    "tick_seconds": 60
    }).json()
    # Step response keys: t, obs, metrics, reward, reward_components, done
    t = step1["t"] # step index (1 after first action)
    obs = step1["obs"] # {cpu_util, rps, instances, traffic, currentTime}
    metrics = step1["metrics"] # {cost_usd_hr, latency_p95, error_rate, uptime, sla_violations}
    # 3. Ramp window (t = 1-4): obs.cpu_util == 0, metrics.cost_usd_hr at minCapacity floor (~$0.06/hr).
    # Use a neutral adjust_threshold action to advance the clock without changing autoscaling config.
    # Only count cost + stability reward components -- skip performance and sla during ACU ramp-up.
    RAMP_STEPS = 4
    result = step1
    for _ in range(RAMP_STEPS):
    result = requests.post(f"{BASE}/rl/environments/{env_id}/step", headers=HEADERS, json={
    "action": {"type": "adjust_threshold", "parameters": {"cpuThreshold": 70}},
    "tick_seconds": 60
    }).json()
    t = result["t"]
    obs = result["obs"]
    metrics = result["metrics"]
    rc = result["reward_components"]
    # Exclude performance and sla components during ACU ramp to avoid false latency penalties
    adjusted_reward = rc["cost"] + rc["stability"]
    print(f"Ramp t={t:2d} cpu_util={obs['cpu_util']:.3f} "
    f"cost_usd_hr={metrics['cost_usd_hr']:.4f} adj_reward={adjusted_reward:.3f}")
    # 4. Steady-state training (t >= 5): all reward components are now meaningful. With a database
    # resource present this is five components — performance, cost, stability, sla, and the
    # connection_pressure DB-pool penalty (see the worked connection-pool example below).
    # metrics.cost_usd_hr climbs over 3-6 steps toward the ACU-proportional steady-state rate.
    done = result["done"]
    while not done:
    result = requests.post(f"{BASE}/rl/environments/{env_id}/step", headers=HEADERS, json={
    "action": {"type": "adjust_threshold", "parameters": {"cpuThreshold": 70}},
    "tick_seconds": 60
    }).json()
    t = result["t"]
    obs = result["obs"]
    metrics = result["metrics"]
    reward = result["reward"]
    done = result["done"]
    print(f"Train t={t:2d} cpu_util={obs['cpu_util']:.3f} "
    f"latency_p95={metrics['latency_p95']:.0f}ms "
    f"cost_usd_hr={metrics['cost_usd_hr']:.4f} reward={reward:.3f}")
    # 5. Reset for the next episode
    requests.post(f"{BASE}/rl/environments/{env_id}/reset", headers=HEADERS)

    Key behaviors to expect

    • Ramp window (t = 1–4): cpu_util is 0 and cost_usd_hr ≈ $0.06/hr. Only count cost + stability reward components — skip performance and sla to avoid false penalties.
    • Steady state (t ≥ 5): all reward components are meaningful — performance, cost, stability, sla. cpu_util stabilises at 20–70% for OLTP workloads. cost_usd_hr ramps over 3–6 more steps to the ACU-proportional rate (up to ≈ $1.92/hr at 16 ACUs).
    • Connection-pool penalty (fifth signal): because this episode adds a database resource, every step also reports a fifth reward component, connection_pressure (and a matching metrics.connection_pressure ratio). It is 0 while the pool is under capacity and turns negative once active connections exceed maxConnections — scale the database (not just compute) when it approaches 1.0.
    • Idle scale-back: When load drops below the minCapacity breakeven, cost_usd_hr reverts to the floor within 1–2 steps.
    • Multi-resource sims — read the per-DB array: The cpu_util == 0 and floor-cost_usd_hr signals above are visible at the top level only in this single-serverless-DB quickstart. When the simulation also runs a busy compute tier or other databases, the sim-wide cpu_util, cost_usd_hr, and connection_pressure are aggregates that mask one DB's warming window, ACU floor, and pool saturation. Read metrics.serverless[i] — one entry per Aurora Serverless v2 DB, each exposing its own cpu_util, acu, warming, cost_usd_hr, and connection_pressure.

    What to explore next

    Chaos engineering

    Register failure scenarios (database crash, zone outage, network partition) and measure your architecture's resilience score.

    Hybrid prediction engine

    Step via the hybrid endpoint to blend rule-based simulation with ML-based prediction and compare the two paths side by side.

    Multi-cloud strategy exploration

    Generate and score architecture variants across AWS, GCP, Azure, OCI, and DigitalOcean to find the best cost/latency/lock-in trade-off.

    RL training loop

    Wrap the step endpoint in an episode lifecycle to train reinforcement learning agents that optimise autoscaling policies.