Antifragile System
The same adaptive loop, two fates: with one knob negative each failure makes the system stronger; flip its sign and failures spiral to certain breakdown.
Level: Beginner
Feedback Loops
Understand the balancing and reinforcing feedback loops that drive system behavior and create complex dynamics in systems thinking.
Take the QuizFragile or antifragile? The sign of one feedback loop
A system fails at random, and after each failure it adjusts itself — but which way? An antifragile system gets stronger from stress: every failure makes the next one less likely, so failures grow rare. A fragile one does the opposite — each failure makes the next more likely, and a death spiral takes hold.
The knob is fragility. Negative heals (antifragile); positive runs
away (fragile). Same random shocks, opposite fates.
from tys import probe, progress
Simulate a system whose failure rate adapts after every failure.
def simulate(cfg: dict):
import random
random.seed(cfg.get("seed", 0)) # deterministic backbone
failure_rate = cfg["failure_rate"] # probability of failing this step (the stock)
fragility = cfg["fragility"] # <0: heal after a failure, >0: worsen
iterations = cfg["iterations"]
failures = 0
for t in range(iterations):
if random.random() < failure_rate:
failures += 1The failure reshapes the odds of the next one — down if antifragile, up if fragile.
failure_rate = min(max(failure_rate * (1 + fragility), 0.0), 1.0)
probe("failure_rate", t, failure_rate)
probe("total_failures", t, failures)
progress(int(100 * (t + 1) / iterations))
return {
"failures": failures,
"final_failure_rate": failure_rate,
"recovered": failure_rate < cfg["failure_rate"],
}
def requirements():
return {
"external": [],
}
# antifragile.yaml — the default: fragility < 0, so each failure makes the
# system more reliable and failures die out.
failure_rate: 0.3
fragility: -0.1
iterations: 50
seed: 0
| Metric | Value |
|---|---|
| failures | 5.00 |
| final_failure_rate | 0.18 |
| recovered | true |
# fragile.yaml — the contrast: identical except fragility flips positive, so
# each failure makes the next more likely and the failure rate runs away to 1.
failure_rate: 0.3
fragility: 0.1
iterations: 50
seed: 0
| Metric | Value |
|---|---|
| failures | 28.00 |
| final_failure_rate | 1.00 |
| recovered | false |
- What is the difference between the fragile and antifragile runs?
- Both adapt after every failure; the sign of fragility sets the direction. Below zero the failure_rate is multiplied down after each failure (the system heals); above zero it is multiplied up, so each failure makes the next more likely.
- Where is the tipping point?
- At fragility = 0 the failure rate never changes. Any negative value drives failures toward zero; any positive value pushes the rate toward 1.0, where every step fails.
- Why does the fragile run end at a failure rate of 1.0?
- Each failure raises the rate, which causes more failures, which raise it further - a reinforcing loop that saturates at certainty (the rate is clamped to 1.0).
- What is a real-world example?
- A service hardened by chaos engineering grows more reliable after each incident (antifragile); a codebase where every rushed patch adds fragility accumulates until it breaks constantly (fragile).