skip to content

How do you compute a link's utilisation from SNMP IF-MIB octet counters polled twice, and which speed object do you divide by?

level: middleimportance: must knowfreq 42%

answer

  1. one reading means nothing
  2. difference over the interval
  3. octets to bits
  4. each direction on its own
  5. speed in megabit units

basics

~10 s

Difference two readings of ifHCInOctets (or ifHCOutOctets), multiply by 8, divide by the seconds between the polls, then divide by the interface speed, ifHighSpeed x 1,000,000 bit/s. Each direction is computed separately.

solid answer

~50 s

IF-MIB (RFC 2863) octet counters are cumulative and have no defined starting value, so utilisation needs two polls: `utilisation = delta-octets x 8 / (delta-t x ifHighSpeed x 10^6)`. Use the 64-bit `ifHCInOctets` / `ifHCOutOctets` from `ifXTable` and `ifHighSpeed`, which reports speed in units of 1,000,000 bit/s. On a 10 Gb/s uplink (`ifHighSpeed` = 10000) whose `ifHCInOctets` rose by 112,500,000,000 across 300 s, that is 900,000,000,000 bits / 300 s = 3 Gb/s, or 30% inbound. On a full-duplex link each direction has the whole capacity, so in and out are reported separately, not added. Do not divide by `ifSpeed` on a fast link: it is a Gauge32 in bit/s, it reports its maximum, 4,294,967,295, when the real speed is higher, and the RFC says `ifHighSpeed` must then be used. The result is an average over the interval; a 300 s poll smooths bursts away.

code

pseudocode · 12 lines
pseudocode
poll1 = get(sysUpTime.0, ifCounterDiscontinuityTime.i, ifHCInOctets.i, ifHighSpeed.i)
wait about 300 s
poll2 = get(sysUpTime.0, ifCounterDiscontinuityTime.i, ifHCInOctets.i, ifHighSpeed.i)

if poll2.sysUpTime < poll1.sysUpTime: discard   # agent re-initialised
if poll2.ifCounterDiscontinuityTime != poll1.ifCounterDiscontinuityTime: discard

seconds = (poll2.sysUpTime - poll1.sysUpTime) / 100
bits = (poll2.ifHCInOctets - poll1.ifHCInOctets) * 8
speed = poll2.ifHighSpeed * 1000000
utilisation = bits / seconds / speed
# 112,500,000,000 octets over 300 s at ifHighSpeed 10000 -> 0.30

go deeper

for a junior

Recall that SNMP interface counters only grow, so utilisation comes from the difference between two polls, converted from octets to bits and divided by the link speed.

for a middle

Explain the full formula with ifHCInOctets and ifHighSpeed, why ifHighSpeed is in megabit units, and why ifSpeed caps at 4,294,967,295 on a 10 Gb/s port.

for a senior

Show the validity checks before trusting a delta, sysUpTime and ifCounterDiscontinuityTime, per-direction reporting, real timestamps, and why an average hides bursts that discards reveal.

for a principal

Discuss what poll interval buys: a shorter one shows bursts but multiplies agent load and stored series, and polled octet counters still cannot resolve sub-second congestion.

