Continuously Monitor Linux Traffic With VnStat and Picosnitch

Contents

When traffic on a VPS looks abnormal, there are usually two questions: which network interface transferred how much data and when, and which service was actually responsible.

vnStat records sent and received traffic per network interface. It is useful for total egress and hourly, daily, or monthly trends. picosnitch records connections per executable, letting you continue down to processes, domains, ports, and byte counts. Both keep collecting data in the background, but at different levels, so they complement each other well.

vnStat: per-interface traffic

vnStat is not a packet sniffer. It reads the network-interface counters exposed by the kernel, while vnstatd periodically writes the data to its database. Resource usage stays low. It retains traffic records at five-minute, hourly, daily, monthly, and yearly resolutions.

Install it and start the service on Arch Linux:

sudo pacman -S vnstat
sudo systemctl enable --now vnstat

On its first start, the service creates database entries for available interfaces. List the ones already being recorded:

vnstat --dbiflist

An interface added later can be explicitly added, for example after Tailscale creates tailscale0:

sudo vnstat --add -i tailscale0

Common overview queries:

# Default summary: today, current month, and all time
vnstat -i wlan0

# Short summary
vnstat -i wlan0 -s

# Single parseable line for scripts
vnstat --oneline -i wlan0

# Last 7 days, 12 hours, and recent months
vnstat -i wlan0 -d 7
vnstat -i wlan0 -h 12
vnstat -i wlan0 -m

For the time range of an anomaly, combine --begin and --end with daily, hourly, or five-minute lists. With --end, vnStat adds a sum line at the end: the total received and transmitted traffic for that range.

# Daily records and the range total
vnstat -i wlan0 -d --begin 2026-07-20 --end 2026-07-31

# Hourly records within a day, precise to the minute
vnstat -i wlan0 -h --begin "2026-07-28 08:00" --end "2026-07-28 20:00"

# Five-minute records during a peak period
vnstat -i wlan0 -5 --begin "2026-07-28 12:00" --end "2026-07-28 14:00"

--begin accepts YYYY-MM-DD HH:MM, YYYY-MM-DD, and today; --end accepts the first two formats. They are only available with list output, JSON, or XML.

Use JSON when a script needs raw byte counts:

vnstat -i wlan0 -d --begin 2026-07-28 --end 2026-07-30 --json \
  | jq '.interfaces[0].traffic.days'

For a real-time rate or graphs:

# Press Ctrl+C to show statistics for this run
vnstat --live -i wlan0

# Terminal bar graph for the past 24 hours
vnstat -i wlan0 -hg

# Render daily data to a PNG
vnstati -i wlan0 -d -o ~/wlan0.png

Five-minute data is retained for only 48 hours by default. To keep fine-grained records of peak periods longer, change 5MinuteHours in /etc/vnstat.conf, then restart the service:

5MinuteHours 336
sudo systemctl restart vnstat

vnStat only records traffic from the point vnstatd starts running; it cannot recover traffic that passed through an interface earlier.

picosnitch: per-process traffic

vnStat can reveal when total interface traffic grows, but it cannot say which service generated it. picosnitch is a userspace daemon using BPF and fanotify. It records network connections by executable and stores them in SQLite. Its records include the executable path and hash, parent process, domain, port, user, and bytes sent and received. It can identify applications running in containers too.

The picosnitch upstream project recommends a system-wide pipx installation. On Arch Linux:

sudo pacman -S python-pipx
sudo pipx install picosnitch --global
sudo picosnitch systemd
sudo systemctl enable --now picosnitch

It requires Python 3.12 or newer and a Linux kernel capable of running modern libbpf CO-RE programs.

There are three ways to view the data:

# Terminal UI for historical connections
picosnitch tui

# Web UI, listening on http://localhost:5100 by default
picosnitch webui

# Live event stream
sudo picosnitch top

Configuration is at /etc/picosnitch/config.toml. The local SQLite database defaults to /var/lib/picosnitch/picosnitch.db and retains 30 days of history by default. To retain more history, change retention_days and restart the service:

[database]
retention_days = 90
sudo systemctl restart picosnitch

The Web UI listens locally by default. To make it reachable from a LAN or reverse proxy, set its address and port before launching it. Apply appropriate access control before exposing it publicly:

PICOSNITCH_HOST=0.0.0.0 PICOSNITCH_PORT=5100 picosnitch webui

Investigate anomalies with both tools

Start with vnStat to see the traffic that actually passed through an interface, then identify the day or hour when it grew. With that time window narrowed, open picosnitch’s TUI or Web UI and inspect the executables, domains, and ports for the same period.

For example, if vnStat shows a sharp increase in transmitted traffic through wlan0 across two hours at noon, check that range in picosnitch next. If the traffic is concentrated in caddy, inspect the clients it connected to; if it is concentrated in a backup job or downloader, continue with that service’s logs and configuration. Interface accounting finds the problem. Process accounting identifies its source.

Contents