Skip to content

Light-House-Group/Network-Speed

Repository files navigation

Network Monitor

A native macOS menu-bar utility that tells you, second by second, which apps are using your bandwidth and how much. No accounts, no telemetry, no background services beyond the menu-bar app itself. All data lives on your machine.

Platform Swift License


What you get

Menu bar

  • Live total speed. ↓ 1.2 MB/s | ↑ 305 KB/s, refreshed every second.
  • Left-click opens the popover. Right-click brings up Launch-at-Login + Quit.

Popover (the per-app list)

  • One row per app, sorted by cross-session lifetime bytes. Each row reads as 3 lines on each side:
    • Left: name + code-signature trust icon · System/User chip + PIDs · last-active time
    • Right: total bytes · ↓ in / ↑ out · current speed (when transmitting)
  • Live green dot before any app currently transmitting.
  • Active-count badge in the header doubles as a filter — click to show only currently-active apps, click again to show all.
  • Search bar (always visible) filters across app names, PIDs, ports, and services. Results group into four collapsible sections with colored match-type chips. Just start typing anywhere in the popover — the first printable keystroke jumps you straight into search.
  • Right-click any row:
    • Hide from List — single ignore
    • Select Multiple to Hide… — enters multi-select mode with a top action bar; click rows to toggle (no checkboxes), then Hide Selected
    • Reset All-Time Data — wipes the persistent lifetime store
  • Gear menu: restore ignored apps, close all chart windows (when ≥ 2 are pinned), reset all-time data, quit.

Chart panel (click any row)

A floating panel opens beside the popover with a per-app history graph and a port/service breakdown.

  • 3-line header mirroring the row layout: pulsing activity dot + name + trust · origin + PIDs + status · live ↓/↑.
  • Date-range picker: Live (1 min) / 5 min / 15 min / 1 hour / 24 hours / 7 days / 30 days.
  • Trading-chart crosshair on hover — dashed vertical at the snapped time + two horizontal guides (blue ↓, green ↑) reading off the y-axis, plus a floating value box showing the exact numbers. Cursor turns to a crosshair over the plot.
  • Port / service breakdown under the chart: every service the app talks to (443 → https, 53 → dns, …) with ↓/↑ totals. Click any port to expand the distinct remote IPs behind it.
  • Resizable graph / port-service split with a draggable divider that highlights on hover. Per-pane minimums prevent collapse.
  • Movable, resizable window. Drag from any non-interactive area; resize from edges + corners.
  • Pin to keep it open. Up to 3 pinned panels can be open simultaneously — useful for comparing two or three apps' traffic patterns live. Unpinned chart auto-closes when you click anywhere in the main popover or outside both windows. Pinned charts survive until you close them explicitly.

How it works (one minute)

The app spawns /usr/bin/nettop -P -n -L 1 once per second, parses the CSV output, and computes per-PID byte deltas. PIDs are grouped by bundle identifier so multi-process apps (Chrome helpers, Electron renderers) collapse to a single row. The previous architecture tried to keep one long-lived nettop process, which doesn't work — nettop block-buffers stdout when piped and only emits CSV when given -L. Per-cycle spawning costs ~60 ms each tick (idle CPU stays near 0%).

Code signatures are checked once per bundle path via SecStaticCodeCheckValidity and cached. Lifetime byte counts are accumulated into a JSON file under ~/Library/Application Support/NetworkUsageMonitor/lifetime.json and saved every 30 seconds plus on quit. Speed history is tiered: 1 Hz samples for the last hour in memory, per-minute averages for 24 hours, and per-hour averages for 30 days — both averaged tiers persisted to speed-history.json.


Requirements

macOS 13 Ventura or later (Swift Charts)
CPU Intel or Apple Silicon
Toolchain (for building) Swift 5.9+ (Xcode 15 or Command Line Tools)

No external Swift packages. The app is not sandboxed — it needs to invoke nettop and read installed-application metadata via NSWorkspace, both of which the App Sandbox blocks. That's why this can't ship on the Mac App Store; download from GitHub Releases (or Homebrew) instead.


Install

Option 1 — Homebrew Cask

brew install --cask light-house-group/taps/network-monitor

Option 2 — Pre-built download

Grab NetworkUsageMonitor.app.zip from the Releases page, unzip, and drag NetworkUsageMonitor.app into /Applications.

First launch: right-click the app → Open → confirm. (Standard Gatekeeper prompt for unnotarized builds; the app is ad-hoc-signed.)

