SNMP CPU Monitoring
When a server starts dragging, CPU is the first thing anyone checks. And SNMP CPU monitoring is the least painful way to watch it — no logging into the box, no agent to install, no script to babysit. This guide covers what the processor-load value actually means, the exact OID that returns it, how to read that OID by hand, where to put your alert thresholds, and why polling it from outside the machine is the part that saves you at 3 a.m. Everything here leans on the standard SNMP daemon your server most likely already runs.
What is CPU and why monitor it
Every request your server answers, every query it runs, every cron job that wakes up in the background — all of it runs on the CPU. CPU utilization is simply the share of that processing capacity actually doing work instead of sitting idle, reported as a percentage from 0 to 100. The wrinkle people forget: on a multi-core machine each logical processor keeps its own score. An eight-core box gives you eight numbers, not one.
So why monitor CPU usage in the first place? Because a high reading is both a warning and a wound. It warns you about a runaway process, an undersized instance, a traffic spike, or a query that lost its index. It turns into a wound when the run queue fills faster than the cores can drain it — that's when latency creeps up, requests time out, and health checks start flapping.
Here's the bit that trips people up. A CPU pinned at 100% for ten seconds during a backup or a compile is not a problem; that's the hardware earning its keep. What deserves an alert is load that climbs and stays there. Sustained saturation is the state where a server quietly stops keeping up with demand, and it rarely announces itself politely.
SNMP CPU monitoring is appealing precisely because it is so cheap to stand up. You install nothing extra on the host — the SNMP daemon already publishes the processor-load value through the Host Resources MIB. From there you poll it on whatever cadence suits you, keep the history, draw the graph, and set a line you would rather not see crossed.

The OID: 1.3.6.1.2.1.25.3.3.1.2
The number you are after — the CPU load OID — is 1.3.6.1.2.1.25.3.3.1.2, known as hrProcessorLoad in the Host Resources MIB (RFC 2790). It is not a single scalar. It is a table column: the agent hands back one row per logical processor, each keyed by an hrDeviceIndex, and every row is an INTEGER from 0 to 100 — that processor's average load over the last minute.
| Property | Value |
|---|---|
| OID | 1.3.6.1.2.1.25.3.3.1.2 |
| Object name | hrProcessorLoad |
| MIB / standard | Host Resources MIB (RFC 2790) |
| Type | INTEGER (0–100, percent) |
| Averaging window | Last 1 minute |
| Structure | Table — one entry per logical CPU |
That one-minute average is quietly useful. Instantaneous CPU readings jump around so much they are almost noise; a value already smoothed over sixty seconds drops onto a chart and behaves. Want a single figure for the whole machine instead of one per core? Poll every row and take the mean. That is the standard move for turning per-core hrProcessorLoad into a headline CPU usage percentage.
One caution about the index. The suffixes you will see — .196608, .196609, and friends — are not core numbers in any human sense. They are the device indices the agent assigned; stable for a given boot, otherwise opaque. Don't read meaning into them. Walk the column, treat each row as one processor, move on.
The neighbouring branches of the same MIB tree carry the rest of a server's vitals: memory, storage, uptime, system load. That is exactly why the sensor & OID catalog keeps them shelved together. CPU is one reading in a family, and it is seldom the only one you end up wanting.
How to query it
Any Net-SNMP client reads this in a second. The examples assume an agent running SNMPv2c with a read-only community string — if you have not set that up, the snmpd.conf guide walks through it.
- Walk every processor on the host:
Sample output — one line per core:snmpwalk -v2c -c public 10.0.0.5 1.3.6.1.2.1.25.3.3.1.2HOST-RESOURCES-MIB::hrProcessorLoad.196608 = INTEGER: 3 HOST-RESOURCES-MIB::hrProcessorLoad.196609 = INTEGER: 7 - Read a single core when you already know its index:
snmpget -v2c -c public 10.0.0.5 1.3.6.1.2.1.25.3.3.1.2.196608 - Force numeric output if the Host Resources MIB is not installed locally:
snmpwalk -v2c -c public -On 10.0.0.5 1.3.6.1.2.1.25.3.3.1.2
Two things worth knowing when you do this for real. snmptable will render the whole processor table as a grid if you would rather see it laid out. And to get the machine-wide CPU usage number people actually chart, you average across those rows — most polling tools fold that step in for you.
When it fails, the way it fails usually tells you why. An empty walk almost always means the OID is not published: it has been left out of the agent's view, so add it to your OID allowlist. A request that hangs and times out is a different animal — a mistyped community string, the wrong port, or a firewall in the path, not the OID itself.
Normal vs alarming values & thresholds
There is no single number that means "bad" — it depends on what the server does — but a few bands hold up across most machines:
- 0–60% sustained — healthy headroom, the normal operating range for a well-sized box.
- 60–80% sustained — worth watching. Fine for short peaks; a warning-level trigger fits here once it lasts a few minutes.
- 80–95% sustained — at capacity. Response times usually start to degrade; treat it as a high-priority alert.
- 95–100% sustained — saturated. The server cannot absorb new load. Page someone.
- Brief spikes to 100% — expected during backups, deploys, and batch jobs. Alert on duration, never on a lone sample.
Beyond the bands, two habits make your SNMP CPU monitoring thresholds trustworthy rather than annoying. First, alert on duration, not on a single reading — require the value to hold above the line for, say, five minutes straight. That one rule kills the false pages that every nightly backup would otherwise set off. Second, baseline each server against its own normal. A database node that sits at 45% all day is telling a different story from a web node idling at 5%, and a flat one-size threshold flattens that difference into noise. Learn what quiet looks like for each host, then alert on the departure.
Alerting on this metric externally
Polling hrProcessorLoad on demand tells you the CPU is busy right now. What prevents an incident is being told the moment it has been busy too long — and that is exactly where on-host tooling has a blind spot. An alerting agent that lives on the struggling server depends on that same server to send its message. Pin the CPU hard enough to starve the scheduler and the local notifier may never get a turn to speak.
Polling from outside the server sidesteps the whole problem. That is the idea behind double durability: an independent watcher keeps checking even when the host has gone silent, so a saturated — or fully crashed — machine still trips an alert. SNMP is a pull protocol, so the external side just polls 1.3.6.1.2.1.25.3.3.1.2 on its own schedule and tests the threshold on its own hardware. The sick server does not have to cooperate.
You can build that yourself, or hand it off. ostr.io Monitoring polls the CPU load OID from outside your network and fires real-time email and SMS alerts the second the reading crosses your limit — so a pegged CPU reaches you even when the box is far too busy to reach you first.
