monitoring

How to Monitor Interface Traffic via SNMP (In/Out Octets)

Read ifInOctets/ifHCInOctets counters, diff two polls, and convert octet deltas to bits per second.

By the SNMP Monitoring team · Reviewed July 2026

Interface traffic is the single most-graphed thing in all of network monitoring, and almost nobody reads it correctly the first time. The trap: the OID you poll is not "traffic." It's a running total of every byte the interface has ever moved. Read it once and you get a big meaningless number. Read it twice, subtract, divide by the seconds in between — that's traffic. Everything on this page is really just that one idea, applied carefully enough that your Mbps graph isn't lying to you.

This is the how-to. For the full column-by-column IF-MIB object list and types, jump to the reference twin, interface OIDs. Parent: network monitoring.

Which OIDs hold traffic counters

Two families, and picking the wrong one is the most common mistake here:

  • 32-bit (ifTable)ifInOctets at 1.3.6.1.2.1.2.2.1.10, ifOutOctets at 1.3.6.1.2.1.2.2.1.16. Bytes in and out. Works on SNMPv1 and everything since.
  • 64-bit (ifXTable)ifHCInOctets at 1.3.6.1.2.1.31.1.1.1.6, ifHCOutOctets at 1.3.6.1.2.1.31.1.1.1.10. Same bytes, wider counter. Needs SNMPv2c or later.

Both are octet counters — cumulative, monotonic, they only climb until the agent restarts. There is no "current rate" object anywhere in the IF-MIB. The device doesn't compute Mbps for you; you compute it from the deltas. If your NMS shows a bandwidth graph, it's doing exactly this arithmetic under the hood.

Rule I follow without thinking: anything 1 Gbit or faster gets the ifHC counters. Slow links and museum-piece agents that don't expose ifXTable fall back to the 32-bit pair. When in doubt, walk ifHCInOctets first — if you get rows, use them.

Why counters wrap (and 64-bit fixes it)

A 32-bit counter maxes out at 4,294,967,295. On a gigabit link running near capacity, that many bytes go by in about 34 seconds. So the counter rolls over — wraps back to zero — several times an hour. If a wrap happens between two of your polls, your subtraction produces a negative number or a nonsense spike, and you get a phantom 40 Gbit burst on a 1 Gbit port.

The 64-bit counters end the problem. At 2^64 you'd need centuries to wrap a gigabit link, so in practice they never do.

Property 32-bit ifInOctets 64-bit ifHCInOctets
OID …2.2.1.10 …31.1.1.1.6
Max value ~4.29 billion ~1.8 × 10^19
Wrap time at 1 Gbit ~34 seconds Effectively never
Minimum version SNMPv1 SNMPv2c

If you're stuck on 32-bit counters for some reason, poll fast enough that a wrap can't hide between samples — but honestly, just move to v2c and the ifHC objects.

Calculating bits per second

The whole conversion, step by step:

  1. Read the octet counter at time T1. Note the value and the timestamp.
  2. Wait your polling interval, read the same OID again at T2.
  3. Subtract: Δoctets = value(T2) − value(T1).
  4. Multiply by 8 to turn bytes into bits.
  5. Divide by Δseconds (T2 − T1) to get bits per second.

As a formula: throughput (bps) = (Δoctets × 8) ÷ Δseconds.

Worked example. ifHCInOctets reads 48,000,000,000 at T1 and 48,093,750,000 ten seconds later:

  • Δoctets = 93,750,000
  • × 8 = 750,000,000 bits
  • ÷ 10 s = 75,000,000 bps = 75 Mbps inbound

Do inbound and outbound separately — they're different counters and rarely symmetric. To turn that 75 Mbps into a percentage of link capacity you need the interface speed too; that math lives on bandwidth monitoring so it isn't duplicated here.

Reading it with snmpbulkwalk

Don't hand-Get a big interface table. Use snmpbulkwalk, which pulls many rows per request:

