Why does a 32-bit SNMP ifInOctets counter fail on a 10 Gb/s link, and what does RFC 2863 require instead?
answer
- two to the thirty-second octets
- seconds, not minutes, at 10G
- more than one wrap per poll
- high-capacity objects in ifXTable
- 20 and 650 Mb/s
basics
~20 sA Counter32 octet counter wraps after 2^32 octets, about 3.4 seconds at 10 Gb/s, so a poller cannot count the wraps between polls. RFC 2863 requires 64-bit ifHCInOctets above 20 Mb/s, and 64-bit packet counters from 650 Mb/s.
solid answer
~50 s`ifInOctets` is a `Counter32`: it climbs to 4,294,967,295 and wraps to zero. At a sustained 10 Gb/s that takes 2^32 x 8 / 10^10 = about 3.4 s, so a 300 s poll can contain dozens of wraps, and a delta taken modulo 2^32 is only right if at most one wrap occurred. RFC 2863 therefore adds `Counter64` versions in `ifXTable`: above 20 Mb/s the 64-bit octet counters (`ifHCInOctets`, `ifHCOutOctets`) must be supported, and at 650 Mb/s or faster the 64-bit packet counters as well. A Counter64 at 10 Gb/s takes about 468 years to wrap. The 32-bit objects stay and must report the low 32 bits of their 64-bit twins, so a poller must deliberately ask for the HC objects, and must use a v2c or v3 request, because the coexistence rules (RFC 3584) forbid returning a Counter64 to an SNMPv1 request.
go deeper
Recall that SNMP interface counters roll over to zero at their maximum, and that fast links need the 64-bit high-capacity counters such as ifHCInOctets.
Compute the wrap time from 2^32 x 8 divided by the line rate, and explain why one wrap is recoverable and several are not.
Walk through RFC 2863's 20 Mb/s and 650 Mb/s thresholds, why the 32-bit objects still answer with the low half, and how a backwards 64-bit counter signals a restart.
Weigh an estate audit for pollers still reading 32-bit objects against faster polling, and decide how to treat devices or protocol versions that cannot serve Counter64.
## Counters wrap, and the wrap time is arithmetic SMIv2 (RFC 2578) defines `Counter32` as a non-negative integer that increases until it reaches 2^32-1 (4,294,967,295) and then "wraps around and starts increasing again from zero". `Counter64` does the same at 2^64-1. In IF-MIB (RFC 2863), `ifInOctets` and `ifOutOctets` in `ifTable` are `Counter32`; `ifHCInOctets` and `ifHCOutOctets` in `ifXTable` are `Counter64`. The minimum wrap time for an octet counter is the number of bits it can count divided by the line rate: **2^32 x 8 / rate**. | Line rate | Counter32 octet wrap at full load | |---|---| | 10 Mb/s | 3,436 s, about 57 minutes | | 100 Mb/s | 344 s, about 5.7 minutes | | 1 Gb/s | about 34 seconds | | 10 Gb/s | about 3.4 seconds | | 100 Gb/s | about 0.34 seconds | RFC 2863's own figures agree: just over 57 minutes at 10 Mb/s, 5.7 minutes at 100 Mb/s, 34 seconds at 1 Gb/s. The same arithmetic for `Counter64` gives about 468 years at 10 Gb/s and, as the RFC notes, just under 5 years at 1 Tb/s. ## Why one wrap is fixable and many are not A poller that sees the second reading smaller than the first can assume one wrap and compute `(new - old + 2^32) mod 2^32`. That is correct only if **at most one** wrap happened. Nothing in a counter's value records how many times it passed zero. Take the reserved scenario: a 10 Gb/s uplink running at 3 Gb/s, polled every 300 s on the 32-bit counter. 1. Octets in 300 s: 3,000,000,000 x 300 / 8 = 112,500,000,000. 2. Wraps: 112,500,000,000 / 4,294,967,296 = about 26.2. 3. What the modulo delta sees: 112,500,000,000 - 26 x 4,294,967,296 = 830,850,304 octets. 4. Reported rate: 830,850,304 x 8 / 300 = about 22 Mb/s, roughly 0.2% of a link that is 30% busy. The graph is not noisy; it is quietly wrong. Polling faster does not rescue it either: at line rate the interval would have to be under 3.4 s on every interface. ## What RFC 2863 requires RFC 2863 rejected scaled counters (counting in 1,024-octet blocks) because they make light traffic look bursty, and adopted 64-bit "high capacity" groups instead: - **20,000,000 bit/s or less**: 32-bit octet and packet counters must be supported. - **Faster than 20,000,000 and slower than 650,000,000 bit/s**: 64-bit octet counters must be supported; 32-bit packet counters remain enough. - **650,000,000 bit/s or faster**: 64-bit octet **and** packet counters must be supported (`ifHCInUcastPkts` and the rest), because 32-bit packet counters wrap in about 57 minutes with back-to-back 64-octet packets at that rate. Separately, SMIv2 lets a standard MIB use `Counter64` only where a `Counter32` would wrap in less than an hour. RFC 2863 calls its thresholds a reasonable compromise, which deliberately leaves 10 Mb/s Ethernet, with its 57-minute wrap, on 32-bit counters. ## The traps that remain after you switch - The 32-bit objects are **not deprecated**. When 64-bit counters exist the 32-bit ones must still answer, with the low 32 bits of the 64-bit count (`ifInOctets` = low half of `ifHCInOctets`). A poller left on `ifInOctets` gets plausible-looking numbers and the multi-wrap error above. - `Counter64` arrived with SMIv2. The coexistence rules (RFC 3584) say a multi-lingual agent never returns a Counter64 in a response to an SNMPv1 request, so the high-capacity objects need a v2c or v3 request. - A 64-bit counter that goes **backwards** has, in practice, not wrapped; at these rates a wrap takes centuries. It restarted, and the delta must be discarded, not "corrected". - The 64-bit counters do not remove the need for the discontinuity checks: `sysUpTime` and `ifCounterDiscontinuityTime` still decide whether a delta is valid. ## Auditing a poller for this defect 1. List the interfaces faster than 20 Mb/s (`ifSpeed` above 20,000,000, or `ifHighSpeed` above 20) and confirm the poller reads `ifHCInOctets` and `ifHCOutOctets` for them, not `ifInOctets` and `ifOutOctets`. 2. For interfaces at 650 Mb/s and faster, confirm packet rates come from the `ifHC...Pkts` objects as well. 3. Confirm those requests are sent as v2c or v3, so the agent is allowed to return `Counter64` values. 4. Compare one interface's graph against a hand calculation from two `ifHCInOctets` readings; a 32-bit poller on a busy fast link reads far too low.
- Is a 300 s poll of 32-bit counters safe on a 100 Mb/s interface?Just. At full load a Counter32 octet counter wraps every 2^32 x 8 / 10^8 = about 344 s, so a 300 s interval sees at most one wrap and modulo-2^32 correction works, with little margin for a late poll. RFC 2863 still requires 64-bit octet counters above 20 Mb/s, so the right answer is to poll `ifHCInOctets`.
- Why did RFC 2863 not simply count octets in larger units to avoid the wrap?It considered scaled counters, for example counting 1,024-octet blocks, and rejected them: on a lightly used link the counter would move only rarely, so traffic would look bursty and lead to wrong conclusions. It added 64-bit counters instead and kept the 32-bit ones for compatibility.
- A poller sees ifHCInOctets lower than at the previous poll on a 10 Gb/s link; should it apply wrap correction?No. A Counter64 at 10 Gb/s needs about 468 years to wrap, so a decrease means the counter restarted: an agent re-initialisation or another discontinuity. The poller should discard that interval, confirm with `sysUpTime` and `ifCounterDiscontinuityTime`, and resume from the new reading.
saying these in an interview costs you the question
- At 10 Gb/s a 32-bit octet counter still takes several minutes to wrap
- Modulo-2^32 correction fixes any number of wraps between polls
- RFC 2863 deprecated ifInOctets once ifHCInOctets existed
- Only octet counters ever need 64 bits; packet counters never wrap
- A 64-bit counter that went backwards just wrapped and can be corrected
- Polling faster is a fine substitute for 64-bit counters on 10G links