Option 3 — Build from source

git clone https://github.com/Light-House-Group/Network-Speed.git
cd Network-Speed
./Scripts/build_app.sh --run        # builds + launches
# or
./Scripts/build_app.sh --install    # builds + copies to /Applications + launches

The script handles compilation, bundle assembly, ad-hoc signing, and (optionally) installation.


Keyboard & mouse cheat sheet

Action Result
Left-click menu bar Open / close popover
Right-click menu bar Launch-at-Login + Quit menu
Type anywhere in popover Auto-enter search; characters seed the field
Click row Open chart for that app
Click same row again (chart open) Close that chart
Click anywhere in popover (chart open, unpinned) Close transient chart
Pin button in chart header Promote chart to standalone window (survives outside clicks)
Drag chart panel body Move window
Drag chart edges/corners Resize window
Drag chart divider Resize graph vs. port-service split
Hover plot Crosshair with ↓ / ↑ / time at snapped sample
Right-click row → Select Multiple to Hide… Enter multi-select mode

Project layout

Network-Speed/
├── Package.swift
├── Scripts/
│   ├── build_app.sh                  # build + sign + (optional) install/run
│   ├── Info.plist                    # bundle metadata
│   └── NetworkUsageMonitor.entitlements
├── Sources/NetworkUsageMonitor/
│   ├── NetworkUsageMonitorApp.swift  # @main + AppDelegate + popover plumbing
│   ├── Managers/
│   │   ├── NetworkMonitor.swift      # per-cycle nettop spawner
│   │   ├── NettopLineParser.swift    # pure CSV-row parser
│   │   ├── NetworkViewModel.swift    # SwiftUI publishers
│   │   ├── ProcessTracker.swift      # per-PID → per-bundle aggregation
│   │   ├── ProcessClassifier.swift   # System/User + Trust verdicts
│   │   ├── LifetimeUsageStore.swift  # persistent all-time totals
│   │   ├── SpeedHistoryStore.swift   # tiered history: 1h raw + 24h/30d on disk
│   │   ├── LatestSnapshotStore.swift # per-id live snapshot cache
│   │   ├── IgnoreListManager.swift   # user-hidden apps
│   │   ├── BudgetManager.swift       # per-app session limits (no current UI)
│   │   ├── BudgetNotifier.swift      # threshold-crossed notifications
│   │   ├── ServiceDirectory.swift    # port → service name lookup
│   │   └── LaunchAtLoginManager.swift
│   ├── Models/
│   │   ├── AppNetworkUsage.swift
│   │   └── NetworkSpeed.swift
│   ├── Utilities/FormatUtility.swift
│   └── Views/
│       ├── PopoverRootView.swift     # popover + search + multi-select
│       └── GraphPanel.swift          # chart panel + multi-pin controller
└── Tests/NetworkUsageMonitorTests/
    ├── NettopLineParserTests.swift
    ├── ProcessTrackerTests.swift
    ├── BudgetManagerTests.swift
    ├── FormatUtilityTests.swift
    └── LifetimeUsageStoreTests.swift

Known limits

  • 30-day history with downsampling. Raw 1 Hz samples for the last hour (in memory), per-minute averages for 24 hours, per-hour averages for 30 days. Long ranges are averaged, not raw — a 30-day view shows hourly means.
  • No retroactive counters. macOS doesn't expose per-process bytes the kernel counted before our app launched, so All-Time totals only include bytes observed while the monitor was running.
  • Cold-start cost. First snapshot after launch hashes each running binary's signature. Expect a brief ~0.3-1 second CPU spike, then idle.
  • Not in the Mac App Store. See Requirements — the sandbox blocks nettop invocation.

Contributing

Bug reports, fixes, and feature ideas are all welcome. Please open an issue first for anything larger than a small fix so we can sort scope. See CONTRIBUTING.md for the basics.


Publishing & Distribution

If you're a maintainer (or planning to fork-and-ship), read DISTRIBUTION.md — covers Apple Developer ID signing, notarization for Gatekeeper, GitHub Releases automation, and submitting a Homebrew Cask formula.


License

MIT — see LICENSE.

About

A native macOS menu-bar utility for live, per-app network monitoring — with cross-session totals, code-signature trust badges, and an on-hover historical graph. No accounts, no telemetry, no background services. Just a small status item that quietly tells you who's using your bandwidth.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors