withdraw p50
0.00s
re-announce
0.00s

steel withdraw · orange re-announce

rustbgpd

A BGP route server and route reflector in Rust.

Animated topology of a BGP flapstorm. A steel withdrawal wave, then a Ferris-orange re-announce flood. Withdraw p50 0.25 seconds. Re-announce 0.39 seconds. Press R or use Replay to run it again.

W

Wire

Field reports. Not receipts.

All of the wire →

00

IXP Manager

verified IXP Manager 7.4 Bird's Eye API compatibility with documented BIRD-internal divergences.

Pinned IXP Manager v7.4.0 consumer journeys against BIRD 2.0.12 + Bird's Eye 2.1.0. Fail-closed allow-list; remaining divergences are named under Honesty. [source contract]

Route views match the pinned oracle's field shapes. Protocol and export lookups use its longest-match behavior; fallback scans stay within the queried address family and have a separate route-scan bound. An incomplete scan returns HTTP 403 instead of evaluating a partial view.

01

Cold convergence

700 clients × 400,400 routes, same host, same harness. Time for all 700 sessions to reach Established, then for every observer to hold the full base table. rustbgpd v0.80.0 and OpenBGPD 9.3 ran on one host in the same night, 2026-10-25, three runs each with the daemon order alternated. The BIRD 3.3.2 row is dated: it was measured 2026-10-03 to 2026-10-04, against rustbgpd v0.74.0. BIRD did not run in the v0.80.0 matrix; BIRD 3.3.3 is measured in the IRR roots only.

rustbgpd

Established
0.8 s
Base-table delivery
3.1–3.3 s

BIRD 3.3.2 (dated)

Established
15.2–17.8 s
Base-table delivery
67.3–70.1 s

OpenBGPD 9.3

Established
126.2–209.9 s
Base-table delivery
365.7–449.8 s

Six legs per daemon (S2 + S3 × three runs). [source receipt]

02

Flapstorm propagation

700 clients × 400,400 routes, same host, same harness. 50 members hard-close simultaneously; 650 survivors observe 28,600 withdrawn prefixes. The 50 reconnect and re-announce. rustbgpd v0.80.1 ran three runs of its release tag on 2026-10-25. OpenBGPD 9.3 ran in the v0.80.0 queue the same day, on the same host and inputs but not alongside them. The BIRD 3.3.2 row is dated: it was measured 2026-10-03 to 2026-10-04, against rustbgpd v0.74.0. BIRD did not run in either 2026-10-25 matrix.

rustbgpd

Withdraw p50
0.24–0.30 s
Re-announce p50
0.36–1.02 s

BIRD 3.3.2 (dated)

Withdraw p50
0.68–0.99 s
Re-announce p50
3.27–4.06 s

OpenBGPD 9.3

Withdraw p50
8.46–9.60 s
Re-announce p50
17.88–18.55 s

The re-announce clock starts only after all 50 sessions re-reach Established, so it measures re-delivery fan-out (~18.6M NLRI), not reconnect pacing. [source receipt]

02b — policy reload

Policy reload

700 clients × 400,400 routes, same host, same harness. SIGHUP policy reload stall and completion — not the IRR filter refresh below. rustbgpd v0.80.0 and OpenBGPD 9.3 ran on one host in the same night, 2026-10-25, three runs each with the daemon order alternated. The BIRD 3.3.2 row is dated: it was measured 2026-10-03 to 2026-10-04, against rustbgpd v0.74.0. BIRD did not run in the v0.80.0 matrix; BIRD 3.3.3 is measured in the IRR roots only. The stall harness changed after v0.75.0, so the stall is compared within the 2026-10-25 night only.

rustbgpd

Stall p50
35.4–51.8 ms
Stall worst
132.6 ms
Completion p50
0.84–0.96 s
Completion worst
1.00 s

BIRD 3.3.2 (dated)

Stall p50
—
Stall worst
—
Completion p50
89.06–103.61 s
Completion worst
118.20 s

OpenBGPD 9.3

Stall p50
193.1–251.9 ms
Stall worst
291.6 ms
Completion p50
205.91–215.36 s
Completion worst
215.36 s

Stall = the longest gap between UPDATE arrivals at a member while the reload is in flight. Completion = every member verifiably holds the full new-policy table. The three reload paths are not the same amount of work: SIGHUP re-parses only rustbgpd’s policy files, birdc configure re-parses BIRD’s entire config and re-evaluates its filters, and bgpctl reload re-parses and soft-reconfigures OpenBGPD’s RDE. Each is that daemon’s documented route-server reload. BIRD 3.3.2’s dated stall, measured on the earlier harness, was 1,767–2,531 ms p50 with a worst observer of 9,285 ms; it is not ranked against this night. [source receipt]

IRR-scale filter reload

320 members × 183,040 prefixes, 0/10/50% received-view overlap. rustbgpd v0.80.0, BIRD 3.3.3 and OpenBGPD 9.3 in the same night, 2026-10-25, three cross-daemon roots per overlap. BIRD 3.4.0 is not measured. Every row 320/320 sessions. Cgroup peak is rustbgpd’s own scope or the competitor’s container, which also charges its reload clients; daemon and container defaults differ, so it is not a ranked comparison.

rustbgpd

Completion p50
0.598–0.853 s
Cgroup peak
759–931 MiB

BIRD 3.3.3

