One message, a thousand withdrawals
Public route collectors record every BGP message they receive. Most routing research, ours included, starts with those files. This post is about one number you can pull out of them: how many prefixes a single UPDATE message carries. Across one week and the whole collector fleet the answer is 2.87. The number is correct, and on its own it tells you almost nothing.
A thousand prefixes in one message
On 21 October 2026, at 04:05 UTC, the RIPE RIS collector rrc24 recorded an unusual five minutes from AS46997. One UPDATE message withdrew 1,133 network prefixes. Across that whole file the session withdrew 1,079,048 prefixes in 1,069 messages, and the median message carried 1,008 of them.
The fleet average that week was 2.87.
Nothing here is broken. A BGP UPDATE tops out at 4 KB. A withdrawal is a list of prefixes, roughly four bytes each for IPv4, so about a thousand fit in one message. An announcement also has to carry the path attributes: origin, AS path, next hop, often communities. The same 4 KB then holds a handful of prefixes. The largest single withdrawal message we saw all week was 1,197 prefixes, from AS29691 at rrc20, just under that ceiling.
Once you have seen those two shapes, the average of 2.87 starts to look like a number that mostly measures how often each shape shows up.
What we counted
Public route collectors write their data to MRT files: RIPE RIS every five minutes, RouteViews every fifteen. Each BGP UPDATE message can carry several route entries, called NLRI (network layer reachability information). One entry is one prefix being announced or withdrawn. A message announcing ten prefixes is one message and ten NLRI.
Define packing as NLRI per message. A router that batches hard has high packing; a router that sends one prefix per message sits near 1. The denominator is the record count for that session, which matters in one place below: RouteViews update files contain only UPDATE records, while RIPE RIS files also record keepalives and state changes, so RIS numbers come out about 2.5% low.
We processed every update file published between 2026-10-16 20:00 and 2026-10-23 20:00 UTC:
- 79 collectors: 23 from RIPE RIS, 56 from RouteViews
- 83,999 update files, 98.9% of which we could attribute to individual sessions
- 20.82 billion NLRI carried in 7.25 billion records
- 2,696,994 per-file session records, covering 2,846 peer addresses
Packing is not traffic, and it is not convergence time. It is a choice about how to serialize updates, which is what makes it measurable from the outside without seeing inside anybody’s network.
The shape of the fleet
Over the week, the fleet-wide weighted packing was 2.872 NLRI per message. Counting at file level instead gives 2.865, and the per-session mean is 2.711 with a median of 2.229. Three ways of counting, all within 0.3% of each other.
Figure 1. Distribution of packing across 2.7 million file-sessions, 2026-10-16 to 10-23 UTC.

Four in ten sessions sit between 1.5 and 2.5 NLRI per message, and another 13% sit between 1.0 and 1.5. Then comes the tail: 1.05% of sessions go above 10, and 169 of 2.7 million go above 100. Those 169 carry a disproportionate share of the traffic, which is where the AS6939 numbers below come in.
Same week, same Internet, threefold difference
Figure 2. Networks with more than 50 million NLRI over the week, ranked by packing.

The busiest packer among large peers was AS16276 (OVH) at 6.05 NLRI per message, and it barely moved all week: between 5.81 and 6.40 every single day. AS142289 (Roxonic Systems) came next at 5.95, then AS38880 (Micron21) at 5.22 and AS24115 at 4.86.
At the other end: AS212635 at 1.62, AS51185 at 1.92, AS31027 at 1.98, and AS32590 (Valve Corporation) at 2.20.
All of these networks send a full BGP feed, and they differ by a factor of three. That is a real difference in behavior, not a measurement artifact. What we cannot do is explain it. Peer role (transit or exchange member), router vendor, address family mix, local policy: all plausible, and none of them visible in MRT. What the data does say is that the behavior is stable. OVH stayed inside a narrow band for seven days, which is not what noise looks like.
Trickle and bulk: one session, two modes
AS6939 (Hurricane Electric) is the case that taught us the most, partly because our first read of it was wrong. The same network shows up at many collectors and behaves differently at each.
Figure 3. AS6939 across four sessions on 2026-10-22, by message size. Left: share of messages. Right: share of NLRI.

