You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(demos): flapping herd outage for faithful spikes-with-gaps
The herd's sustained outage produced a smooth rising ramp for
independent, un-synchronized naive clients, not the spikes-with-gaps
the tour copy claims. Switch the model input to a flapping backend
(down/recover x3) so unbounded retries genuinely surge on each dip
and clear on recovery -- real spikes-with-gaps, faithfully sourced
from backend recovery rather than client synchronization. The
existing simulateHerd algorithm already produces this shape once the
fault flaps; this is a scenario + rendering + copy change.
Add computeOutageBands so the rate strip shades each dip separately,
leaving recovery gaps visibly unshaded between them (falls back to
the single outage window for callers that don't pass bands, so the
full-stack macro strip is unaffected). Re-measure the naive
multiplier against the flapping scenario (~18x, down from the
sustained model's ~70x since each dip is shorter) and reconcile
retry.md's copy and the change-file's motivation/design/payoff
language to match.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/demos/retry.md
+14-11Lines changed: 14 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -47,24 +47,27 @@ document.addEventListener('DOMContentLoaded', function () {
47
47
48
48
HttpwareDemo.mountHerd('#retry-herd', {
49
49
clients:20,
50
+
intro:'A real backend rarely dies cleanly — it <b>flaps</b>: fails, recovers, fails again. These strips show <b>backend call-rate over time</b> for twenty clients through three dips. Press play and watch the shape.',
{ when: (s) =>s.revealed>=Math.round(2.2/sim.dt), spot: ['naiveStrip', 'hwStrip'],
57
-
title:'The outage hits both herds',
58
-
body:'Twenty naive clients and twenty httpware clients face the same sustained outage. Every failed request wants to retry. Watch what each herd does to the backend call-rate.' },
59
-
{ when: (s) =>s.revealed>=Math.round(4.0/sim.dt), spot: ['naiveStrip'],
60
-
title:'Naive: synchronized spikes',
61
-
body:'All twenty naive clients back off the SAME fixed delay, so a batch that fails together retries together — the failures never spread out. Tall spikes with dead gaps between: the retry storm hammering a backend that is already down.' },
62
-
{ when: (s) =>s.revealed>=Math.round(6.5/sim.dt), spot: ['hwStrip'],
63
-
title:'httpware: a near-flat rate',
64
-
body:'Full jitter scatters each client’s retries across the window instead of stacking them, and each client’s own budget + max_attempts cap how much it can add — so the aggregate holds at a low, steady few-times-baseline instead of exploding.' },
60
+
title:'A flapping backend',
61
+
body:'The backend drops, recovers, drops again — three dips (shaded). Every failed request wants to retry. Watch what each herd does to the backend call-rate through the dips.' },
62
+
{ when: (s) =>s.revealed>=Math.round(4.6/sim.dt), spot: ['naiveStrip'],
63
+
title:'Naive: a surge on every dip',
64
+
body:'On each dip, twenty clients retry unbounded — the load piles up into a surge that keeps climbing until the backend recovers, then clears. Three dips, three spikes, with recovery gaps between: the retry storm hitting a backend every time it tries to come back.' },
65
+
{ when: (s) =>s.revealed>=Math.round(8.2/sim.dt), spot: ['hwStrip'],
66
+
title:'httpware: flat through every dip',
67
+
body:'Full jitter spreads each client’s retries out, and each client’s own max_attempts=3 cap (with its per-client budget as the guarantee at higher volume) limits how much it can add — so httpware holds a low, steady few-times-baseline through every dip instead of spiking.' },
65
68
{ when: (s) =>s.revealed>=sim.buckets-1, spot: ['naiveMult', 'hwMult'],
66
69
title:'Peak load: the whole point',
67
-
body:'The naive herd peaked at about 70× the healthy load — and keeps climbing the longer the outage runs, because its retries are unbounded. httpware peaked at about 3×: at this client count, that ceiling comes from each client’s own max_attempts=3 cap (jitter just spreads the retries flat instead of stacking them). The per-client budget is what holds the line as the herd grows even larger. Same outage, same client count — a flat rate also leaves the backend room to recover.' },
70
+
body:'On its worst dip the naive herd spiked to about 18× the healthy load; httpware never exceeded about 3×, capped by each client’s max_attempts. That flat rate is exactly what lets the backend recover in the gaps — instead of being knocked back down by a retry surge every time it heals.' },
Copy file name to clipboardExpand all lines: planning/changes/2026-07-19.02-resilience-demo-herd-and-enrich.md
+37-31Lines changed: 37 additions & 31 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,5 @@
1
1
---
2
-
summary: Added a many-client thundering-herd macro view to the retry page (naive ~70x vs httpware ~3x peak backend load, httpware bounded by max_attempts at demo scale with a per-client budget) and folded three enrich techniques across the demo suite — a backoff countdown ring on timeout + circuit-breaker only (retry's sub-tick backoff makes a faithful ring there impossible, so it's dropped, not faked), a color-independent jagged failure shape everywhere, and a live backend call-rate macro strip with active-phase label on the full-stack page.
2
+
summary: Added a many-client thundering-herd macro view to the retry page (naive ~18x vs httpware ~3x peak backend load through a flapping outage, httpware bounded by max_attempts at demo scale with a per-client budget) and folded three enrich techniques across the demo suite — a backoff countdown ring on timeout + circuit-breaker only (retry's sub-tick backoff makes a faithful ring there impossible, so it's dropped, not faked), a color-independent jagged failure shape everywhere, and a live backend call-rate macro strip with active-phase label on the full-stack page.
3
3
---
4
4
5
5
# Design: Resilience demo herd view + enrich pass
@@ -9,7 +9,7 @@ summary: Added a many-client thundering-herd macro view to the retry page (naive
9
9
Improve the resilience demo suite (shipped in `2026-07-18.02`) using techniques
10
10
proven by the best existing visualizations. Two parts: (1) a **thundering-herd
0 commit comments