skip to content

Interface Counters

Link utilisation comes from differencing IF-MIB octet counters over a poll interval, and 64-bit counters matter because 32-bit ones wrap in seconds at 10G. It is the most practical SNMP ask.

on this pageshow

questions

5

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
open as a page

Why does a 32-bit SNMP ifInOctets counter fail on a 10 Gb/s link, and what does RFC 2863 require instead?

level: seniorimportance: must knowfreq 35%

basics

~20 s

A 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.

open as a page

In SNMP's IF-MIB, what does ifAdminStatus up with ifOperStatus down say about an interface, and how is that different from both being down?

level: juniorimportance: should knowfreq 38%

basics

~20 s

ifAdminStatus is the desired state and ifOperStatus the actual one. Admin up with oper down means the interface should work but cannot, so RFC 2863 presumes a fault; both down means it was disabled on purpose, with no fault implied.

open as a page

In SNMP's IF-MIB, how do ifOutDiscards and ifOutErrors differ, and what does a rising discard count on a moderately loaded uplink suggest?

level: middleimportance: should knowfreq 22%

basics

~20 s

ifOutDiscards counts outbound packets dropped although no error was detected, for example to free buffer space; ifOutErrors counts packets that could not be sent because of errors. Rising discards at moderate average utilisation usually mean bursts overflowing the output buffer.

open as a page

An SNMP utilisation graph for a 10 Gb/s uplink drops to zero or spikes absurdly after a line card swap; how does IF-MIB let a poller detect counter discontinuities?

level: seniorimportance: should knowfreq 20%

basics

~20 s

IF-MIB counters can restart at agent re-initialisation and at times marked by ifCounterDiscontinuityTime. A poller must discard any delta where sysUpTime went backwards or ifCounterDiscontinuityTime changed between polls, instead of treating the drop as a wrap.

open as a page