Completion p50
12.884–15.858 s
Cgroup peak
1,378–1,597 MiB

OpenBGPD 9.3

Completion p50
44.921–64.451 s
Cgroup peak
1,471–1,555 MiB

rustbgpd was 3.3–3.8 s at this shape in the earlier grouped per-client-best receipt, and 67–69 s ungrouped before ADR-0126. [source receipt] [source receipt]

03

24-hour soak receipts

Each card is the latest tagged run of its shape, archived in-repo. No control daemon ran alongside them. The EVPN run covers route reflection only, not VTEP or dataplane behavior.

Route-server shape

PASS

v0.80.1 tag, 2026-10-26

Rescored under the split management gate: 1 tolerated availability miss (a doctor health check during a reload); sessions and routing unaffected.

1,000 eBGP clients × 400 routes (400,000 total) under churn and management-plane load, 24 h

Analyzer gates passed
22 / 22
Barrier-verified SIGHUP policy reloads
48 / 48
Max-prefix trip → timed-restart cycles
6 / 6
Peak RSS
680.0 MB
Late-window RSS slope
+1.339 MB/h
/readyz bad samples
0 / 2,921
[source receipt]

Route-reflector shape

PASS

v0.73.0 tag, 2026-09-28

1,000 iBGP clients × 100 routes (100,000 total) under churn, 24 h

Analyzer gates passed
13 / 13
Churn cycles
5,493,035
Session flaps
0
Reflected prefixes per client, terminal check
99,900 exact
[source receipt]

EVPN route-reflector shape

PASS

v0.77.0 tag, 2026-10-12

150 iBGP EVPN clients × (200 Type 2 + 50 Type 5) under churn, flaps and reloads, 24 h

Analyzer gates passed
25 / 25
Exact per-epoch convergence checks
1,440 / 1,440
Client flaps · SIGHUP reloads
288 · 48
Invalid, self-reflected or unparsable routes
0
[source receipt]
04

Honesty

The receipts also include the losses.

OpenBGPD winsChanged-observer gap at IRR 50% overlap

At IRR scale (320 members × 183,040 prefixes) with 50% received-view overlap, OpenBGPD 9.3's changed-observer gap p50 is 365–448 ms vs rustbgpd v0.80.0's 589–623 ms. At 0% and 10% overlap the ranges overlap: 361–428 vs 380–413 ms and 356–445 vs 430–459 ms. [source receipt]

OpenBGPD winsFirst re-announced route after a member flap

OpenBGPD 9.3 delivers the first re-announced route to each survivor in 0.10–0.16 s p50 (median 0.13 s) vs rustbgpd v0.80.1's 0.24–0.90 s (median 0.25 s). It then needs 17.88–18.55 s to finish the re-announce, vs rustbgpd's 0.36–1.02 s. OpenBGPD's figures are from the v0.80.0 queue. [source receipt]

BIRD winsPeak memory sample

Dated, from the 2026-10-03 night: BIRD 3.3.2 had the lower peak RSS sample at both matrix shapes, 407–414 MiB vs rustbgpd v0.74.0's 540–541 MiB at S2 and 332–377 MiB vs 511–544 MiB at S3. Settled RSS under flap churn (S3) was mixed run by run (BIRD 377/332/373 MiB, rustbgpd 376/376/375 MiB); at S2 rustbgpd settled lower, 369/373/370 MiB vs 407/412/414 MiB. BIRD did not run in the v0.80.0 matrix; BIRD 3.3.3 is measured in the IRR roots only. [source receipt]

IXP Manager / Bird's Eye

The claim is scoped, not an unqualified Bird's Eye replacement. runtime_compatibility is true; a must_match divergence still re-blocks the flag. File-backed protocol aliases reload on SIGHUP; direct aliases stay startup-only. Product identity stays rustbgpd. Countdown timers and route-change counters stay unsupported; retained-reject namespace and retention metadata are extensions. Still named unsupported: defined-only reject-reason emission, a generic IXP Manager UI-filter policy engine, full-table counts, live hold/keepalive countdowns, and direct runtime alias reconfiguration. Config render and activation are the rs-config-render Foil path, not a Bird's Eye endpoint. 00 · [source contract]

rs-config-render publishes config.toml, policy/, and datasets/ as one immutable activation tree. If recover --apply stops on a later failure, it reports only the recovery steps that completed and keeps the nonzero result.

What this is and is not

  • Public alpha at v0.81.0. Not production-grade yet. The daemon is not on crates.io; only rustbgpd-wire, rustbgpd-fsm, and rustbgpd-rpki are published there. Pull ghcr.io/lance0/rustbgpd:0.81.0, take a release tarball, or build from a checkout (protobuf-compiler required).
  • Linux only. No FreeBSD, no Mac, no Windows.
  • EVPN is functional but outside the v1 compatibility promise.
  • Every receipt is currently self-generated — no external pilot yet.
  • OpenBGPD 9.3 delivers the first re-announced route sooner after a member flap and has the shorter changed-observer gap at IRR 50% overlap. rustbgpd's S2 reload cgroup peak is lower, 583–616 MiB against OpenBGPD 9.3's 989–1,003 MiB, and it settles lower: 375–376 MiB against 794–802 MiB at S2, and 410–418 MiB against 825–847 MiB at S3. In the dated BIRD 3.3.2 rows, BIRD has the lower peak memory sample at both matrix shapes, and settled memory under flap churn is mixed.