Your server’s bandwidth graph spikes, uploads crawl, or the monthly traffic counter jumps. Which connection or process is responsible? iftop shows live traffic per connection (which remote hosts you’re talking to), and nethogs shows it per process (which program is sending). Together they answer “who is using the bandwidth right now?” in seconds.
Install
sudo apt install iftop nethogs # Debian/Ubuntu
sudo dnf install iftop nethogs # RHEL family (EPEL)
Both need root, because they capture packets.
iftop: traffic per connection
sudo iftop -i eth0
12.5Mb 25.0Mb 37.5Mb 50.0Mb
└──────────────┴─────────────┴─────────────┴─────────────┴──────
vps.example.com => 198.51.100.77 18.2Mb 17.9Mb 15.4Mb
<= 512Kb 498Kb 470Kb
vps.example.com => 203.0.113.200 2.10Mb 2.04Mb 1.98Mb
<= 96Kb 91Kb 88Kb
──────────────────────────────────────────────────────────────────
TX: cum: 1.20GB peak: 24.6Mb rates: 20.4Mb 20.1Mb 17.5Mb
RX: 40.2MB 640Kb 608Kb 589Kb 558Kb
TOTAL: 1.24GB 25.2Mb 21.0Mb 20.7Mb 18.0Mb
- Each pair of lines is one connection:
=>sent,<=received. - The three columns are the average rates over the last 2, 10 and 40 seconds.
Useful options and keys:
sudo iftop -i eth0 -n -N -P # no DNS lookups, numeric ports, show ports
sudo iftop -i eth0 -f 'port 443' # BPF filter, like tcpdump
sudo iftop -i eth0 -t -s 10 # text mode: print once after 10 s (for scripts/logs)
While running: n toggles DNS, p toggles ports, P pauses, s/d hide source or destination, t cycles the display, and q quits.
With -P you see which service is busy: :443 is your web server, :22 is SSH/rsync, an ephemeral local port to a remote :443 means your server is downloading. See tcpdump for filter syntax.
nethogs: traffic per process
sudo nethogs eth0
PID USER PROGRAM DEV SENT RECEIVED
4412 www-data nginx: worker process eth0 2210.4 35.1 KB/sec
9830 backup rsync eth0 1840.2 12.0 KB/sec
1123 root /usr/sbin/sshd eth0 4.1 0.6 KB/sec
This shows which program is responsible: Nginx serving downloads, a backup job, a Docker container (shown as its process), or something unexpected.
Keys: m cycles units (KB/s, KB, MB…), r sorts by received, s by sent, q quits. Use -d 2 for a 2-second refresh, and -t for trace mode output.
Unknown processes sending lots of traffic (to many IPs, or on port 25) can mean a compromised server: a spam bot or a DDoS participant. See detect a compromised server.
Other quick tools
| Tool | Shows |
|---|---|
nload |
Simple in/out graphs per interface |
bmon |
Per-interface rates with history |
vnstat -l |
Live rate, plus historical totals. See vnStat |
ss -tnp |
Connections and their processes (no rates) |
iptraf-ng |
Menu-driven per-connection and protocol statistics |
Typical findings and fixes
| Finding | Action |
|---|---|
| Nginx sending lots to many IPs | Popular downloads or media. Use a CDN, compression, and check for hotlinking |
| Nginx sending to a few IPs heavily | Scrapers or bots. Rate limit or block. See Nginx rate limiting |
| rsync / backup tools at peak hours | Schedule off-peak, use --bwlimit. See traffic shaping |
| Docker container pulling images | Expected during deployments. Use a pull-through cache |
| apt / dnf | Updates. Normal |
| Unknown binary, or many outbound SMTP connections | Investigate a compromise immediately |
Quick reference
| Task | Command |
|---|---|
| Live per connection | sudo iftop -i eth0 -nNP |
| Filter | sudo iftop -i eth0 -f 'port 443' |
| Snapshot to text | sudo iftop -t -s 10 |
| Live per process | sudo nethogs eth0 |
| Simple graph | nload eth0 |
Related: ss and netstat and Linux network troubleshooting.