Reliability: when does a system fail?
A machine is built from many parts, and it keeps working only while every part still works — the parts are in series, like links in a chain. Each part fails at some random time. So when does the whole machine fail? At the moment its first part gives out.
This is a question you answer by simulation: build thousands of virtual machines, fail their parts at random, and look at the distribution of when each machine died. Slide the number of parts up and watch a sobering fact emerge — more parts means the system fails sooner, because there are more ways for it to break. All live in WebAssembly.
begin
using PlutoUI, WasmMakie
endnumber of parts (in series) =
per-part failure rate =
number of machines simulated =
let
# one flat loop over every part of every machine. Each part's lifetime is an
# exponential random variable, t = -ln(u)/rate; a machine fails at its EARLIEST
# part failure. Histogram those system failure times.
rate = Float64(ratei) / 100.0
nbins = 40
hi = 6.0 / (rate * Float64(nparts)) # a few mean-lifetimes wide
counts = Vector{Float64}(undef, nbins)
for b in 1:nbins
counts[b] = 0.0
end
s = 99173
mn = hi * 1000.0 # earliest failure so far in the current machine
c = 0
grand = nsims * nparts
for t in 1:grand
s = (s * 16807) % 2147483647
u = Float64(s) / 2147483647.0
if u < 0.0000001
u = 0.0000001
end
life = -log(u) / rate # this part's lifetime
if life < mn
mn = life
end
c += 1
if c == nparts # the whole machine has now been assembled
frac = mn / hi
b = Int64(floor(frac * Float64(nbins))) + 1
if b < 1
b = 1
end
if b > nbins
b = nbins
end
counts[b] += 1.0
mn = hi * 1000.0
c = 0
end
end
fig = Figure(size = (600, 340))
ax = Axis(fig[1, 1])
for b in 1:nbins
center = hi * (Float64(b) - 0.5) / Float64(nbins)
lines!(ax, [center, center], [0.0, counts[b]]) # a histogram bar
end
fig
endrel_stats = let
# compute the readout numbers in a SEPARATE bond-dependent cell (returns a tuple)
# so the markdown below interpolates them live — values buried inside a markdown
# cell's own `let` get baked to the slider defaults by the render-once splice.
rate = Float64(ratei) / 100.0
s = 99173
mn = 1.0e18
c = 0
total = 0.0
done = 0
grand = nsims * nparts
for t in 1:grand
s = (s * 16807) % 2147483647
u = Float64(s) / 2147483647.0
if u < 0.0000001
u = 0.0000001
end
life = -log(u) / rate
if life < mn
mn = life
end
c += 1
if c == nparts
total += mn
done += 1
mn = 1.0e18
c = 0
end
end
(floor((total / Float64(done)) * 100.0) / 100.0, floor((1.0 / rate) * 100.0) / 100.0)
end;Average time to first failure: about 2.47 (in the same units), versus 10.0 for a single part on its own. With 4 parts in series the machine fails roughly 4x sooner – its failure rate is the SUM of the parts' rates. Redundancy fights this; series chains make it worse.
The lesson of series systems
There is a clean law hiding in the histogram: when independent parts each fail at a constant rate, a series system's failure rate is the sum of the parts' rates. Ten parts that each last 100 hours on average give a machine that lasts only about 10. This is why complex hardware is hard to keep running, and why engineers add redundancy — parallel backups, so the system survives until the last copy fails instead of the first.
More broadly, this is reliability engineering by Monte Carlo: when the math of combining many random lifetimes gets hairy, simulate it. The same approach prices insurance, plans spare parts, and stress-tests power grids.
Appendix
The MIT lecture uses Distributions.jl / StatsBase / Plots.jl. WebAssembly can't run those in the browser, so part lifetimes come from an inline Park-Miller generator via t = -ln(u)/rate (the exponential distribution) and the histogram is drawn with WasmMakie. The series-failure law is exactly the textbook result.