snmpbulkwalk -v2c -c <RO_string> <host> 1.3.6.1.2.1.31.1.1.1.6
IF-MIB::ifHCInOctets.1 = Counter64: 48213847721
IF-MIB::ifHCInOctets.2 = Counter64: 1002934771155
IF-MIB::ifHCInOctets.3 = Counter64: 0
IF-MIB::ifHCInOctets.4 = Counter64: 77519034402

The trailing .1, .2 … are the ifIndex values, and they're the same index across every IF-MIB column. So ifName.2 names the port whose ifHCInOctets.2 you just read — walk 1.3.6.1.2.1.31.1.1.1.1 to get the human names and line them up:

snmpbulkwalk -v2c -c <RO_string> <host> 1.3.6.1.2.1.31.1.1.1.1

An all-zero row is almost always an unused or shut port, not a broken agent. <RO_string> stays a placeholder on purpose — never paste a live community into a page. Flag reference: snmpwalk.

snmpbulkwalk output of ifHCInOctets across interfaces

Pitfalls

A few things that quietly corrupt a traffic graph:

  • Counter reset on reboot. When the agent restarts, every counter drops to zero. Your next delta goes negative. Decent pollers detect the reset and skip that one sample; a naive script draws a cliff.
  • ifIndex reordering. Indexes are not guaranteed stable across reboots or when line cards are added — index 5 might be a different port tomorrow. Re-map ifIndex to ifName/ifDescr periodically instead of hard-coding "index 5 = WAN."
  • Polling interval drift. If you assume 60 s but the poll actually landed at 74 s, your rate is off by 20%. Use the actual Δseconds between reads, not the nominal interval.
  • Mixing 32- and 64-bit. Pick one counter per interface and stick with it. Diffing a 32-bit value against a 64-bit one is garbage.

Reference

This page covers the procedure. For the object types, status enumerations and the complete interface column list, use the reference twin: interface OIDs. Related how-tos: bandwidth utilization and port speed. Term definitions live at glossary; the full index at all sensors.

Frequently asked questions

What OID is interface traffic in SNMP?

Inbound bytes are ifInOctets (1.3.6.1.2.1.2.2.1.10) or, for fast links, ifHCInOctets (1.3.6.1.2.1.31.1.1.1.6); outbound are ifOutOctets / ifHCOutOctets. They're cumulative counters, so you diff two reads to get a rate — there's no ready-made "Mbps" object.

How do I convert octets to Mbps?

Take the difference between two octet reads, multiply by 8 (bytes to bits), divide by the seconds between reads, then divide by 1,000,000. So (Δoctets × 8 ÷ Δseconds) ÷ 1e6 = Mbps.

Why do my interface counters reset to zero?

The agent restarted — a device reboot or an SNMP daemon restart zeroes every counter. The delta right after a reset is meaningless and should be discarded; good pollers detect the drop and skip it rather than plotting a negative spike.

Should I use 32-bit or 64-bit interface counters?

Use 64-bit ifHC counters on any link 1 Gbit or faster, because 32-bit counters can wrap in under a minute on fast links and wreck your rate math. Only fall back to 32-bit for slow links or agents that don't expose the high-capacity table.

Key takeaways

  • Traffic OIDs are cumulative counters — diff two reads, never graph the raw value.
  • Throughput (bps) = (Δoctets × 8) ÷ Δseconds; do in and out separately.
  • Prefer 64-bit ifHC counters on 1 Gbit+ links to dodge the ~34-second wrap.
  • Use snmpbulkwalk for the table and map ifIndex to ifName before trusting a row.
  • Watch for reboots (counter reset) and index reordering — both poison deltas.
  • Types and the full column list: interface OIDs; a dead-site-proof external check via external monitoring backstops the primary poller.

Monitor it from outside the network

SNMP only tells you a box is healthy while something is still asking. ostr.io polls your endpoints externally and fires email + SMS alerts the moment a reading crosses your line — or the agent goes silent.