← All guides

Bandwidth Usage Alerts on Linux: Thresholds Without Spam

Updated:

A useful bandwidth alert answers one question: is the link full for long enough to hurt users, or am I about to blow my monthly transfer quota? Everything else - a 3-second spike during a backup, a burst when a cache warms up - is noise.

This guide gives you two alerts that cover almost every server:

  1. Utilization alert - throughput above X% of link speed, sustained for N minutes.
  2. Quota alert - monthly transfer on track to exceed the provider's limit.

To inspect bandwidth by hand first, see how to check network bandwidth usage on Linux. To confirm a slowdown is really bandwidth, run the 5 bandwidth checks.

Step 1: Measure Throughput From Kernel Counters

The kernel keeps byte counters per interface in /sys/class/net/<iface>/statistics/. Read them twice and divide by the interval - no extra packages needed:

#!/usr/bin/env bash
# bw-usage.sh - average in/out Mbit/s over an interval, plus % of link speed
IFACE=${1:-eth0}
INTERVAL=${2:-60}

S=/sys/class/net/$IFACE/statistics
rx1=$(cat $S/rx_bytes); tx1=$(cat $S/tx_bytes)
sleep "$INTERVAL"
rx2=$(cat $S/rx_bytes); tx2=$(cat $S/tx_bytes)

rx_mbit=$(( (rx2 - rx1) * 8 / INTERVAL / 1000000 ))
tx_mbit=$(( (tx2 - tx1) * 8 / INTERVAL / 1000000 ))

speed=$(cat /sys/class/net/$IFACE/speed 2>/dev/null)   # Mbit/s, -1 or empty on many virtual NICs
speed=${LINK_MBIT:-$speed}                              # override: LINK_MBIT=200 ./bw-usage.sh
if [ -n "$speed" ] && [ "$speed" -gt 0 ]; then
  max=$(( rx_mbit > tx_mbit ? rx_mbit : tx_mbit ))
  util=$(( max * 100 / speed ))
  echo "rx=${rx_mbit}Mbit/s tx=${tx_mbit}Mbit/s util=${util}%"
  [ "$util" -lt "${THRESHOLD:-90}" ] || exit 2         # non-zero exit = threshold breached
else
  echo "rx=${rx_mbit}Mbit/s tx=${tx_mbit}Mbit/s util=unknown (set LINK_MBIT)"
fi
$ ./bw-usage.sh eth0 60
rx=41Mbit/s tx=612Mbit/s util=61%

Averaging over 60 seconds already removes most sub-second bursts. Use the name of your real uplink (ip -br link lists them - often eth0, ens3 or enp1s0).