We took one file per hour for a full day and looked at AS6939’s sessions at two RIPE RIS collectors and two RouteViews collectors:
- rrc16 (IPv6 session): 14,396 messages, 89,825 NLRI, packing 6.24
- rrc16 (IPv4 session): 2,594 messages, 10,378 NLRI, packing 4.00
- route-views2 (IPv4): 147,882 messages, 425,444 NLRI, packing 2.88
- route-views6 (IPv6): 146,780 messages, 281,911 NLRI, packing 1.92
The obvious guess is that the RIS session was batching harder. Counting message sizes says otherwise. In all four sessions, between 60% and 71% of messages carried exactly one prefix. One-prefix messaging is the norm everywhere; the sessions differ in the tail. At rrc16’s IPv6 session, 149 messages carried 100 or more prefixes, and those messages hold 67% of all NLRI. At route-views6, 8 messages in an entire day crossed 100, together 0.5% of NLRI.
That tail is not an artifact of big messages quietly carrying more. Inside one five-minute file at rrc16, five messages carried 1,957 prefixes, about 391 each, close to what a 4 KB IPv6 message can hold. The other 575 prefixes in the same file arrived one per message, and the two groups had no prefix in common.
So the same network runs both modes at once: bulk for one set of prefixes, trickle for another.
Three explanations we could rule out:
- Window length. RIS files are five minutes and RouteViews files are fifteen. Combining three consecutive rrc16 files gives a fifteen-minute window with packing 6.67, still 3.5 times the RouteViews session.
- Add-path. Both sides record
BGP4MP_MESSAGE_AS4(subtype 4), not the add-path subtype 9. - Collector-triggered refresh. The file contains no locally originated records and no route refresh, so the bulk messages came from the peer unprompted.
What we still cannot say is why AS6939’s sessions differ. That is outbound policy or implementation on specific sessions, and MRT does not carry it. So the claim we are willing to make is smaller than the one we started with: cross-collector packing differences come from content shape, and reading them as a uniform batching policy is a mistake.
Withdrawals are the exception
Withdrawals are a minority of the stream: 1.49 billion withdrawal NLRI against 20.82 billion total, or 7.13%. They behave nothing like announcements.
Figure 4. Largest single withdrawal message observed per network in the week, against the fleet average of 2.87 NLRI per message.

Sessions that mostly withdrew, with 80% or more of their NLRI withdrawn, averaged 37.84 NLRI per message. Sessions with no withdrawals at all averaged 4.50. The extremes are worth seeing: AS1257 (Tele2) withdrew 426,062 prefixes at rrc25 on 19 October in 422 messages, the largest carrying 1,089, followed by two more bursts of 347,427 and 148,759 over the next ten minutes. AS328840 withdrew 636,782 prefixes in 787 messages at rrc00 on 18 October, largest 1,078. AS8359 and AS51519 also crossed 600 prefixes in a single message.
Rare, though. Of 2.7 million session records, 169 went above 100 NLRI per message. But when a network drops a large part of its table, it does it in the densest messages BGP allows, because there are no attributes to carry.
When the shape breaks
On 23 October 2026, at 12:17 UTC, six RouteViews collectors lost their BGP sessions within seconds of each other. The session events themselves are not in the files. What they did to the update stream is.
Figure 5. Packing and withdrawal share per 15-minute slot for three RouteViews collectors during the 23 October reset.

In the 12:15 slot, route-views2 jumped from 2.47 to 6.18 NLRI per message while its withdrawal share collapsed from 7.99% to 0.03%. route-views5 went from 2.08 to 5.75 with withdrawals falling from 9.69% to 0.15%. route-views8 went from 3.00 to 6.77, withdrawals from 13.28% to 0.30%. Each collector re-advertised its full table in the densest form available, then settled back within 45 minutes.
The RIPE RIS collectors were fine, with flat session state-change counts through the same window.
RouteViews is also why we hedge on this one. Its update files hold only
BGP4MP UPDATE records, with no OPEN, KEEPALIVE or STATE_CHANGE entries, so the
reset is inferred from the shape of the update stream, not observed directly. A
synchronized silence followed by a full re-advertisement with almost no
withdrawals does not have another ordinary explanation, but it is still an
inference.
What this is good for
Do not compare file sizes across archives. RIPE RIS writes gzip and RouteViews writes bzip2, so the same traffic differs by roughly a factor of two in bytes. Packing is 2.804 for RIS and 2.922 for RouteViews, and once the RIS denominator is corrected for keepalive and state-change records the two are effectively the same. The content shape is identical; the compressor is not.
Packing also works as a cheap detector. NLRI per message plus withdrawal share, two numbers per file, identify a full-table replay without any session state. That is useful exactly where session records are missing, which is every RouteViews update file.
And capacity planning should count NLRI, not messages. During a replay, elements per second rise about 2.5 times while message counts rise far less, so a pipeline sized on messages per second will under-provision exactly when a collector resets.
What this does not say
- Only update files are covered, not RIB dumps. RIB packing is a different measurement.
- The per-session breakdown covers the seven days studied here; earlier periods are not included.
- The AS6939 case is one day and one sample per hour. It is enough to establish that the two modes coexist, not to characterize how often the bulk mode fires.
- Packing is not BGP message rate, convergence time, or traffic volume. It says nothing about how fast a network converges.
Reproduce it
Everything here comes from public archives, and the toolchain is open source. Download any update file from the RIPE RIS or RouteViews archives, then expand it into elements with bgpkit-parser:
bgpkit-parser updates.20261022.1200.gz
Each output line is one NLRI with its peer, timestamp, and path attributes, so counting lines per peer gives the NLRI total, and counting MRT records gives the message total. BGPKIT Broker locates the files; Monocle does the same slicing from the command line.
Figures were generated with matplotlib from the same aggregates.