
OpenWrt Traffic Monitor: Read Raw Kernel Data First
Skip the GUI-first reflex. For an OpenWrt traffic monitor you can actually trust, install nlbwmon for per-IP accounting you can query, then read /proc/net/dev and tc -s qdisc yourself before you believe any dashboard. The tools aggregate, and sometimes they drop counters without saying so. Only the raw kernel numbers tell you when that is happening. Everything below sits on top of those numbers, so start there.
Last updated: 2026-07-21
What counts as traffic monitoring on OpenWrt
Three different things get called "traffic monitoring," and picking the wrong layer wastes an evening. Interface counters tell you how many bytes crossed eth0 or wan. Per-IP accounting tells you which host on your LAN did it. Deep packet stats tell you which flow or protocol filled the pipe.
Most people want the middle layer and reach for the hardest one. If your question is "who is hogging the WAN," you need per-host accounting, not a packet sniffer. If your question is "is the link saturated right now," a live interface reader answers it in one command.
So decide the question first. That single choice picks the tool, and it saves you from installing a full stack to answer something cat /proc/net/dev already knows.
How do you monitor network traffic on OpenWrt?
Every tool here reads one of three kernel sources, so learn those before the tools. The first is procfs. Run cat /proc/net/dev and you get rx and tx byte and packet counts per interface, straight from the kernel. That is the ground truth every bandwidth monitor polls and turns into graphs.
The second is netfilter and its connection tracker. Run cat /proc/net/nf_conntrack to see live flows with source, destination, and byte counts. This is what per-IP accounting is built on. When a per-host number looks wrong, this file is where you check it.
The third is the traffic control layer. Run tc -s qdisc show dev wan and you get bytes, packets, drops, and backlog per queue. That drops count is the one people miss. If throughput is bad but the link is not full, the drops here usually tell you why. Learn these three and any dashboard failure becomes diagnosable instead of mysterious.
Monitoring traffic per IP with nlbwmon
Install nlbwmon and its LuCI page, and you get per-host bandwidth accounting that survives reboots. Run opkg update && opkg install nlbwmon luci-app-nlbwmon, then open the Bandwidth Monitor page in LuCI. It groups usage by client IP and MAC and keeps a rolling history, which is exactly what "who used all the data" needs.
It works because it reads netfilter's accounting, not by sniffing packets. That keeps CPU low on a small router. Set the accounting period and the database size in /etc/config/nlbwmon so it does not slowly eat your flash.
Verify its numbers against the source before you trust a client's total. Pick a busy host and run conntrack -L | grep <ip> to see its live flows and byte counts. If nlbwmon says a phone pulled gigabytes but conntrack shows almost nothing, your accounting period rolled over or the host changed MAC. Check the raw flows, then believe the dashboard.
Which bandwidth monitoring tools work best?
There is no single best OpenWrt bandwidth monitor. Each tool answers a different question, and the trade-off is per-host detail versus history versus setup cost. Here is how the common ones compare.
| Tool | Best for | Weak spot |
|---|---|---|
| nlbwmon | Per-IP bandwidth accounting, clean LuCI page | Short retention by default; tune the DB size |
| vnstat | Long-term monthly and daily trends | No per-host breakdown |
| luci-app-statistics (collectd) | Full dashboard, many metrics, RRD graphs | Most moving parts to install and debug |
| darkstat | Quick real-time per-host visibility | Weak historical retention |
| iftop / nload | Instant live diagnosis over SSH | Nothing is stored |
My default is nlbwmon for per-IP and vnstat for the long view. Run both. They cost little RAM and answer the two questions you will actually ask. Reach for collectd only when you want a real dashboard and accept the extra parts to maintain. You can read the tool details in the OpenWrt documentation if you want the config options for each.
Building a dashboard with collectd and Grafana

