monitoring

How to Monitor RAM / Memory Usage via SNMP

Find the hrStorage RAM row, compute percent used with allocation units, set thresholds.

Monitor with ostr.io

By the SNMP Monitoring team · Reviewed July 2026

Memory pressure is a quiet outage factory: the box still pings, CPU looks fine, and then the OOM killer starts choosing victims. This how-to gets you from “agent answers” to a usable RAM % used signal over SNMP—without turning into the full OID encyclopedia.

OID twin (lookup tables): memory sensors. Parent: server monitoring.

How SNMP reports memory

Two common families on Linux-ish agents:

  • HOST-RESOURCES hrStorageTable — rows for RAM, disks, maybe swap; columns for size/used/units/descr
  • UCD memory under 1.3.6.1.4.1.2021.4 — e.g. memTotalReal .5, memAvailReal .6

Bullets for picking:

  • Portable host story → start with hrStorage RAM row
  • Need avail/total style UCD objects → poll 2021.4 when present
  • Always multiply by allocation units for hrStorage
  • Don't mix units across formulas

Full leaf dump: sensors/memory.

Finding the RAM row in hrStorageTable

Base: 1.3.6.1.2.1.25.2.3.1

  • descr .3
  • units .4
  • size .5
  • used .6

RAM rows use hrStorageType hrStorageRam (and descr often like “Physical memory”). Walk descr first, pick the index, then pull size/used/units for that index.

snmpwalk -v2c -c <RO_string> <host> 1.3.6.1.2.1.25.2.3.1.3
HOST-RESOURCES-MIB::hrStorageDescr.1 = STRING: Physical memory
HOST-RESOURCES-MIB::hrStorageDescr.3 = STRING: Virtual memory
HOST-RESOURCES-MIB::hrStorageDescr.10 = STRING: /

Index 1 looks like RAM here—confirm type on your agent, don't assume index stability forever.

Computing % used

Numbered calc for hrStorage:

  1. Read hrStorageSize, hrStorageUsed, hrStorageAllocationUnits for the RAM index.
  2. Bytes total = size × units.
  3. Bytes used = used × units.
  4. % used = (used ÷ size) × 100.
  5. Optionally track bytes free = (size − used) × units.

Worked example (units = 1024):

  • size = 16333648 → ~16 GB class footprint depending on units
  • used = 8921040
  • % used ≈ 8921040 / 16333648 × 100 ≈ 54.6%

If size is zero or missing, don't divide—fix the row.

Reading it with snmpwalk

snmpwalk -v2c -c <RO_string> <host> 1.3.6.1.2.1.25.2.3.1
HOST-RESOURCES-MIB::hrStorageDescr.1 = STRING: Physical memory
HOST-RESOURCES-MIB::hrStorageAllocationUnits.1 = INTEGER: 1024 Bytes
HOST-RESOURCES-MIB::hrStorageSize.1 = INTEGER: 16333648
HOST-RESOURCES-MIB::hrStorageUsed.1 = INTEGER: 8921040

UCD alternative:

snmpwalk -v2c -c <RO_string> <host> 1.3.6.1.4.1.2021.4
UCD-SNMP-MIB::memTotalReal.0 = INTEGER: 16333648 kB
UCD-SNMP-MIB::memAvailReal.0 = INTEGER: 6200120 kB

(Exact labels depend on MIB load; numbers are what matter.) Tooling: snmpwalk.

snmpwalk output of the RAM row in hrStorageTable

Caveats: cache/buffers vs real free

Linux free shows buffers/cache that can be reclaimed. SNMP hrStorage “used” for RAM often looks higher than the “available” story free prints. That's not always a bug—it's a different definition of used.

Practical stance:

  • Alert on sustained high % that correlates with reclaim/OOM pain, not a single sample after a page cache fill
  • Watch swap too (swap monitoring)—swap-in is the real “memory hurt” signal
  • Don't page every time cache grows

