On this page
Question 01
What is a launch agent on a Mac?
A launch agent is a small configuration file that tells launchd, the macOS process that starts and supervises background jobs, to run a program for you. The file is a property list (a .plist) that names the job with a Label, says which program to run and when: at login, on a schedule, when a file changes or whenever it quits. The difference between an agent and a daemon is who it runs for. A launch agent runs inside a user’s login session, as that user, so it can show windows, menu bar items and notifications. A launch daemon runs system-wide, usually as root, starts before anyone logs in and has no user interface. Software updaters such as Google’s and Microsoft’s, Homebrew services, Docker and many sync and backup tools install launch agents or daemons. Most are legitimate, but because they survive a restart, adware and malware use them too.
Question 02
Where are launch agents and daemons stored?
macOS reads launch jobs from five folders. ~/Library/LaunchAgents holds agents for your user only, and any app you run can write there without an administrator password. /Library/LaunchAgents holds agents that run for every user who logs in, and /Library/LaunchDaemons holds system-wide daemons; both need an administrator to change. /System/Library/LaunchAgents and /System/Library/LaunchDaemons belong to Apple, live on the read-only system volume and are protected by System Integrity Protection, so leave them alone. The Library folder in your home folder is hidden in Finder: choose Go › Go to Folder (Shift-Command-G) and type ~/Library/LaunchAgents, or list the folders from Terminal. Sort by date to see what was added recently. A plist file’s name usually matches its label, such as com.google.keystone.agent.plist, but the name alone doesn’t prove who made it, so read the file to see what it actually runs.
# Your agents, newest firstls -lt ~/Library/LaunchAgents# Agents and daemons for all usersls -lt /Library/LaunchAgents /Library/LaunchDaemonsQuestion 03
How do I read a launch agent’s plist?
Print it in a readable form with plutil -p followed by the path, for example plutil -p ~/Library/LaunchAgents/com.example.agent.plist. A few keys tell you most of what you need. Label is the job’s name inside launchd. Program, or the first item of ProgramArguments, is the executable that actually runs, and that path matters more than the file name. RunAtLoad set to true starts the job as soon as it is loaded, which for an agent means at every login. KeepAlive tells launchd to restart the program if it quits, so killing the process alone won’t make it go away. StartInterval and StartCalendarInterval run it on a timer or a schedule. WatchPaths starts it when a file or folder changes. If ProgramArguments starts with an interpreter such as /bin/bash, /bin/sh, python3 or osascript, look at the script it runs, because that script is the real program.
# Print a plistplutil -p ~/Library/LaunchAgents/com.example.agent.plistQuestion 04
How do I list, stop and remove launch agents with launchctl?
launchctl list shows the jobs loaded in your session with their PID, last exit status and label; a dash in the PID column means the job is loaded but not running. To stop and unload one of your own agents, run launchctl bootout gui/$(id -u) followed by the plist path. Older guides use launchctl unload with the path, which still works on many versions but is deprecated. For a daemon in /Library/LaunchDaemons, use sudo launchctl bootout system and the path. Unloading only lasts until the next login or restart if the plist is still in place, so to remove a job for good, unload it, then move its plist to the Trash; keep it there until you’re sure nothing broke. On macOS 13 and later, System Settings › General › Login Items (Login Items & Extensions on newer versions) also lists apps that are allowed to run in the background and lets you switch them off without touching files.
# Jobs loaded in your sessionlaunchctl list# Stop and unload one of your agentslaunchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.example.agent.plist# Stop and unload a system daemonsudo launchctl bootout system /Library/LaunchDaemons/com.example.daemon.plist