>
Open Source

Find the Linux process hogging your bandwidth in under a minute

Your Linux server’s network is maxed out and you have no idea what is eating it. The standard reflex is to look at top or htop, and when those do not help (because they only show CPU and memory, not network usage per process), you restart services at random and hope the spike goes away. There are four small tools that solve this in under two minutes: nethogs, iftop, ss, and the /proc filesystem. They are pre-installed or one apt/dnf command away on Ubuntu, Debian, RHEL, and Rocky.

The setup is the same on every modern Linux server. On Debian or Ubuntu: sudo apt install nethogs iftop net-tools -y. On RHEL or Rocky: sudo dnf install nethogs iftop net-tools -y. All three are lightweight, take seconds to install, and work without configuration. The fourth tool, ss, ships with the iproute2 package that is already installed on every modern Linux distribution.

nethogs: bandwidth usage per process

When the question is “what is using my bandwidth right now,” nethogs is the fastest answer. Most network tools show total traffic, but nethogs breaks traffic down by process ID (PID, the number Linux assigns to every running program), so you see which specific program is responsible. Run it pointed at your active interface:

sudo nethogs eth0

The output looks like this:

NetHogs version 0.8.7
PID   USER    PROGRAM              DEV     SENT      RECEIVED
14823 root    /usr/bin/rsync       eth0    12.847    0.143 KB/sec
9301  www-data /usr/sbin/apache2   eth0    0.734     4.211 KB/sec
1204  root    sshd: ravi@pts/0     eth0    0.012     0.008 KB/sec
0     root    unknown TCP          eth0    0.000     0.000 KB/sec
TOTAL                                 13.593    4.362 KB/sec

You can immediately see rsync pushing the most data. If you did not start a backup or file sync, that is your bandwidth spike. The PID on the left (14823 in this case) is what you use if you want to inspect the process further or kill it. Press q to exit. Press m inside nethogs to switch between KB/sec, KB, and MB display modes. On a busy server, MB makes the numbers readable at a glance.

Not sure what your interface is called? Run ip link show first. On most cloud servers and VMs it is eth0, but on newer systems with predictable network interface names it can be something like ens5 or enp0s3.

iftop: who your server is talking to

nethogs tells you which program is using the bandwidth. iftop takes it one step further and shows who that program is actually talking to on the network, broken down by connection and remote IP.

sudo iftop -i eth0

The output is a live view like this:

your-server.example.com => 203.0.113.45.storage.net    4.92Mb  4.98Mb  4.76Mb
                        <=                                 320Kb   288Kb   310Kb
your-server.example.com => 198.51.100.22.cdn.net        1.23Mb  1.18Mb  1.20Mb
                        <=                                  88Kb    72Kb    90Kb
─────────────────────────────────────────────────────────────────────────────────
TX: cum: 1.47GB  peak: 6.54Mb  rates: 6.15Mb  6.16Mb  5.96Mb
RX: 312MB       peak: 1.21Mb  rates: 408Kb   400Kb   400Kb
TOTAL: 1.78GB           rates: 6.52Mb  6.55Mb  6.36Mb

The key thing to read here is the direction arrows. The => line shows traffic going out from your server to a remote system; the <= line shows traffic coming back in. In this example, the server is sending 6.15 Mb/s out and receiving 408 Kb/s back, which is a classic asymmetric pattern for an upload (like a backup or a content sync). If you see 10 Mb/s in both directions to a single IP, that is more consistent with a download, an API sync, or a peer-to-peer connection.

Combine nethogs and iftop and the picture becomes clear. nethogs tells you which program, iftop tells you which destination. Together they answer “what is doing this, and to whom” in one screen each.

ss: which sockets are open

ss is the modern replacement for netstat and it is pre-installed on every Linux distribution with the iproute2 package. It shows open connections, listening ports, and connection states faster than netstat ever did.

ss -tunap