If finance wants “matches free -h,” use UCD fields carefully and document the formula in the runbook.

Reference OIDs & thresholds

Leaves and types: memory OIDs. Alert design: alerts.

Starting policy many teams use:

  • Warn ~85–90% used sustained
  • Crit ~95%+ sustained or swap climbing hard
  • Multi-sample windows—memory spikes during deploys

Tune per workload; JVMs and databases lie differently.

External monitoring

When the host is drowning, you still want something off-box asking for RAM via the storage table. ostr.io can read RAM device name/capacity/usage over external SNMPv2c as part of its metric set—allowlist the storage OIDs, don't expose the world. See external, setup ostr.io.

One contextual product link on this page; the rest is math and walks.

Ops checklist

  1. Identify RAM index via descr/type
  2. Poll size, used, units
  3. Compute % with units
  4. Graph + multi-sample alert
  5. Correlate with swap and load
  6. Re-check after kernel/agent upgrades (indexes shift)

Failure modes

  • Alerting on wrong storage row (a disk labeled oddly)
  • Forgetting × units → “% used” off by 1024
  • Treating cache-heavy used% as emergency
  • No swap metric → surprise thrash

Glossary: glossary.

Worked night-shift scenario

Pager: RAM 96% for fifteen minutes on db-03.

  1. Confirm the alert is the RAM row, not a mislabeled volume.
  2. Check swap used % and rate of change.
  3. Check load and CPU—thrash vs pure compute.
  4. Look for a deploy/backup window in the calendar.
  5. If swap is climbing and free is critically low, shed load or reboot with intent—not as superstition.

SNMP got you the signal. Runbooks do the rest. Without swap + duration, you'd have paged on cache fill after a warm-up every night.

What not to put on this page

Full UCD leaf catalogs, every vendor enterprise memory OID, and thirty screenshots of MIB browsers. That's sensors/memory and vendor MIBs. Here: find row → compute % → alert → optionally externalize.

If hrStorageRam is missing, say so in the device note and fall back to UCD or vendor objects after a lab walk—don't invent leaves.

Threshold starting points (not gospel)

Workload Warn used % Crit used % Also watch
General VM ~85 ~95 swap
JVM host ~80 ~90 GC / swap
DB buffer-heavy tune high tune with DBA swap + disk

Numbers are starting guns. If warn fires daily and nobody acts, raise the bar or fix capacity—alert fatigue is a monitoring bug. Write the final numbers into the service runbook so 3 a.m. you is not guessing under heavy pressure at night.

Cross-check with CPU and load when memory pressure presents as “everything is slow.”

UCD path recap when hrStorage fights you: base 1.3.6.1.4.1.2021.4, memTotalReal .5, memAvailReal .6. Still document units (often kB in descriptions) before graphing. And remember ostr.io-style external checks that read the storage table for RAM capacity/usage need those OIDs in the allowlist—name them explicitly in the ticket when you open the firewall.

Frequently asked questions

What OID is memory usage in SNMP?

Use hrStorage used/size under 1.3.6.1.2.1.25.2.3.1 for the RAM row, or UCD 1.3.6.1.4.1.2021.4.6 / .5 style total/avail when present. Twin page lists details: sensors/memory.

How do I calculate RAM % used?

(hrStorageUsed ÷ hrStorageSize) × 100 for that row. Convert to bytes with × hrStorageAllocationUnits when you need GB.

Does SNMP show free memory?

Derive free as (size − used) × units, or use UCD avail objects when exposed.

Why does SNMP memory differ from free?

Different accounting of cache/buffers and which pools count as “used.” Compare trends, not single-sample equality.

Key takeaways

  • RAM via hrStorageTable (+ optional UCD 2021.4).
  • % used = used/size; bytes need allocation units.
  • Mind cache vs pressure; watch swap.
  • OID reference: sensors/memory.
  • Optional off-box: ostr.io.

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.