---
type: Article
title: "SNMP CPU Monitoring"
description: "Watch processor load over SNMP with no agent to install: what the value means on multi-core boxes, the exact OID, and where to set alert thresholds."
resource: "https://snmp-monitoring.com/sensors/server-resources/cpu-utilization/"
tags: [sensors, snmp]
timestamp: 2026-07-13T00:00:00Z
---

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

![Diagram: an external SNMP poller reading hrProcessorLoad from a server's SNMP agent over UDP](https://snmp-monitoring.com/img/sensors/cpu-snmp-poll.webp)

## 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](/sensors/index.md) 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](/setup/snmpd-conf.md) walks through it.

1. **Walk every processor** on the host:
   ```bash
   snmpwalk -v2c -c public 10.0.0.5 1.3.6.1.2.1.25.3.3.1.2
   ```
   Sample output — one line per core:
   ```
   HOST-RESOURCES-MIB::hrProcessorLoad.196608 = INTEGER: 3
   HOST-RESOURCES-MIB::hrProcessorLoad.196609 = INTEGER: 7
   ```
2. **Read a single core** when you already know its index:
   ```bash
   snmpget -v2c -c public 10.0.0.5 1.3.6.1.2.1.25.3.3.1.2.196608
   ```
3. **Force numeric output** if the Host Resources MIB is not installed locally:
   ```bash
   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](/setup/oid-allowlist.md). 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](/monitoring/double-durability.md): 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](https://ostr.io/service/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.

![Chart: hrProcessorLoad percentage over 24 hours with a warning threshold line at 80 percent](https://snmp-monitoring.com/img/sensors/cpu-load-chart.webp)


## FAQ

**Is `hrProcessorLoad` the same as the Linux "load average"?**
No, and mixing them up causes a lot of confusion. `hrProcessorLoad` is a percentage, 0 to 100, of processing time used per core over the last minute. Load average is a different metric entirely — the number of processes waiting to run — and SNMP exposes it separately at `1.3.6.1.4.1.2021.10.1.3`. If that is what you are after, see [SNMP system load](/sensors/server-resources/system-load.md).

**How do I get one CPU figure for a multi-core server?**
Walk `1.3.6.1.2.1.25.3.3.1.2` and average the values across every row returned. Each row is one logical processor, so the mean is your machine-wide CPU usage percentage.

**Why does my walk return no processor rows?**
Nine times out of ten the OID simply is not in the agent's allowlisted view. Add it in `snmpd.conf` — the [OID allowlist guide](/setup/oid-allowlist.md) shows the exact `view` line.

**Which SNMP version should I use to monitor CPU usage?**
SNMPv2c is enough for read-only polling on a trusted network, and it is what most setups run. Reach for SNMPv3 when you need authentication and encryption on the wire.

## Conclusion

SNMP CPU monitoring really does come down to one table column — `hrProcessorLoad` at `1.3.6.1.2.1.25.3.3.1.2` — read per core, smoothed over a minute, and judged against a *sustained* threshold instead of a momentary blip. Publish it in your [snmpd.conf](/setup/snmpd-conf.md), make sure it survives your [OID allowlist](/setup/oid-allowlist.md), and poll it on a steady cadence. The number on its own is trivia. Reading it from outside is what turns it into protection, because an independent checker still catches the server too overloaded to raise its own hand.
