What starts automatically at login on my Mac?
Track down everything macOS launches for you at login — Login Items, launchd user agents and system daemons — from the Terminal, then switch off the ones you never asked for.
What this covers
macOS has three separate places where something can be set to start on its own: the Login Items list (apps the system reopens for you), launchd user agents (background jobs loaded in your session) and launchd system daemons (jobs loaded at boot, before anyone logs in). Only the first is visible in System Settings, which is exactly why "what is this and why is it running?" is so hard to answer from the GUI. This guide reads all three from the Terminal, works out which job is which, and disables the ones that shouldn't be there — permanently, so they don't return after a reboot.
Symptom
List every Login Item registered with System Events
These are the apps macOS reopens for you at login — the Dock-visible kind that also show up in System Settings > General > Login Items. Asking System Events for them gives you a plain list of names you can copy, compare against what you installed, and act on. A name you don't recognise here is your first suspect. You'll know it worked when you get a comma-separated list of names back — or an empty result, which means nothing is registered at all.
osascript talks to System Events to list every login item and delete the unwanted ones by name.
$ osascript -e 'tell application "System Events" to get the name of every login item'▾ Undo
$ osascript -e 'tell application "System Events" to delete login item "App Name"'List the launchd jobs loaded in your session
Not everything that auto-starts is a Login Item. launchd user agents and system daemons load without ever appearing in the GUI, which is why an audit that stops at System Settings misses them. This listing shows every job in your session with its PID and last exit status: a PID means it is running right now, and a non-zero exit status means it has been crashing and being restarted. Worked if you get a list of job labels — scan for third-party prefixes (com.google, com.docker, vendor names) you never intended to keep.
Use plain `launchctl list` to audit agents running in your user session with their PIDs and last exit statuses.
$ launchctl list | head -30Read a suspicious job's own definition file
A job label tells you almost nothing; its plist tells you everything — which binary is executed, whether it runs at load or on a schedule, and which user it runs as. Pretty-printing turns that file into readable keys instead of XML you have to squint at, so you can tell a genuine updater from something you don't want. Look at ProgramArguments (what actually executes) and RunAtLoad / KeepAlive. This step is optional: you only need it once a specific label has caught your eye.
Dump any property list as readable key-value output — no Xcode, no XML squinting.
$ plutil -p ~/Library/Preferences/com.apple.TextEdit.plistCheck whether SSH Remote Login is quietly enabled
The most overlooked auto-start on a Mac isn't a login item at all: if Remote Login (SSH) is on, sshd is listening from the moment the machine powers up, before anyone logs in, with nothing visible in System Settings' startup section. Auditing 'what starts automatically' is incomplete without checking it. This needs sudo because the setting is machine-wide. Worked if you get a clear 'Remote Login: On' or 'Off' — an unexpected 'On' is a security problem, not merely a startup annoyance.
Use systemsetup -getremotelogin to see if other machines can SSH into this Mac.
$ sudo systemsetup -getremoteloginSwitch the unwanted job off for good
Removing a Login Item only covers applications. For a launchd job the durable fix is a disable override: launchd records that the job is off and honours it across reboots and across plist updates from the vendor — unlike killing the process or deleting a plist that the installer will simply rewrite. Confirm the new state right away, and keep the matching enable command noted down so you can reverse it. Worked if the job no longer reports as enabled and does not come back after a restart.
launchctl enable/disable writes a persistent override so a daemon stays off across reboots and updates of its plist.
$ sudo launchctl disable system/com.apple.example.daemon
# Confirm current state:
sudo launchctl print-disabled system | grep example▾ Undo
$ sudo launchctl enable system/com.apple.example.daemonConfirm the job's real state with launchctl print
The modern print interface reads a job's actual state in one place — enabled or disabled, last exit status, PID, arguments — so you verify the fix instead of assuming it. It doubles as the starting point if you later want to restart the job deliberately. Worked if the state shows the job as disabled (or simply not running) and the last exit status is no longer a crash-and-restart loop.
The modern launchctl interface — full state of any launchd job plus a restart that actually works.
$ launchctl print gui/$(id -u)/com.apple.FinderHow to confirm it worked
The unwanted name is gone from the Login Items list, launchctl print reports the job as disabled, and after a full reboot nothing respawns — no process, no menu bar icon, no background CPU load.
Undo everything
Every command above can be reverted. Run these in order to undo all of it.
$ sudo launchctl enable system/com.apple.example.daemon
osascript -e 'tell application "System Events" to delete login item "App Name"'Review before running — some steps may not be independent.
Sources
- osascript — execute AppleScript and JavaScript (macOS man page)Evidence: Documents running AppleScript from the shell; System Events' login items class manages startup items.
- systemsetup — configure System Preferences machine-level settings (macOS man page)Evidence: Documents `systemsetup -getremotelogin` and `-setremotelogin on|off` for the Remote Login (SSH) service.
- launchctl - Interfaces with launchd to manage servicesEvidence: Documents `launchctl list`: 'List all of the jobs loaded in their own domain' with PID, status and label columns; run without sudo it lists your user domain.
- launchctl(1) man pageEvidence: Man page for launchctl: the `list` subcommand prints the label, PID (or '-' if not running) and last exit status of each service in the caller's domain.
- plutil - Property List UtilityEvidence: Documents the -p option which prints the property list in a human-readable form to the terminal.
- plutil(1) man pageEvidence: The plutil man page describes -p: print the property list in a human-readable fashion (output format not designed for machine parsing).
Last verified: 2026-09-21
Related guides
Find out what is waking your Mac and stop it, using only built-in macOS power-management tools.
Find the process overheating your Mac with one-shot CPU snapshots, live monitors and disk/network tracing, then fix the cause and verify the machine cools down.
Check battery health, hunt down CPU-hungry and sleep-blocking processes, and tune sleep settings to stop fast battery drain on macOS.