The Verification Venue · pointed at the story a single cascade tells

Blackouts Come in All Sizes

Every explanation of a large blackout shows one cascade: a domino chain with an identifiable first domino, and therefore a cause that could have been prevented. Run the long-run process instead, demand rising and failed lines reinforced, and the largest blackouts arise from initiating events indistinguishable from the thousands that go nowhere. The sizes spread across nearly two decades with no characteristic size, and they lie close to a straight line on logarithmic paper. This page computes that line in front of you, and then spends most of its effort making you distrust it, successfully: over the window the data actually covers, the fitted power law cannot be told apart from an exponential, and the page shows you the statistic that says so.

Start small. Below is the network this page grows by a stated rule, and a line waiting to be tripped. Trip one and watch the cascade resolve, step by step, exactly as the slow reference implementation computes it. Then scroll: the same machinery, run for simulated years, tells a story that one cascade cannot.

the grown network, 56 nodesquiescent

Lines tripped

0

Load shed

0.0

load units, the model's own demand

Cascade step

Or click any line on the diagram to trip that one. What you are watching is one cascade: a story with characters. Resist its moral for a moment.

The rules, stated in full because every number downstream is a consequence of them and nothing else. The network grows planar: start from a triangle, repeatedly pick a random face and insert a node inside it joined to the face's three corners, until there are 56 nodes and 162 lines. Six nodes of highest degree generate; everyone else demands between 1 and 3.5 load units. Line capacities start at 1.4 times the virgin flow. A cascade trips one line, then re-solves the direct-current flow, trips every overloaded line simultaneously, and repeats until quiet; islands without a generator shed their demand. Between cascades, scheduled demand grows 1%, shed demand recovers slowly, and every line that failed comes back 8% stronger. That is the whole machine:

There is no external data anywhere in this piece. The network is grown from the seed, the flows are solved from the network, the blackouts fall out of the flows. Which is exactly why the interesting question is not the computation but the evidence: at full size there is no second implementation that can reach the answer, so the page carries its checks with it, and you can watch every one of them run.

The long run: 14 independent histories of 3,000 cascades

Chunks done

0 / 14

workers: waiting

Operations, counted

0

elapsed: —

Blackouts so far

0

fit: waiting for data

Each chunk is one independent 3,000-cascade history from its own seed. This page aggregates an ensemble of histories, not one continuous history; the two estimate different things, and the ensemble is what is used here.

The margin the process finds by itself

cascade index →margin: distance to the first overload

The line is the loading margin, averaged over the runs, sampled through the 3,000 cascades: how far the most-loaded line sits from tripping before each cascade begins. Demand growth pushes it down; each large blackout sheds load and reinforces lines, pulling it back up. The process walks itself to the brink and hovers there. Nobody told it to.

Blackout sizes, doubly logarithmic

blackout size, load units (log)number of blackouts (log)

Watch the histogram straighten as the sample grows. The overlaid line is the fitted power law over its stated window, with the bootstrap interval drawn beside it. A straight line here would be the claim; everything in the check panel below exists to attack it, and when the run finishes this caption is replaced by what the attack found.

Now the second, harder result. The model offers two different interventions. Hardening changes the failure rule itself: a line must exceed 130% of its capacity to trip. Adding capacity leaves the rule alone and just enlarges every line by 30% at the outset. One of these may change the shape of the tail; the other may mostly change how often it is sampled. No single-cascade animation can even express that distinction. The table below computes, from your own runs, which knob moved the exponent and which moved the rate; the page does not prejudge the answer. The exponent there is a descriptor of the fitted line, not a claim that the underlying law is a power law: see the check panel for how little this window can settle about that.

scenariorunsblackoutsrate /cascade alpha (MLE)alpha (regression)verdict vs baseline

The check: everything that stands between you and the headline

These run in your browser, in this order, before the run button unlocks. The battery compares the WebAssembly engine against the slow JavaScript twin on six small cases; the control then breaks the twin on purpose and requires the comparison to notice. The offline gate that repeats all of this, plus a reproducible build of the binary, is node research/blackouts-come-in-all-sizes/verify-blackouts-come-in-all-sizes.mjs.

