←→ Underneath: Background Apps · All Mac guides
Why an app comes back after you restart your Mac
You quit it. You even force quit it in Activity Monitor. Two seconds later, or after the next restart, it is running again. Something is starting it on purpose. On a Mac, that something is almost always launchd.
Short answer: the app has a launchd job. RunAtLoad starts it at every login, and KeepAlive starts it again whenever it stops. Quitting the process does not change the job. To stop it for good, disable the job, not the process.
What launchd is
launchd is the first process macOS starts (process ID 1). It starts almost everything else. It reads small .plist files, called jobs, that say what to run and when. Each job has a label, a unique name like com.google.keystone.agent.
Apps install jobs in ~/Library/LaunchAgents, /Library/LaunchAgents or /Library/LaunchDaemons, or register them from inside their own app bundle.
The keys that bring an app back
Here is a typical launch agent:
<key>Label</key>
<string>com.example.helper</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/Example.app/Contents/MacOS/Helper</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
| Key | Effect | What you see |
|---|---|---|
RunAtLoad | Start the job as soon as it loads, which is at every login (agents) or startup (daemons) | It is there after every restart |
KeepAlive = true | Restart the process whenever it exits | Force quit does nothing; it is back in seconds |
KeepAlive with conditions | Restart only in some cases, such as after a crash (SuccessfulExit = false) or while the network is up | It comes back sometimes, not always |
StartInterval | Run every N seconds | It appears, runs briefly, disappears, repeats |
StartCalendarInterval | Run at set times, like cron | It appears at the same time every day |
WatchPaths | Run when a file or folder changes | It appears after you do something unrelated |
launchd waits about 10 seconds between restarts of a job that keeps exiting, so a KeepAlive job can also look like it “flickers”.
Other reasons an app comes back
- Open at Login. The app is in System Settings › General › Login Items & Extensions. macOS opens it at every login.
- Reopen windows when logging back in. The box in the Restart and Shut Down dialog restores every app that was open.
- The app adds itself back. Its own “Launch at login” setting re-registers it each time it runs.
- A helper opens the main app. A small background helper starts first and then opens the full app, for example to show a sync status.
- Homebrew services.
brew services startwrites a launch agent withRunAtLoad. Stop it withbrew services stop <name>.
Find which one it is
- Find the job label. Run
launchctl list | grep -i example, using part of the app or developer name. The third column is the label. - Read the job:
Look forlaunchctl print gui/$(id -u)/com.example.helperpath(the plist file),state,runs(how many times it started) andlast exit code. A high run count usually meansKeepAlive. - Open the plist and check
RunAtLoad,KeepAliveand the interval keys. - If there is no job, check Open at Login and the app's own settings.
Stop vs. disable
| What you do | Comes back? |
|---|---|
| Quit or force quit the process | Yes: right away if KeepAlive, at next login if RunAtLoad |
launchctl bootout gui/$(id -u)/label | Not now. Yes at next login if RunAtLoad |
launchctl disable gui/$(id -u)/label + bootout | No, until you run launchctl enable |
| Move the plist out of LaunchAgents + bootout | No, until you move it back |
| Turn off in Allow in the Background | No, until you turn it on |
Step-by-step commands are in how to disable launch agents safely.
FAQ
Why does a process restart right after I quit it in Activity Monitor?
Its launchd job has KeepAlive set. launchd watches the process and starts it again when it exits. Stop the job with launchctl bootout instead of quitting the process.
What does RunAtLoad mean?
RunAtLoad is a key in a launchd plist. When it is true, launchd starts the job as soon as it loads the plist, which for a launch agent means every time you log in.
What does KeepAlive mean?
KeepAlive tells launchd to keep the job running. If the process exits or is killed, launchd starts it again. It can also be a set of conditions, such as restart only after a crash.
What is the difference between stopping and disabling a launch agent?
Stopping (launchctl bootout) unloads the job until the next login or restart. Disabling (launchctl disable, or moving the plist out of LaunchAgents) stops it from loading again after a restart.