## Why one reading tells you nothing The **Interfaces Group MIB**, IF-MIB (RFC 2863), describes every interface of a managed device as a row in `ifTable`, extended by a parallel row in `ifXTable`. Its traffic objects are **counters**: `ifInOctets` and `ifOutOctets` in `ifTable` (type `Counter32`) and `ifHCInOctets` and `ifHCOutOctets` in `ifXTable` (type `Counter64`, the "high capacity" versions). Each counts every octet received or sent on the interface, "including framing characters", since the agent last started counting. SMIv2 (RFC 2578) says counters have **no defined initial value**, so a single reading "has (in general) no information content". A reading of 7,204,118,930,112 octets says nothing about whether the link is busy now. What carries information is the **difference** between two readings taken a known time apart. ## The formula For one direction of one interface, polled at times t1 and t2: 1. **Delta octets** = counter(t2) - counter(t1). 2. **Bits** = delta octets x 8. 3. **Rate** in bit/s = bits / (t2 - t1), in seconds. 4. **Speed** in bit/s = `ifHighSpeed` x 1,000,000. 5. **Utilisation** = rate / speed, usually shown as a percentage. Written in one line: `utilisation = delta-octets x 8 / (delta-t x ifHighSpeed x 10^6)`. Some practical rules around it: - Use the **64-bit** objects on any fast link; a 32-bit octet counter wraps in about 3.4 seconds at 10 Gb/s, far shorter than any normal poll interval. - Compute **inbound and outbound separately**. On a full-duplex link each direction can carry the full speed, so adding the two deltas against one speed produces figures up to 200%. - Take delta-t from the **actual** times the two responses were produced, not the nominal schedule; a poll that runs 20 s late distorts the rate by about 7% on a 300 s interval. Requesting `sysUpTime.0` (hundredths of a second since the agent's management system started) in the same request as the counters gives an agent-side clock for the interval. - Before trusting a delta, confirm that `sysUpTime` did not reset and that `ifCounterDiscontinuityTime` did not change between the polls; otherwise the counters restarted and the delta is meaningless. ## Worked example: a 10 Gb/s uplink polled 300 s apart | Quantity | Value | |---|---| | `ifHighSpeed` | 10000 (so 10,000,000,000 bit/s) | | `ifHCInOctets` at t1 | 4,800,000,000,000 | | `ifHCInOctets` at t2 = t1 + 300 s | 4,912,500,000,000 | | Delta octets | 112,500,000,000 | | Bits | 900,000,000,000 | | Rate | 900,000,000,000 / 300 = 3,000,000,000 bit/s | | Utilisation | 3,000,000,000 / 10,000,000,000 = **30%** inbound | ## Which speed object: `ifSpeed` or `ifHighSpeed` | Object | Table | Type and unit | Limit | |---|---|---|---| | `ifSpeed` | `ifTable` | `Gauge32`, bit/s | its object definition says it reports its maximum, 4,294,967,295, when the bandwidth is higher | | `ifHighSpeed` | `ifXTable` | `Gauge32`, units of 1,000,000 bit/s | a value n means somewhere from n-500,000 to n+499,999 bit/s | On a 10 Gb/s port `ifSpeed` is pinned at 4,294,967,295, and RFC 2863 says `ifHighSpeed` "must be used" instead. Dividing the 3 Gb/s above by `ifSpeed` would report about 70% instead of 30%, and any rate above 4.29 Gb/s would read as more than 100%. The RFC's own background section (3.1.7) describes the ceiling as 2^31-1, about 2.2 Gb/s, while the object definition gives 4,294,967,295; either way a 10 Gb/s port does not fit, which is why `ifHighSpeed` exists. Both objects are estimates of the interface's bandwidth, normally the nominal speed, not measured throughput. ## What the number does and does not tell you - It is an **average** over the interval. A link at 30% over five minutes can still be at line rate for milliseconds at a time; rising `ifOutDiscards` is the usual IF-MIB evidence that bursts are overflowing buffers. - It counts what the interface counts. What "including framing characters" covers depends on the media, so a saturated link need not read exactly 100%. - It is per **interface row**. Sub-layers, such as a logical interface stacked on a physical one, have their own rows and their own counters. How the figure is then stored, aggregated or alerted on is the metrics system's business; the IF-MIB part ends at a correct rate per direction.

  • What exactly goes wrong if a poller divides a 10 Gb/s link's rate by ifSpeed?
    `ifSpeed` is a Gauge32 in bit/s; when the real bandwidth exceeds its maximum it reports 4,294,967,295. A 3 Gb/s inbound rate then reads as about 70% instead of 30%, and anything above 4.29 Gb/s reads as more than 100%. RFC 2863 says `ifHighSpeed`, in units of 1,000,000 bit/s, must be used for such interfaces.
  • Why might the same uplink show 30% over five minutes while users report drops?
    Delta-over-interval gives the mean rate; bursts lasting milliseconds can fill the output buffer at line rate and vanish into the average. The IF-MIB evidence is `ifOutDiscards` rising: packets dropped though no error was detected, typically to free buffer space. Shorter intervals narrow the averaging window, but no practical poll interval resolves millisecond bursts, so discards are the direct evidence.
  • Why request sysUpTime.0 in the same SNMP request as the octet counters?
    It gives an agent-side timestamp, in hundredths of a second, taken with the counters, so delta-t reflects when the agent produced the values rather than when the poller meant to ask. A drop in `sysUpTime` also reveals an agent re-initialisation, after which the delta must be discarded.

saying these in an interview costs you the question

  • Octets per second divided by the link speed is already the utilisation
  • ifSpeed always holds the real link speed in bits per second
  • ifHighSpeed is in bits per second, the same unit as ifSpeed
  • Add inbound and outbound octets and divide by the link speed
  • A single reading of ifHCInOctets shows how busy the interface is
  • A 30% five-minute average proves the link never congests