Omahub
← All plugins
O

Network Usage

by oliwier-xiao

Which apps used your bandwidth, in bytes, with a day of history behind it. Two ranked bar charts — one for what came down, one for what went up — measured at packet level, so QUIC and UDP count too, and traffic from a container arrives under the container's name instead of a hole in the numbers.

Security review

Review recommended · 3 findings

Deterministic scan — not a security guarantee

Medium
Risk level
Medium
Analyzed commit
f9817e4
Scanned
3 days ago
  • medium sudo Panel.qml:407

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo or pkexec is required afterwards."
  • medium sudo bin/net-usage:19

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo or pkexec is required: the nethogs package grants its own binary the
  • Docs sudo README.md:20

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo or pkexec is required — nethogs grants

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

Low
AI risk level
Low
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
f9817e4
Reviewed
2 days ago

The plugin is a network usage monitor that wraps nethogs and reads container counters via docker. It does not use sudo or pkexec; the deterministic scan flagged documentation comments only. The code is well-structured with bounds on history size and app names, and it writes only to a user-local state file. No malicious behavior, persistence, or credential theft was found.

  • The deterministic scan flagged 'sudo' mentions, but these are documentation/comments only; the actual code never elevates privileges.
  • The plugin reads container traffic via docker and /proc, but only reads world-readable data and does not modify anything.
  • History is stored in a predictable user-writable path, but the plugin caps file size and app count to prevent resource exhaustion.
How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/oliwier-xiao/omarchy-network-usage --enable
System #bar #quickshell #system

Network Usage

Which apps used your bandwidth, one click from your Omarchy bar.

Install Update Remove
omarchy plugin add https://github.com/oliwier-xiao/omarchy-network-usage.git --enable omarchy plugin update oliwier.network-usage omarchy plugin remove oliwier.network-usage

The Network Usage panel: today's download and upload, ranked by app

Two ranked bar charts — one for what came down, one for what went up — and a day of history behind them. When a gigabyte went somewhere this afternoon, this is the thing that says where.

Measured at packet level rather than inferred from open sockets, so UDP counts — which today means QUIC, which means most of what a browser does. Traffic from a container arrives under the container's name instead of a hole in the numbers, which matters on the day a local build pulled a few gigabytes and nothing on the machine will say what did.

An Omarchy Quattro shell plugin (bar-widget + service). Needs omarchy-shell and the nethogs package from the standard repositories. No sudo or pkexec is required — nethogs grants its own binary the capabilities it needs when it installs, and the plugin never asks for more.


Install

1. Install nethogs. Nothing else on a stock Arch box attributes wire bytes to a process, so the plugin has nothing to count without it — the kernel does not keep that score per app.

omarchy pkg add nethogs

2. Add the plugin.

omarchy plugin add https://github.com/oliwier-xiao/omarchy-network-usage.git --enable

If the bar does not pick it up:

omarchy restart shell

The panel will tell you if nethogs is not there yet. To ask directly:

~/.config/omarchy/plugins/oliwier.network-usage/bin/net-usage doctor

Update anytime with omarchy plugin update oliwier.network-usage. To take it off the bar, see Removing it — the history stays behind unless you clear it too.


What the numbers mean

Wire bytes, headers included, which run about 3% above the payload an app thinks it moved. That is the honest figure — it is what your connection actually carried and what a data cap counts.

Totals are counted continuously between samples, not sampled from them, so a shorter sample interval does not make them more accurate. It only makes the panel newer.

What nothing on this machine asked for

A shared network carries every host's broadcast and multicast chatter — mDNS, NetBIOS, SSDP — to every card attached to it. Your machine receives that traffic because it is addressed to everyone, no socket here owns a single byte of it, and the kernel discards it on arrival. It is not a download. Nothing requested it and nothing read it.

Packet-level accounting still counts it, and since it belongs to no process it can only ever be drawn as one enormous unnamed bar. On a busy office network it is routinely most of the inbound total for the day — a couple of kilobytes a second, every second, which is a few hundred megabytes by midnight. The charts leave it out, so what you see is what this machine actually used.

To see what it consists of on your network:

~/.config/omarchy/plugins/oliwier.network-usage/bin/net-usage explain

Six pcap filters run over one shared window, so the shares are comparable:

ARRIVING ON THE WIRE                   DOWN  SHARE
everything                          10.7 KB   100%
not addressed to this host           9.2 KB    86%
  mDNS / Bonjour (5353)              5.9 KB    54%
  NetBIOS (137, 138)                 3.9 KB    36%
  SSDP / UPnP (1900)                    0 B     0%
QUIC (udp 443)                          0 B     0%

Count broadcast traffic nothing asked for puts it back in, for measuring the wire rather than the machine.

Version 1.0.0 counted it. Upgrading drops the one row it was recorded under, once, and brings the affected day totals down with it — the real bytes in that row cannot be told apart from the noise after the fact, and leaving it in would mean charts that promise to exclude that traffic while still drawing it.

The two unknown rows

What is left over after that genuinely cannot be traced from user space, and it gets its own row per protocol rather than one shared lump, because the two have different causes.

(unknown TCP) is almost always a container. A socket living in another network namespace has no process on this side of it. With Name container traffic on, most of it is pulled back out and named, so this row is usually small.

