nethogs, iftop, ss, and the /proc filesystem.This happens pretty often. The server starts feeling slow, uploads get stuck at 100 percent, or you notice your cloud bill creeping up without any clear reason.
You check top or htop, but everything looks fine because those tools only show CPU and memory, not network usage. So you know something is eating bandwidth, but you cannot actually see what it is.
Linux already has a few simple tools that can help with this. Once you get used to them, you can quickly spot the process behind the traffic instead of just guessing and restarting services randomly.
It works on most common Linux setups like Ubuntu, RHEL, and similar modern distributions, so you can use the same approach almost everywhere.
Install the Tools You Need
These tools are not always installed by default, so you will need to add them first. You will see sudo in the commands below that simply means you are running the command with admin rights. If Linux ever throws a “Permission denied” error, it is usually because sudo was missing.
On Ubuntu or Debian:
sudo apt install nethogs iftop net-tools -y
On RHEL or Rocky Linux:
sudo dnf install nethogs iftop net-tools -y
All three tools are lightweight and usually take only a few seconds to run or understand once installed.
- nethogs: Shows bandwidth usage per process, so you can quickly identify which application is consuming network traffic
- iftop: Displays live network traffic between connections, giving you a real-time view of who is talking to whom
- netstat (from net-tools): A fallback tool that shows open connections and basic network activity for quick inspection
- ss: Already pre-installed on modern Linux systems as part of the
iproute2package and it is used to inspect sockets, showing detailed information about TCP, UDP, listening ports, connections, and their states, much faster and more efficiently thannetstat.
1. Find Network Bandwidth Usage Per Process Using nethogs
When you need a quick answer to “what’s actually using my bandwidth right now”, nethogs is usually the fastest way to get it. Instead of showing total network usage like most tools, it breaks traffic down by process ID (PID), which is just a number Linux assigns to every running program, so you can see exactly which program is responsible for the traffic.
To run it, point it at your active network interface. Replace <interface> with your actual interface name, and ignore the angle brackets since they are only placeholders. If you are not sure what your interface is called, you can check it using ip link show.
sudo nethogs <interface>
On most servers and VMs, the interface is usually eth0, so it often looks like this:
sudo nethogs eth0
When it runs, you will see output 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
This is the useful part. You can immediately see rsync pushing the most data. If you did not start a backup or file sync, that is likely your bandwidth spike. The PID on the left (like 14823) is what you would use later if you want to inspect the process further or stop it.
Press q to exit nethogs.
Tip: Press m inside nethogs to switch between KB/sec, KB, and MB display modes. On a busy server, MB makes the numbers easier to read at a glance.
2. Monitor Active Network Connections in Linux Using iftop
So nethogs tells you which program is using the bandwidth, but iftop takes it one step further and shows you who that program is actually talking to on the network. In other words, it breaks traffic down by connection and remote IP address.
When you combine both tools, it becomes much easier to understand what is happening, because nethogs gives you the process name, and iftop shows the destination of that traffic.
sudo iftop -i eth0
You will see a live view like this:
191Mb 382Mb 573Mb 764Mb 955Mb
└───────────────────────────────────────────────────────────────────────────────────────────────────────
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 1.21Mb 408Kb 360Kb 400Kb
TOTAL: 1.78GB 7.48Mb 6.55Mb 6.52Mb 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, while the <= line shows traffic coming back in.
In this example, you can see the server is sending a lot of data to 203.0.113.45, which strongly suggests something like a backup job or file sync running in the background. If you did not expect that traffic, that is your first thing to investigate.
Inside iftop, you can press p to toggle port display, which helps you figure out which service is responsible for a connection, especially when multiple services talk to the same host.
Note: iftop shows you connections and addresses, while nethogs shows you the program. Keep both open side by side, and you’ll see the full picture, what’s running, and where it’s sending data.
3. Check Open Network Connections by Process Using ss
Once nethogs points you to a suspicious PID, ss helps you dig into exactly what that process is doing at the socket level. It shows active network connections and, with the right flags, maps them back to the program name and PID.
sudo ss -tnp
Here is what the flags mean:
-tshows TCP connections, which covers the most common traffic.-nskips DNS lookups and shows raw IP addresses (faster and clearer).-pshows the process name and PID attached to each connection.
When you run it, you will get output like this:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
ESTAB 0 0 10.0.2.15:22 192.168.1.5:54322 users:(("sshd",pid=1204,fd=4))
ESTAB 0 52608 10.0.2.15:443 203.0.113.45:9000 users:(("rsync",pid=14823,fd=3))
ESTAB 0 0 10.0.2.15:80 198.51.100.22:62104 users:(("apache2",pid=9301,fd=12))
The important column here is Send-Q, which shows how much data is currently queued up waiting to be sent. In this example, the rsync connection has about 52 KB waiting, which means it is actively pushing data out to 203.0.113.45.
At this point, you have the full picture in one place: the process name, PID, local and remote addresses, and ports. That is usually enough to decide whether the traffic is expected (like a backup or deployment) or something you should stop and investigate immediately.
ss and reading network connections, the SSH Course on Pro TecMint covers socket inspection in the context of SSH tunnels and port forwarding4. Find Network Activity by PID in Linux Using /proc
Sometimes you do not have the luxury of installing tools like nethogs or iftop, especially in minimal environments like containers, rescue shells, or stripped-down VMs. In those cases, Linux still gives you a built-in way to trace what a process is doing using /proc.
/proc is a virtual filesystem that Linux keeps in memory. It exposes live details about every running process, including open file descriptors. Network connections also show up here as “socket” files under each process ID.
sudo ls -la /proc/<pid>/fd | grep socket
Replace <pid> with the process ID you already found earlier (for example, from nethogs).
For the same rsync example, it would look like this:
sudo ls -la /proc/14823/fd | grep socket
You will get output like:
lrwxrwxrwx 1 root root 64 Jun 15 11:22 3 -> socket:[1048576] lrwxrwxrwx 1 root root 64 Jun 15 11:22 4 -> socket:[1048602]
Each socket:[number] entry represents one active network connection that the process is holding open. The number inside the brackets is the kernel’s internal reference for that socket.
To go deeper, you can match that socket number with /proc/net/tcp (or /proc/net/tcp6 for IPv6). That file contains the connection table with local and remote IP addresses, ports, and states.
It is not as fast or readable as nethogs, but the advantage is simple: it is always available. Even on a minimal system with zero extra packages installed, /proc still lets you trace exactly what a process is connected to.
Quick Reference
| Tool | What It Shows | Best For |
|---|---|---|
| nethogs | Bandwidth per program (live) | Finding the program behind the traffic fast |
| iftop | Bandwidth per connection (live) | Seeing which remote hosts are involved |
| ss -tnp | Open connections with PID | Confirming a program’s active connections |
| /proc/<pid>/fd | Raw connection files | Minimal systems with nothing installed |
Conclusion
You now have four practical ways to figure out what is using your bandwidth on a Linux server. nethogs gives you a quick per-process view, iftop shows which remote systems are involved, ss helps you connect traffic back to a specific PID, and /proc gives you a last-resort option when nothing can be installed.
In most real-world cases, you will not need all four, because nethogs alone is usually enough to spot the problem in under a minute, especially on a busy server.
The next time you see a sudden network spike, start with:
sudo nethogs eth0
In many cases, you will get a PID almost immediately. From there, you can use ss to inspect the connections, iftop to see where the traffic is going, or simply stop the process if it is not supposed to be running. Often the root cause is something simple like a backup job running twice, a cron task misfiring, or an application stuck in a retry loop.
So the workflow stays pretty straightforward once you know it: identify the process, confirm the connections, and decide whether it is expected behavior or something that needs to be shut down or fixed.
What tool do you reach for first when something’s eating bandwidth? Drop your answer in the comments, especially if you’ve got a method that’s faster than nethogs.