The flags break down as: -t for TCP, -u for UDP, -n for numeric addresses (no DNS lookup), -a for all sockets including listening, -p for the process name and PID. The output is line-by-line: each row is one connection, with local address, remote address, state, and process. If you are trying to confirm whether a daemon is listening on a port, this is the command. If you are trying to see which process opened an outbound connection to a specific remote IP, this is also the command.

For a faster scan limited to listening ports:

ss -tlnp

That filters to TCP listening sockets and drops everything else. Useful when you are checking firewall exposure.

The /proc filesystem: when nothing else tells you

When nethogs shows 0 KB/s but the cloud bill disagrees, the process is hiding. The most common reason is a kernel module, a containerized workload, or a process running under a different network namespace. None of those show up cleanly in nethogs or iftop because they are not regular user processes in your shell’s view.

The fallback is /proc. Every running process has a directory at /proc/<PID>/, and the network accounting files live there.

ls /proc/*/net/tcp 2>/dev/null | head -3
cat /proc/net/tcp

/proc/net/tcp shows every TCP connection the kernel is tracking, with local and remote addresses, connection state, and the owning UID. The catch is that /proc shows the kernel’s view, not your userspace view, so a process running in another network namespace will show up here even when nethogs cannot see it. The other useful file is /proc/<PID>/net/dev, which shows per-interface byte counters for any process you can read. Read it twice, sleep one second, read it again, and the delta is the per-second throughput for that interface.

Trade-offs

nethogs requires root or CAP_NET_ADMIN (the Linux capability, a fine-grained permission, that lets a process read network usage for other processes’ sockets) to see traffic from other users’ processes. If you are debugging your own workload as a non-root user, you will see your own processes and nothing else. Running under sudo is the usual answer.

iftop can be noisy on busy servers with thousands of connections. The display saturates and you lose the signal in the scrollback. Limit it to specific subnets with -F 10.0.0.0/8 or filter to a specific port with -f port 443.

ss gives you the connections, not the byte counts. It answers “who is connected” rather than “who is using the bandwidth.” If you need the bytes, combine it with /proc/net/dev.

The /proc filesystem is the bottom of the stack, the place you go when the userland tools cannot see what is happening. It works in every namespace and every container, but it requires reading raw kernel counters and doing the math by hand. For one-off debugging on a single server, that is fine. For ongoing monitoring, you want a real tool on top.

Putting the four together

The four tools answer four different questions, and the order you reach for them matters. Start with nethogs to identify the process. Move to iftop to identify the destination. Use ss to confirm the connection state and process owner. Drop to /proc when nethogs and iftop show nothing but the cloud bill disagrees. This sequence works for 90 percent of the “where is my bandwidth going” tickets I have seen.

For ongoing monitoring rather than incident response, the same four tools are the foundation of larger systems. Prometheus node_exporter (a small daemon that exports Linux system metrics to a Prometheus server) reads from /proc/net/dev directly and exposes per-interface counters. The nicstat tool wraps iftop-style output for log files. nethogs itself runs in continuous mode with -d 5 for a 5-second refresh. None of these are replacements for the four core tools, but they are how you turn one-shot debugging into something that runs on a schedule.

The setup cost is one apt or dnf command per package. The runtime cost is the time it takes you to read the output. The migration from “I do not know what is using my bandwidth” to “I know exactly which PID is on which destination IP” is usually under two minutes.

What I would tell past me

  • Install all three before you need them. When the server is on fire, the slowest step is waiting for apt to finish. Pre-install nethogs, iftop, and net-tools on every server you ship, even if you never use them.
  • Start with nethogs, not iftop. nethogs answers the actual question (“which process”) in one screen. iftop is the next question (“which destination”), not the first one.
  • Check /proc when the userland tools lie. If your cloud provider’s bandwidth meter disagrees with nethogs, the process is in a network namespace nethogs cannot see. /proc/net/dev sees everything the kernel knows about.
  • Keep ss in your muscle memory. It is faster than netstat, it is everywhere, and it answers 80 percent of “is this port open” questions in one command.

Leave a comment