Your real speed, up and down, in the menu bar.
Pinned reads the byte counters your Mac already keeps and turns them into a live download and upload readout, on whatever connection is actually carrying your traffic. Open the panel and it also names the app moving the bytes, counts your data cap against your real billing cycle, and measures whether the link still holds up under load.
Not submitted yet. Follow the build at bhd.om.
Other menu bar monitors measure ten things and show you a dashboard. Pinned answers four questions completely: how fast, which app, how much this cycle, and is the link usable.
Fig. 1 / the readout
22 pt bar
The status item is drawn at a guaranteed fixed width. Measured identical from 0 B/s to 1.4 Gbps, so it never jitters and never shoves the items beside it along the bar.
What it measures
It counts what already moved. It does not go and fetch anything.
macOS keeps a running byte count for every network interface on your Mac. Pinned asks the kernel for that list once a second, through sysctl(NET_RT_IFLIST2), and reports the difference between one reading and the next. That difference is your speed. That is the entire measurement.
Those particular counters are 64-bit. The easier interface to reach for hands back 32-bit counters, which wrap every 4.29 GB. On a fast link that can be a few minutes, and every wrap would land on screen as a nonsense spike.
Pinned opens no sockets of its own to do this. No probe, no test file, no server at the other end, nothing added to the very traffic it is trying to describe.
Which interface it reads follows the system default route, re-checked on every tick. Unplug Ethernet and the readout is on Wi-Fi. Tether to a phone and it is on the phone. There is nothing to configure, and a reading it cannot trust is reported as zero rather than guessed at.
Signal path
sysctl(NET_RT_IFLIST2), no elevated privileges requiredFollows the default route
Per-app bandwidth
Which app is moving the bytes, right now.
A rate on its own tells you that something is happening. It does not tell you what. Pinned breaks the live figure down by process, so "why is my connection busy" has an answer rather than a suspicion.
Fig. 2 / by process
Measured on the developer's Mac
- cloudflared 4.42 GB
- claude 163.1 MB
- node 54.6 MB
- mongod 52.2 MB
The usual way to attribute traffic to a process is to install a privileged helper. The commercial alternative ships a root LaunchDaemon: it loads when your Mac loads, and it stays resident whether or not you ever open the menu. That is a permanent piece of your system, running as root, in exchange for a list you glance at now and then.
Pinned does not do that. Per-app attribution runs inside the sandbox, in the app itself. No privileged helper, no root daemon, no admin password, and no permission prompt at any point.
The cost model follows from that. Pinned samples per app at a 3 second floor, and only while the panel is open. Close the panel and the work stops: independently verified at zero subprocesses while closed. A feature you are not looking at should not be running.
What it costs
Two limits worth stating plainly. A 3 second poll cannot see a transfer that starts and finishes between two samples, so a short burst can be missed entirely. And per-app figures are gathered at the socket level, which means they do not sum exactly to the interface total.
Data caps
Counted on your billing cycle, not the calendar month.
"How much of my allowance is left, and am I going to make it to the end of the cycle" is a question a network monitor should answer. Most of them do not.
Set your cap and tell Pinned the day your carrier's cycle starts. Every total is then counted against that window, so a cycle beginning on the 12th runs from the 12th to the 11th, which is what your bill already does.
The awkward cases are handled rather than ignored. A cycle day of 31 uses 28 February and 30 April, and lands back on the 31st in the months that have one. A cycle should never silently skip a month because the calendar was short.
When you are on course to overrun, Pinned says so in words instead of leaving you to do the arithmetic:
Totals are also kept per network, so you can see how much went over the hotel Wi-Fi and how much went over the phone hotspot, which is usually the one that costs real money. Alerts fire at the cap thresholds you choose, on the same hold-and-cooldown rules as every other alert.
Cycle handling
Responsiveness
A link can be fast and still be unusable for a call.
Latency measured on an idle link is nearly useless. What ruins a video call is latency under load, and the only way to know that number is to put the link under load and measure it there.
Your download figure describes how much water the pipe carries. A call cares about how long one drop waits in the queue. When a large transfer fills the buffers in your router, every small packet has to line up behind it, so the connection stays fast and the call falls apart at the same time. That is bufferbloat, and on this connection it is 53 ms of delay that only exists when the link is busy.
Pinned saturates the link on demand, probes while it is saturated, and reports the loaded figure, the idle figure, the gap between them and the round trips per minute. Four numbers, and the one that matters is the gap.
When it runs
Specification
Everything it does, and nothing it does not.
Notify me when a value crosses a threshold and stays there for a duration I choose. A one-second dip is not an event.
Light on your Mac
A monitor that costs you something is a bad trade.
Both figures are measurements, not targets. Taken on an Apple silicon Mac running macOS 26, with the panel closed and Pinned sampling the rate once a second. Opening the panel adds the per-app sampler at a 3 second floor, and closing it takes that back to nothing. Your own numbers will move a little with your settings and your hardware.
Privacy
Nothing leaves your Mac, and there is no small print under that sentence.
A network monitor sits in a position of unusual trust. Here is exactly what Pinned is allowed to do.
Requirements