← Back to blog

Guide

Bosun vs lsof: when is a menu bar app worth it over a one liner?

September 14, 20264 min read

Let us get the awkward part out of the way first. If you know the port number and you just want whatever is on it gone, lsof already solves that, it is already on your Mac, and it costs nothing:

lsof -ti :3000 | xargs kill

That is the honest baseline, and any comparison that pretends otherwise is wasting your time. So the real question is not “which one kills a process faster”, it is “when does the command line stop being the right tool”.

What the one liner actually does

It is worth understanding, because it is better than most people think.

The -t flag makes lsof print process IDs and nothing else. xargs takes every ID it printed and passes all of them to a single kill. So if four processes hold port 3000, which is what happens with multi worker servers like gunicorn, Odoo or a clustered Node app, all four get the signal at once.

You can verify it yourself. Start a server with a supervisor and three workers, then:

lsof -ti :9911
# 39238 39271 39272 39273

lsof -ti :9911 | xargs kill
# the port is free, all four are gone

A plain kill sends SIGTERM, which lets the process shut down cleanly. If something ignores it and the port stays busy, -9 forces the issue:

lsof -ti :3000 | xargs kill -9

Use the gentle version first. SIGKILL gives a process no chance to flush anything to disk.

Where the one liner runs out

The command works when you already know what you are looking for. It is weaker in three situations.

You do not know the port. lsof -i -P -n -sTCP:LISTEN will list everything that is listening, but the output is a wall of text with no sorting, no grouping, and IPv4 and IPv6 entries duplicated for the same process. Reading it is the slow part, not typing it.

The process name tells you nothing. Docker is the classic case. Every published container port belongs to a process called docker-proxy, so lsof shows you six identical rows and no way to tell which container is which. Same story with a bare node or python when you have several projects open.

The thing you forgot about is not a port at all. An ngrok tunnel or a cloudflared quick tunnel is a live route from the public internet into your laptop. It does not appear in a port listing in any way that identifies it. Neither does an active VPN connection. If you want to answer “what is my Mac exposing right now”, lsof is the wrong question to be asking.

What Bosun adds

Bosun runs the same lsof call underneath. It is not a different way of reading the kernel, it is a different way of reading the output, kept permanently visible.

It groups by port number, so a multi worker service collapses into one row with a worker count instead of eight identical lines. It maps docker-proxy back to the actual container image and Compose project. It detects ngrok and Cloudflare tunnels, including quick tunnels, and shows the public URL. It shows whether a native macOS VPN is connected. It keeps a history, so you can see what was listening earlier and not only what is listening now.

None of that is impossible from a terminal. It is just several commands, some of which you would have to look up, and you would have to remember to run them.

An honest recommendation

Situation Use
You know the port, you want it free, right now lsof -ti :PORT | xargs kill
Scripting, CI, a remote machine over SSH lsof, every time
You are not on macOS lsof, Bosun is macOS only
“What is running on this machine right now?” Bosun
Several Docker containers competing for ports Bosun
Checking whether a tunnel is still open to the internet Bosun

If you spend your day in one project with one dev server, learn the one liner and skip the app. Genuinely. The people Bosun is for are the ones running several services at once, or tunnels, or a stack of containers, who want the answer visible without going to look for it.

Bosun is a macOS menu bar app with a 14 day free trial and no signup. It needs macOS 14 or later.

See this instead of typing it

Bosun lives in your menu bar and shows every open port on your Mac, live, mapped to the process behind it. One-click kill, SIGTERM first. Useful the first time this happens. Genuinely useful the fifth time it happens in one afternoon.