Virtual machines: /sys/class/net/*/speed often reports -1 or a meaningless 10000. Use the bandwidth your provider sells instead (for example 1 Gbit/s port, or 200 Mbit/s on a small cloud plan) and pass it as LINK_MBIT=200.

Step 2: Pick Thresholds That Mean Something

Signal Warning Critical Sustained for
Utilization of link speed (either direction) 70% 90% 5-10 minutes
Absolute throughput on a capped VPS 70% of the cap 90% of the cap 5-10 minutes
Monthly transfer vs. quota 80% of quota 95% of quota - (check daily)
Throughput drop to near zero on a busy server - < 5% of the usual level 5 minutes

Why these numbers:

  • Links degrade before 100%. Queues build up and latency rises well before a link is "full"; 90% sustained is already user-visible for interactive traffic.
  • Sustained, not instant. Alert only when the condition holds for several consecutive checks. One sample over the threshold is a spike; five in a row is a problem.
  • The "drop to zero" alert is underrated. A web server that normally pushes 50 Mbit/s and suddenly pushes 0.2 is usually broken (DNS, firewall, crashed app) - bandwidth is just where it shows first.

Step 3: Alert on Monthly Transfer Quotas

Many VPS and dedicated plans include a monthly transfer allowance and charge (or throttle) above it. vnstat keeps per-month totals across reboots:

sudo apt install vnstat        # Debian/Ubuntu
sudo dnf install vnstat        # RHEL/Rocky/Alma (EPEL)
sudo systemctl enable --now vnstat

# Current month totals
vnstat -m -i eth0

# Machine-readable: field 11 = total for the current month (vnStat 2.x --oneline b)
vnstat -i eth0 --oneline b | cut -d';' -f11

A quota check that prints the percentage used:

#!/usr/bin/env bash
# bw-quota.sh - % of the monthly transfer quota used so far
IFACE=${1:-eth0}
QUOTA_GB=${2:-20000}   # e.g. 20 TB allowance
used_bytes=$(vnstat -i "$IFACE" --oneline b | cut -d';' -f11)
echo "used=$(( used_bytes / 1000000000 ))GB quota=${QUOTA_GB}GB pct=$(( used_bytes / 10000000 / QUOTA_GB ))%"

Check whether your provider counts inbound, outbound or both, and adjust the field accordingly (vnstat --oneline fields 9 and 10 are month rx and tx).

Step 4: Find Who Is Using the Bandwidth When It Fires

An alert is only useful if the next step is obvious:

# Per remote host / IP, live
sudo iftop -i eth0 -P -n

# Per process
sudo nethogs eth0

# Per connection with byte counters
ss -tinp | grep -E "bytes_(sent|acked|received)"

Common culprits: backup jobs scheduled during business hours, log shippers after an outage, a crawler hammering one endpoint, or a large file being hot-linked.

Step 5: Run It Automatically With Zuzia

With the Zuzia agent installed on the server:

  1. Add a scheduled task that runs bw-usage.sh eth0 60 every 5 minutes (and bw-quota.sh once a day).
  2. The script exits with code 2 when utilization reaches THRESHOLD (90% by default), so breaches stand out in the task history; set THRESHOLD=70 for an early warning.
  3. Keep host-level CPU, RAM, disk and load metrics on the same server in the same panel, so you can tell whether a bandwidth peak is also a load peak.

Every run's output is stored, so the history doubles as a simple bandwidth log: you can see whether the 90% alert was a one-off or the third evening in a row - which is the point where you schedule the backup elsewhere or upgrade the port.

Common Mistakes

  • Alerting on a single sample. Use a 60-second average and require several consecutive breaches.
  • Measuring the wrong interface. On Docker or Kubernetes hosts, docker0, cni0 and veth* carry the same traffic as the uplink; alert on the physical/uplink interface only.
  • Using bytes instead of bits. Link speeds are in bits per second; /sys counters are in bytes. Multiply by 8.
  • Ignoring direction. A web server saturates tx; a backup target saturates rx. Check both and alert on the larger.
  • Counter resets. Counters reset on reboot or driver reload; if the second reading is lower than the first, skip that sample.

FAQ

What is a good bandwidth utilization alert threshold?

Warn at 70% of link speed and go critical at 90%, both sustained for 5-10 minutes. For capped cloud instances, use the provider's bandwidth cap instead of the NIC speed.

How do I get an alert when bandwidth usage is high on Linux?

Measure throughput from /sys/class/net/<iface>/statistics over 60 seconds, compare it with the link speed, and run that check on a schedule with an alerting tool - cron plus email, or a monitoring service such as Zuzia that stores the history and notifies you.

How do I check bandwidth usage per IP?

Use iftop -i eth0 -P -n for live per-host traffic, or nethogs for per-process usage. For historical per-IP accounting you need flow data (for example nfdump/sFlow) or firewall counters.

How do I track monthly bandwidth usage for a VPS quota?

Install vnstat, enable its service, and read the current month total with vnstat -m or vnstat --oneline b. Alert at 80% of the provider's quota so you have time to react before overage charges apply.

We use cookies to ensure the proper functioning of our website.