(unknown UDP) is a connectionless socket that closed before it could be matched to a process, or QUIC that arrived faster than the mapping could keep up.

If either is ever the largest bar, that is worth knowing rather than worth hiding.

When the router disagrees

A UniFi or router dashboard and this plugin measure different things, so their totals legitimately differ. The gateway's DPI undercounts wired traffic it never classifies, and it sees WAN-only while the plugin sees the wire, LAN traffic included. Meanwhile (unknown TCP) — short-lived connections, build workers, containers, kernel traffic no socket owns — lands in the plugin's totals but in no app's row, which is exactly the gap that opens up during something like npm run build.

To check which side of the gap you are on:

~/.config/omarchy/plugins/oliwier.network-usage/bin/net-usage validate

validate counts apps and the kernel side by side over one short window (default 5s) and prints a verdict: OK (counted within 1.5x of the wire), SUSPECT (within 2.5x), or OVERSHOOT (above that — the counted bytes dwarf what the card received). net-usage explain then breaks the wire side down by pcap filter, which is how you find out what an unnamed bar was made of.

Two charts, not one

Download and upload are different questions asked of the same list, and you almost always have one of them in mind. Side by side in one chart, the answer to either is harder to find. Apart, each chart ranks independently — the app that dominates your download often is not the one dominating your upload, and two charts show that at a glance where one would bury it.

It also means colour is decoration here rather than the thing carrying the meaning, so nothing is lost if the two hues read the same to you.


Settings

Setting Default What it does
Next to the bar icon Download Download, Both directions, or Nothing. Both roughly doubles the width.
Apps per chart 8 Bars drawn before the rest are summed into one row. Click that row, or press e, to list them all.
Name container traffic on Reads each container's own byte counters and puts a name on them.
Show what could not be attributed on Keeps the chart honest about the size of the gap.
Count broadcast traffic nothing asked for off Adds back the chatter no socket here owns.
Sample every 2s A battery setting, not an accuracy one.
Keep history for 90 days Older days are dropped when the file is next written.
Watch this interface empty Empty follows the default route. Name one when a tunnel is up.

Set them from the bar's widget settings, or:

omarchy bar set oliwier.network-usage topApps 10
omarchy bar move oliwier.network-usage --section right

Keys

Key Does
↑, ↓ Scroll the panel
e List every app, or fold the tail back up
d Step through the last seven days
t Back to today
Tab Next panel
Esc Close

The day strip and key hints along the bottom of the panel

Clicking a day in the footer strip pins it; clicking today unpins.

The last row of each chart sums whatever did not fit — click it to list every app instead, and show fewer to fold it back. Expanded charts are usually taller than the panel, which is what the scrolling is for.

From a terminal

The collector is a plain script and is useful on its own. This is the answer to "what is using my connection right now":

~/.config/omarchy/plugins/oliwier.network-usage/bin/net-usage top
APP                              DOWN           UP  SOURCE
curl                           3.9 MB      76.4 KB  proc
webae-postgres                 2.9 MB      79.1 KB  container
claude                         4.9 KB      65.9 KB  proc
(unknown TCP)                  1.2 KB          0 B  unattributed

net-usage top [rows] [seconds] watches for a few seconds and ranks what moved. net-usage validate [seconds] (default 5s) counts apps against the kernel over one window and prints a verdict (OK / SUSPECT / OVERSHOOT) — the check to reach for when the plugin's total and the router's disagree. net-usage explain [seconds] breaks the inbound traffic down by pcap filter, which is how you find out what an unnamed bar was made of. net-usage doctor reports what is missing. net-usage probe prints the interface, the date and the container counters once.

What it cannot tell you

  • A recycled process id is attributed to whatever held that id before it, until the daily restart clears the slate. There is no way to see this from outside the tool.
  • A tunnel counts once. With WireGuard or a VPN up, the same payload is visible as plaintext inside the tunnel and as encrypted UDP outside it. The plugin follows the default route and counts one of them; name the other under Watch this interface if it is the one you meant.
  • Traffic before the shell started was not counted. This is a ledger kept from when it was opened, not a reconstruction.

Removing it

omarchy plugin remove oliwier.network-usage

That leaves the history behind. To take that too:

rm -rf ~/.local/state/omarchy/network-usage

Where things live

Path What
~/.config/omarchy/plugins/oliwier.network-usage/ The plugin
~/.local/state/omarchy/network-usage/history.json Per-day, per-app totals
~/.config/omarchy/shell.json Where the bar records your settings

The history file is state, not config — numbers the machine produced rather than preferences you set. If it is ever unreadable it is moved aside once as history.json.broken and counting starts again, rather than the day being lost to a parse error.

The shell never opens it. omarchy-shell is one process for every plugin on the desktop, so the file is opened once in a child process, with the flags that refuse a symlink outright and decline to wait on a pipe, and its type, its owner and its length are then read off that one descriptor rather than off the name — which anything else running as you can change between one look and the next. Something too large is refused whole rather than cut down to the ceiling: half a document is not a shorter history, it is a parse error wearing one.

Nor is it written by the shell. The replacement is built beside it under a name that the open either creates or fails on, and then renamed over the old one — so a link left at history.json is what gets replaced, and whatever it pointed at is never opened.

License

MIT — see LICENSE.