How to check what an app sends over the network on a Mac
· 7 min read
The quickest check is Activity Monitor’s Network tab: sort by Sent Bytes, use the app for a while, and see whether its number moves. For more detail, Terminal has nettop (live connections per app), lsof (which hosts it is connected to right now) and tcpdump (the actual packets, including the DNS lookups that reveal hostnames). None of these will show you the contents of encrypted traffic, but they will tell you whether an app talks, to whom, how often, and how much. That is usually enough to decide whether you trust it.
Start with Activity Monitor
This needs no Terminal and gives a fast yes-or-no.
- Open Activity Monitor (in Applications, Utilities, or search Spotlight).
- Click the Network tab at the top.
- Click the Sent Bytes column header to sort by it, descending.
- Find the app you are checking. Note its Sent Bytes and Rcvd Bytes.
- Use the app normally for ten minutes. Launch it, do the things you usually do, leave it idle.
- Look again. If Sent Bytes did not change, the app sent nothing in that window. If it grew by a few kilobytes, it made some calls (an update check, a license ping, analytics). If it grew by megabytes, it uploaded something.
The numbers are cumulative since the process started, so quitting and relaunching the app resets them, which is a handy way to measure “what does it send on launch.”
Limits: Activity Monitor shows totals, not destinations, and helper processes appear under their own names. Look for related entries (helpers often contain the app’s or developer’s name) and add them up.
See live connections with nettop
nettop is a built-in command that shows every open connection per process, updating in real time, with bytes in and out.
- Open Terminal.
- Find the process ID:
pgrep -x "Example"(use the app’s process name as shown in Activity Monitor). - Run
nettop -p <pid>, replacing<pid>with the number. - Watch the list. Each line is a connection, with the remote host and port and the bytes transferred. Press
qto quit.
If you want the whole Mac at once, run nettop with no arguments and look for the app’s name in the left column. The -m tcp flag narrows it to TCP connections, which is where nearly all app traffic is.
An app with no networking code, like Punchcard, never appears in nettop at all, because it never opens a connection. That is the kind of result that makes a claim easy to check rather than something you take on faith.
List current connections with lsof
lsof answers “what is this app connected to right now” in one command.
- Get the process ID as above.
- Run
lsof -i -n -P -a -p <pid>.
The -i flag lists network connections, -n and -P skip name lookups so the output is fast and unambiguous, and -a -p restricts it to your process. Each line shows the protocol, the local address, the remote address and port, and the state (ESTABLISHED, LISTEN, and so on).
An app with a persistent connection to a server will show it here even while idle. An app that makes a quick call on launch and closes it will show nothing most of the time, which is why lsof pairs well with the cumulative numbers in Activity Monitor.
A variant that covers every process: sudo lsof -i -n -P lists all network connections on the Mac with their owning process. Scanning this once is a good way to discover background helpers you forgot about.
Watch the packets with tcpdump
When you want to know which hostnames an app contacts, the DNS lookups are the giveaway, because they are usually sent in the clear even when the traffic that follows is encrypted.
- Find your network interface. For Wi-Fi it is usually
en0.ifconfiglists them if you are unsure. - Run
sudo tcpdump -i en0 -n port 53and enter your password. - Launch or use the app. Each DNS query appears as a line ending with the hostname being looked up.
- Press Control-C to stop.
Hostnames tell you a lot. A developer’s own update server is one thing; an analytics or crash-reporting domain is another; a dozen advertising domains is a third. You will see lookups from every app on the Mac, so close what you can, or launch the app at a known moment and read the lines that appear right then.
To watch all traffic to a specific server once you know its address: sudo tcpdump -i en0 -n host 203.0.113.10. You will see packet counts and sizes, not contents.
If your Mac uses encrypted DNS (a profile or a VPN can set this up), port 53 will be quiet. In that case rely on lsof and nettop, which show the addresses after resolution.
What encryption hides, and what it does not
Nearly all app traffic is HTTPS. That means:
- You cannot read the payload with the tools above. Whether the app sent your name or just a version number is invisible.
- You can see the destination (hostname via DNS, or the address via
lsof), the timing, the frequency, and the size. Those four facts are often enough. A tracker that sends 200 KB every five minutes to a server is not sending a version check. - To read contents you need an HTTPS debugging proxy that installs its own certificate on your Mac so it can decrypt traffic you route through it. Apps that pin their certificates will refuse to connect through one. This is a reasonable step for a developer; for most people the destination and volume answer the question.
The built-in tools tell you whether the app is talking and to whom. A proxy tells you what it is saying. For deciding whether to trust an app, the first is usually decisive.
Reading the results
What you are looking for, from least to most concerning:
- Nothing. No bytes, no connections, no DNS. The app is offline by construction. Rare, and the easiest case to trust. The longer explanation of how to verify this from the binary itself is in an-app-with-no-networking-code-what-that-means-and-how-to-check.html.
- A burst on launch to the developer’s domain, then quiet. Update check or license validation. Ordinary.
- Regular calls to analytics or crash-reporting domains. The app has telemetry. Check whether the privacy policy mentions it and whether you can turn it off in the app’s settings.
- Steady traffic while idle. Sync, or something that behaves like it. Fine for a sync app; worth a question for anything else.
- Uploads that scale with what you do. If Sent Bytes climbs as you work, the app is sending your activity. For an app that also holds Accessibility or Screen Recording permission, this is the combination to take seriously. See time-tracker-data-where-it-lives-and-who-can-read-it.html for what that means for a tracker.
One round of these checks on your always-on apps tells you more than any privacy policy. Repeat after major updates, because the behavior can change.
Questions
Do I need to turn off the macOS firewall to see traffic?
No. The firewall affects incoming connections, and none of these tools interact with it. You may need to allow Terminal to capture packets the first time you run tcpdump; the sudo password covers that.
An app shows Rcvd Bytes but almost no Sent Bytes. Is that fine?
Usually. Every request sends something (the request itself), but an app that mostly downloads (an update, a feed, a web page) will receive far more than it sends. The worry case is the reverse: sending much more than it receives.
Can I block one app from the network without uninstalling it?
Not with the built-in firewall, which does not control outbound traffic. A third-party outbound firewall can do it per app. Alternatively, for apps where the network is not part of the feature, prefer ones built without networking code so there is nothing to block.
Why does an app connect to Apple’s servers?
Notarization checks, iCloud, push notifications and in-app purchase receipts all go through Apple. Traffic to Apple domains is usually the system acting on the app’s behalf, though an app that uses iCloud sync is sending your data there by design.