For graphs over time, install luci-app-statistics, which pulls in collectd. It samples interface, load, and memory data into RRD files and draws them in LuCI. Enable the interface and processes plugins, set the polling interval, and the graphs fill in within a few minutes.
Two things break this pipeline, and both are quiet. First, RRD files live in RAM on flash-constrained routers, so a reboot wipes recent history unless you point the storage at persistent storage. Second, if a plugin is enabled but its interface name is wrong, collectd logs nothing useful and the graph just stays flat.
When a graph goes empty, check logread | grep collectd first. That tells you whether the daemon is even sampling. For a proper long-term store, forward collectd to Grafana on another box rather than keeping RRDs on the router. The router should sample and ship, not archive.
Real-time stats over SSH
When you do not trust the dashboard, or there is no dashboard, SSH in and watch live. Run iftop -i wan to see per-connection bandwidth sorted by talker, updating every second. It is the fastest way to catch a single host saturating the uplink right now.
For a plain aggregate, nload wan shows in and out throughput with a small graph, no per-flow noise. Install either with opkg install iftop nload. Both read the same kernel counters a dashboard does, just without the lag and the storage.
My rule during an active problem: skip the graphs and watch tc -s qdisc show dev wan a few times in a row. Rising drops and backlog while throughput is below the link rate points straight at a queue or shaping problem, not a busy client. Live tools tell you what is happening; stored tools tell you what happened.
Analyzing historical bandwidth data
For monthly and daily totals, vnstat is the light choice. Install it with opkg install vnstat luci-app-vnstat, add your WAN interface, and it logs cumulative usage with almost no overhead. Run vnstat -m for a month view or vnstat -d for days. It answers "did we blow the data cap" without keeping per-packet detail.
Storage is the catch on a small router. Flash wears out on constant writes, and RRD or vnstat databases grow. Point vnstat's database at persistent storage you can afford to write to, or push the data off-box on a schedule.
If you need per-host history and not just per-interface totals, vnstat will not give it to you. Pair it with nlbwmon, which keeps the client breakdown, and let vnstat own the long timeline. Do not stretch one tool to cover both jobs.
The eBPF route for packet-level counters

I built an OpenWRT eBPF traffic monitor to get low-overhead packet counters on a home router. I compiled a custom image, flashed the device, and used bpftool to confirm loaded programs. This is the heavy path. Take it only when interface counters and per-IP accounting cannot answer your question, because it needs a custom build.
The method is reproducible. Prepare a Linux build host with build-essential and the listed packages, clone the OpenWrt source, and enable CONFIG_BPF and CONFIG_BPF_SYSCALL in make menuconfig before you build. Those two kernel options must be on or the router cannot load a single program. Then build with make -j$(nproc), flash the image from the web UI, and install bpftool via opkg to verify with bpftool prog list.
For live counters I run a small user-space loader from xdp-tools that attaches an XDP program and polls per-interface maps for rx_bytes and rx_packets. XDP runs in the kernel fast path at a fraction of the CPU overhead of traditional tools like iptables, which is the whole reason to bother. I keep programs minimal for performance and avoid changing the forwarding path.
Keep backups and a recovery image to avoid bricking during experiments. If you want the full build steps, the BPF toolchain build guide and the kernel config guide cover the parts I compressed here. For capturing actual packets instead of counters, see the eBPF packet capture walkthrough.
Why do OpenWrt traffic monitor numbers look wrong?
Usually the counter reset and nobody noticed. Interface counters in /proc/net/dev are unsigned and reset on a reboot or an interface bounce. A monitor that missed the reset shows a huge negative delta or a nonsense spike. Check uptime and logread for an interface flap before you blame the tool.
The second common cause is NAT double-counting. Traffic crossing your router hits both the LAN and WAN interfaces, so summing every interface counts the same bytes twice. Count the WAN alone for internet usage, not the total of all interfaces.
The third is a missing or renamed interface. If your accounting watches eth0 but traffic now rides wan or a VLAN, the numbers quietly stay low and look fine. Confirm the real path with ip -br link and tc -s qdisc, then point the tool at the interface that actually carries the traffic. When a dashboard and the raw kernel counters disagree, the kernel is right. Go read /proc/net/dev and find where the tool lost the plot.
FAQ
Does running a traffic monitor slow down my router?
Per-IP tools like nlbwmon and vnstat read counters the kernel already keeps, so the cost is negligible on any device with enough RAM. Live sniffers like iftop cost more while open but nothing when closed. The only real overhead comes from packet-capture and heavy collectd polling on a weak CPU, so keep the polling interval sane.
Can I see which website or app a client is using, not just how much?
Not from byte counters alone. nlbwmon and vnstat tell you volume per host, never the destination site. For domain-level detail you need DNS logging or per-flow inspection, and modern encryption limits how much even a packet capture reveals. Decide whether you need "how much" or "to where" before you install anything.
Why does per-IP data disappear after a reboot?
Because the accounting database often lives in RAM or on tmpfs by default. Set nlbwmon's database path and vnstat's storage to persistent storage in their config, and size the retention so it fits your flash. Otherwise every reboot starts the history from zero.
How do I monitor a specific VLAN or guest network separately?
Point the tool at that interface directly. Run ip -br link to find its name, then set nlbwmon or vnstat to watch that interface instead of the WAN. For live checks, iftop -i <vlan-iface> shows only that segment's traffic.
Is eBPF worth it for a home router?
Only if plain counters cannot answer your question. For "who used the data" or "is the link full," nlbwmon and tc do the job with no custom build. The eBPF route earns its keep when you need per-packet detail at low CPU cost and are willing to compile and flash a custom image to get it.
