rustbgpd
- Established
- 0.8 s
- Base-table delivery
- 3.1–3.3 s
steel withdraw · orange re-announce
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.
Field reports. Not receipts.
Field report · 2026-08-26
First contact with the default-free zoneTwo live full tables. 136 observed AS_SET dispositions. Not a receipt.
Matrix · 2026-08-20
700 clients, 400,400 routesPolicy reload in 1.4s where BIRD takes 80s. Canonical on lance0.com.
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.
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.
| Daemon | Established | Base-table delivery |
|---|---|---|
| rustbgpd | 0.8 s | 3.1–3.3 s |
| BIRD 3.3.2 (dated) | 15.2–17.8 s | 67.3–70.1 s |
| OpenBGPD 9.3 | 126.2–209.9 s | 365.7–449.8 s |
Six legs per daemon (S2 + S3 × three runs). [source receipt]
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.
| Daemon | Withdraw p50 | Re-announce p50 |
|---|---|---|
| rustbgpd | 0.24–0.30 s | 0.36–1.02 s |
| BIRD 3.3.2 (dated) | 0.68–0.99 s | 3.27–4.06 s |
| OpenBGPD 9.3 | 8.46–9.60 s | 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]
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.
| Daemon | Stall p50 | Stall worst | Completion p50 | Completion worst |
|---|---|---|---|---|
| rustbgpd | 35.4–51.8 ms | 132.6 ms | 0.84–0.96 s | 1.00 s |
| BIRD 3.3.2 (dated) | — | — | 89.06–103.61 s | 118.20 s |
| OpenBGPD 9.3 | 193.1–251.9 ms | 291.6 ms | 205.91–215.36 s | 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]
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.
| Daemon | Completion p50 | Cgroup peak |
|---|---|---|
| rustbgpd | 0.598–0.853 s | 759–931 MiB |
| BIRD 3.3.3 | 12.884–15.858 s | 1,378–1,597 MiB |
| OpenBGPD 9.3 | 44.921–64.451 s | 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]
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.
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
v0.73.0 tag, 2026-09-28
1,000 iBGP clients × 100 routes (100,000 total) under churn, 24 h
v0.77.0 tag, 2026-10-12
150 iBGP EVPN clients × (200 Type 2 + 50 Type 5) under churn, flaps and reloads, 24 h
The receipts also include the losses.
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 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]
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]
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.
ghcr.io/lance0/rustbgpd:0.81.0, take a release tarball, or build from a checkout (protobuf-compiler required).