How LOADLINE simulates an architecture
LOADLINE is a deterministic, discrete-event simulation (DES) of your architecture. Simulated time is an integer nanosecond counter fully decoupled from wall-clock time: a 60-second horizon runs in milliseconds. Requests arrive, queue, consume service time and complete — every metric the UI shows is measured from those events, never fabricated to look realistic.
From users to peak RPS — the workload chain
User-level requirements are converted through an explicit chain with every intermediate value exposed in the run plan. Nothing jumps from “1M users” to “10k RPS” without showing its work:
RequestsPerDay = DAU × RequestsPerUserPerDay
AverageRPS = RequestsPerDay ÷ 86400
PeakRPS = AverageRPS × PeakMultiplier
ReadFraction = ReadWriteRatio ÷ (ReadWriteRatio + 1)
MeanInterArrivalMillis = 1000 ÷ PeakRPSArrivals are a homogeneous Poisson process: exponential gaps drawn from a seeded stream, with mean rate exactly PeakRPS at peak. Values are validated before the run starts (DAU ≤ TotalUsers, PeakMultiplier ≥ 1, non-negative payload), and invalid specs are rejected explicitly rather than silently accepted.
Component models
Nine generic component kinds carry the behavior; provider services (Cloudflare, AWS, GCP) map onto them in the catalog layer, so the engine itself never contains provider-specific branches.
| Kind | Modeled behavior |
|---|---|
| client | Generates Poisson arrivals at the configured peak RPS and receives responses. |
| load balancer | Routes with its own concurrency and queue; optional fan-out replicates a request to N downstream targets. |
| api server | Computes service time per operation and forwards reads and writes along its links. |
| cache | Reads hit with the configured probability (seeded roll) and terminate; misses and writes continue downstream. |
| queue | Zero-delay pass-through that buffers into exactly one linked worker — the worker's queue holds the real backlog. |
| worker | Async compute: drains its queue with its concurrency slots; terminal node. |
| database | Priced read/write service times — the classic bottleneck. |
| object storage | Priced get/put service times. |
| network | Pure transit-latency hop, unconstrained. |
Architectures are validated before any run: exactly one client, no cycles, every node reachable, every queue fed by exactly one worker.
Queueing and latency
Queues are real system state — one FIFO line per constrained component. When arrival rate exceeds service rate, depth grows; the trend classifier reports growing, draining orstable. Admission rejects only when concurrency slots are full and the queue is at its limit; rejected requests never enter service, so they are excluded from latency percentiles and tracked as a rate instead.
request latency = Σ over visited components (
queue wait — time in that component's FIFO
+ service time — spec service time + injected failure penalty
)
+ transit — unconstrained hops (network, client)Tail latency emerges from queueing: under load, p99 grows because later requests wait behind earlier ones. Percentiles are nearest-rank over actual per-request observations (rank ceil(p × n) of sorted latencies) — there is no artificial tail multiplier anywhere in the engine.
Failure injection and cascades
| Type | Effect while active |
|---|---|
| crash | The component cannot serve: requests fail at it (or pass through untouched when configured, e.g. cache → origin). |
| increased latency | A fixed per-request service-time penalty while active. |
| increased error rate | A fraction of serviced requests fails while active. |
| network failure | Transit latency inflation plus packet loss (drops). |
Failures modify simulation state — they are not a red icon. Cascades are emergent, never scripted: a crashed cache produces misses, cache misses become database traffic, database arrival exceeds its capacity, the queue grows, percentiles rise, callers with budgets time out, and retries re-enter the failing component and amplify the load. A test asserts each link of that chain from measured numbers.
Metrics and their definitions
| Metric | Definition | Scope |
|---|---|---|
| Throughput | Completed requests ÷ measured window | per component, window average |
| Error rate | Failed ÷ generated requests | system, cumulative |
| p50 / p95 / p99 | Nearest-rank percentile over per-request terminal latencies | system, per request |
| Queue depth | Current FIFO length; max depth is the high-water mark | per component, instantaneous / max |
| Utilization | Busy time ÷ (concurrency × window) | per component, window average |
| Arrival vs capacity RPS | Arrived ÷ window against the configured modeled ceiling | per component, window average |
| Headroom | 1 − utilization (and 1 − arrival/capacity) | per component |
The run satisfies a conservation invariant — generated = completed + rejected + failed + in-flight — asserted by tests including fan-out and horizon-edge cases.
Capacity model
For each provider-backed component the modeled ceiling is derived, not guessed, and the derivation is printed in the report's assumption trail:
MaxSustainableRPS = concurrency ÷ effective service time (static kinds)
= catalog ModeledRPS (serverless kinds)
Headroom = 1 − Utilization
Saturated = arrival exceeded the modeled ceilingExample: 8 database slots ÷ 5 ms service ≈ 1,600 RPS modeled ceiling — “arrival is 50% of ceiling” is then a measured statement about the run, not a marketing number.
This is a modeled ceiling of the current configuration — an estimate from the service model, not a measured quantity and not a guaranteed production limit. Real systems usually degrade earlier (contention, GC, hot keys, connection pools).
Cost estimation
Cost consumes simulation outputs — it never lives inside component logic:
simulation outputs (completed requests, GB-s busy, window)
↓ scale to a 730h month at observed average rates (factor printed)
pricing model per service (unit prices + free-tier allowances)
↓
monthly estimate with full assumption trailEvery line item carries component, category, quantity, unit, unit price and monthly cost; every estimate carries the scale factor, the workload basis (DAU × requests/user/day) and the marker that prices are local mid-tier-region estimates. Pricing models cover per request, compute time, instance-hour, storage/month and bandwidth/egress. It is always labeled an estimate — never live billing.
Determinism and reproducibility
Given identical architecture, workload, failures, duration and seed, runs are byte-identical. Randomness is SplitMix64: each event draws from an independent stream derived from (runSeed, eventID), events are ordered by (timestamp, ID) with monotonically increasing IDs, no wall clock enters any scheduling path, and unseeded runs default to seed 1. Tests lock this at the engine, sim, API and pacing layers.
Known limitations
Honesty is part of the model — the engine deliberately does not model:
- Service-time invariance — service times are constant per op; real systems degrade under contention, so modeled ceilings are optimistic near saturation.
- Cache realism — hits are independent seeded rolls at a fixed ratio; no key space, TTL, eviction or locality.
- Traffic shape — a sustained Poisson stream at peak intensity; no diurnal curves or geographic distribution.
- Autoscaling — fleets are static per run; no mid-run scale-out events.
- Retry sophistication — per-request FIFO retries with exponential backoff; no circuit breakers or hedging.
- Latency attribution — per-request, not per-hop; there is no “which component added what” breakdown yet.