battery casewasm fingerprintreference fingerprintmatch
running…
control: waiting
planted witnesses: waiting
positive control (infinite capacity): waiting
flow conservation: waiting
cross-method flow solve (Jacobi vs elimination): waiting
decomposition check (5 and 6 runs, shared seeds): waiting
fitter's controls (synthetic exponential and synthetic power law): waiting
engine hash: waiting

What none of this rules out. The battery proves the two implementations agree, and agreement does not rule out a fault the two share: they were written from one contract, so the instruments that can catch a misreading of it are the ones outside it, the planted fixtures whose extents are worked out by hand, the conservation recomputed from the record rather than by the solver, and the Jacobi cross-check. The decomposition check rules out a chunk-boundary mistake and very little else. The invariants rule out solver drift, not a shared misunderstanding of cascading. And a power-law fit on this model's output describes this model: alternating-current flow, hidden failures and operator response all change the exponent, published values for real grids are contested, and this page makes no claim about any real grid or any real event. The fitter's controls exist because a KS distance is not comparable across datasets and windows: over two thirds of a decade, almost any smooth density looks straight on logarithmic paper, and an earlier form of this check rewarded exactly that. The page instead compares the power law against a shifted exponential on the same window by log-likelihood, normalised by its own sampling error, and it runs that comparison on two kinds of synthetic data before believing anything it says about the model: exponential samples, which it must never call a power law, and real power-law samples of the same tail size and window width, which it must always call one. Held to that test, this model's own tail does not separate the two: the comparison lands inside the band where the hypotheses are indistinguishable, it falls on opposite sides of zero for the two halves of your own ensemble, and in the offline gate it falls on the other side again for a run of twice the size. So the honest reading of the straight line above is a tail with no characteristic size over the fitted window, with an exponent quoted as a descriptor of that line under these parameters, and not a demonstration that the law is a power law. That leaves stretched-exponential, log-normal and truncated power-law alternatives open as well, which a window under two decades could not have separated either.

The cost, measured rather than boasted

Operations (engine's own counter)

Wall time · workers

vs main-thread JavaScript

The speed factor is measured on a slice and scaled, and the slice it came from is printed next to it, because a scaled number is an extrapolation and saying so is the difference between a measurement and a boast.

What's exact here, what's a model, and what the small version gets wrong

Exactly true. The determinism: each run is a pure function of its seed, verified byte-for-byte under two chunk assignments. The planted fixtures: a network built so one trip must cascade to exactly three lines and shed exactly 1.0, and the machinery finds exactly that, on every cascade, because a fixture restarts from its scheduled demand each time. The positive control: infinite capacity sheds nothing, ever. The conservation law: generation minus demand balances at every node of every solve, reported as a relative residual (each node's imbalance divided by its island's largest injection, so the bound is scale-free) and asserted under 1e-9; the offline verifier recomputes it independently from the recorded angles and flows, with a tamper control that proves the bound can fail. The two estimators and their interval are computed from the events you just generated, not quoted.

Measured, and not settled. Which law the tail follows. The exponent is a maximum-likelihood descriptor of the best straight line over the fitted window, quoted with a bootstrap interval. On this data the same-window comparison against a shifted exponential lands inside the band where the two cannot be told apart, and it stays there for either half of the ensemble and for an ensemble of twice the size, while the same comparison detects a genuine power law of this tail size and window every time it is shown one. So the tail has no characteristic size across the fitted range, and that is as far as this page can take you.

Idealised. Direct-current flow, not alternating-current. No hidden failures, no operator response, no maintenance, no weather. Generators are unlimited and dispatch equally. The network is a planar toy grown by one rule. The trip rule is simultaneous and deterministic. Demand restoration is a linear relaxation, chosen because the alternative ratchets the network dead (see the research README's spec corrections).

The wrong lesson, named. The single cascade above is not a simplified version of the statistical picture. It teaches a different and false model of risk: that the size of the outcome tells you something about the size of the cause. In the long run, the largest blackouts are started by line trips indistinguishable from the thousands that go nowhere. Size lives in the system's loading, not in the spark.