How to Use LaunchAgents and LaunchDaemons on macOS: A Complete Guide

Last update: 22/09/2025
Author Isaac
  • LaunchAgents depend on user and system LaunchDaemons; both are managed by launchd and .plist files in specific paths.
  • macOS 13+ introduces SMAppService, notifications, and XML profiles for transparently approving items in the background.
  • Diagnose with sfltool, launchctl and logs from backgroundtaskmanagement; check items in System Settings.
  • Apply correct permissions, use KeepAlive with SuccessfulExit/NetworkState, and avoid touching /System/Library for maximum stability.

Guide to LaunchAgents and LaunchDaemons on macOS

In macOS, much of the magic happens behind the scenes thanks to services that start without you even noticing, and the pairing LaunchAgents/LaunchDaemons is the heart of that automation. If you ever wondered how to make a script Boot alone, keeping a critical app alive, or auditing what apps load, here's the practical guide you've been looking for.

From macOS 13, Apple changed the rules of the game with a new structure in the packages of apps and the framework of SMAppService, which provides more transparency to the user and consistent management of login elements, launch agents y launch daemons. Additionally, there are enhancements for administrators with configuration profiles and diagnostic tools that are a good idea to master.

Programs that run at startup
Related articles:
Programs That Run At Startup. Which Ones To Remove And How To Do It

What are launchd, LaunchAgents and LaunchDaemons

The process launchd It starts just after the kernel (it's one of the first to start, usually with PID 1) and is what launches, controls, and monitors other services. It normally consumes few resources, but if one day you see it running high in Activity Monitor, a restart usually returns it to normal.

The LaunchDaemons They are executed at system startup and do so in the context of root; they don't depend on anyone logging in and can't interact with the graphical interface. They're perfect for system tasks, persistent processes, and services that need to be available even when a user isn't logged in.

The LaunchAgents They are loaded when a specific user logs in and can interact with the interface (menu bar, notifications, windows, etc.). They are ideal for user utilities, app wizards and processes that require a login.

In both cases, the configuration resides in files .plist with keys and values ​​that indicate what to run, when, and how. These .plist files are managed by launchd and live in specific locations on the system, so knowing where they go, with what permissions, and how to load them is crucial.

Structure and location of .plist files

macOS organizes .plist files as follows: at the system level in /System/Library/LaunchAgents y /System/Library/LaunchDaemons, globally in / Library / LaunchAgents y / Library / LaunchDaemons, and at the user level in ~ / Library / LaunchAgents. The healthy rule is to install your own in /Library or in ~/Library, and Do not touch the /System/Library tree.

.plist files are XML files with keys like Label (service identifier), Programme o ProgramArguments (what to run), RunAtLoad (start as soon as it loads) or Keepalive (retry/live policy). You can view them with a text editor, but edit them carefully and always know what each key does.

For launchd to accept a .plist, ownership and permissions must be respected. As an administrator: sudo chown root:wheel /Library/LaunchAgents/mi.servicio.plist y sudo chmod 644 /Library/LaunchAgents/mi.servicio.plist. These settings ensure that root can write, the group wheel and others can read it, and launchd trusts the file.

Once installed, it loads with sudo launchctl load -w /Library/LaunchAgents/mi.servicio.plist or its counterpart in /Library/LaunchDaemonsTo remove it, you can use launchctl remove com.ejemplo.mi-servicio (where the label corresponds to the value of Label).

  0x803f7001 (License not found): How to activate Windows 11 step by step

New features since macOS 13: SMAppService and user transparency

Apple introduced an app bundle structure that keeps helper executables within the app itself and manages them with SMAppServiceThis allows recording and monitoring login elements, launch agents, and launch daemons as auxiliary executables, without spreading them throughout the system and with greater visibility for the user.

When these items are deployed via MDM or installers, macOS 13+ displays a managed item installation notification to report and allow review in System Settings. The first match with a rule generates a notification; subsequent matches that same day no longer issue repeated notifications.

If the user postpones the notification, macOS silences further notifications of this type for the chosen period (1 day or 1 week). While the notification is visible, no further installations appear; if you dismiss it, subsequent installations will resume notifications. This policy reduces noise while providing control.

Visibility and diagnostics: everything you need to check

To see what is being recorded with the new frame, open System Settings > General > Startup ItemsThere you'll see the login and background elements; the information button shows you the executable being launched and associated details.

Online commands, you have several uses. With launchctl list You get all the running services. For the background task framework, use sfltool dumpbtm and check the current status (includes the UUID of the payload of servicemanagement). If you need to clean up the state between tests, run sfltool resetbtm and, for hygiene, restart el Mac before trying again.

For real-time logs, filter on Console by the appropriate subsystem and category, or launch in Bus Terminal: log stream --debug --info --predicate "subsystem == 'com.apple.backgroundtaskmanagement' AND category == 'mcx'"With this, you'll see useful traces of item addition, deletion, and management.

If you have access to AppleSeed for IT, the tool Mac Evaluation Utility 4.3.0+ generates detailed reports along the lines of what it throws up sfltool dumpbtm, and allows exporting delimited results for further analysis or correlation with inventory.

XML profiles for managing background tasks

Organizations can automatically approve background items using a XML configuration profileContent is an array of rules (dictionaries); when an element matches, it is approved. There are several types of matching that are worth mastering.

  • BundleIdentifier (Bundle ID) with exact match for a specific app.
  • BundleIdentifierPrefix to authorize families of apps under a prefix.
  • TeamIdentifier from the developer (code signing) with exact match.
  • Label of the service (key Label from the launchd .plist) with exact match.
  • LabelPrefix to approve tags that begin with a given pattern.

With this approach, administrators ensure that legitimate elements are activated without friction, all with traceability and complying with corporate policy. If you manage fleets, this saves you support and prevents unnecessary downtime.

Security, malware and system powers

Many installers add .plist files that are forgotten when the original app is uninstalled. This residue can restart processes you thought were eliminated. Furthermore, malware abuses LaunchAgents to persist, collect data, and communicate with remote servers.

  What are the best programs that teach you how to sing?

Apple maintains an attribution file with common helper binaries that help identify who's who: /System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/Resources/attributions.plistConsulting it can give you clues to attribute executables to their parent apps in forensic analysis or cleanup.

As a "handcrafted" surveillance layer, you can activate Folder actions on sensitive routes: /Library/LaunchAgents, /Library/LaunchDaemons, /System/Library/LaunchAgents, /System/Library/LaunchDaemons y ~/Library/LaunchAgentsThis way, you'll be notified when a new .plist file appears, allowing you to inspect it on the fly.

Creating your own LaunchAgents and LaunchDaemons

The basic idea is simple: write a .plist with the Label (e.g., com.ejemplo.miscript), define Programme o ProgramArguments with the exact path of the executable/script, set keys like RunAtLoad and, if applicable, Keepalive, and place it in the appropriate folder.

If the task should run before login and without UI, place it in /Library/LaunchDaemons. If you depend on a user and/or interact with the interface, use /Library/LaunchAgents o ~/Library/LaunchAgents (only for that user). Remember to apply property and permits correct before loading.

To activate instantly: sudo launchctl load -w /Library/LaunchDaemons/com.ejemplo.miscript.plist. To stop and download: sudo launchctl unload -w /Library/LaunchDaemons/com.ejemplo.miscript.plist o launchctl remove com.ejemplo.miscript. Make sure the paths to binaries exist and are executable.

Practical advice: always test first on ~ / Library / LaunchAgents with your user, check logs and behavior, and only then promote to /Library. Avoid modifying /System/Library/…; in addition to being bad practice, the protected system (SIP) prevents it for security reasons.

KeepAlive policies and real-life use cases

If you need a process to always stay on top, the key Keepalive allows you granularity. You can put <true/> for unconditional retries or use a dictionary with conditions for fine control.

A very useful pattern combines Keepalive with SuccessfulExit. When you define SuccessfulExit = false, launchd will retry if the process exits with a code other than 0 (crash, error), but if the user closes it "cleanly" (exit 0), No. will relaunch it. This way you can avoid any hassles when updating an app or shutting down your Mac.

Another common approach is NetworkState: if you set it to true Within KeepAlive, the relaunch will respect the "network availability" (the device has an IP address). Note: a network presence doesn't always mean internet access; launchd only checks for basic connectivity, not that your ISP is responding.

If you plan to keep an interface app alive (for example, a menu bar utility), create a LaunchAgent with its actual package binary: e.g., /Applications/MiApp.app/Contents/MacOS/MiApp. Avoid paths to aliases or the “iconic” app and point to the executable inside the package.

In unattended environments (kiosk, information screens, servers with persistent session), these policies can make the difference for your tools don't fall and if they do, they stand up on their own without human intervention.

Old alternatives and practices that should be avoided

Apple left aside Cron y LoginHooks as recommended ways to launch tasks; the official path is launchd. There were also startup items in older versions (folders in System and Global Library), but should not be used for new implementations today.

Edit system trees by hand (/System/Library/LaunchDaemons) may end up on a Mac that not start. Don't take any chances: if you need to boot very early, use /Library/LaunchDaemons with the correct configuration and permissions, and leave the system components alone.

Performance monitoring and troubleshooting

If you notice your Mac is slow, open Activity Monitor and sort by CPU. Normally launchd does not appear in the lead; if it is at 30-40% continuously, restart the system and check again. If it persists, list services with launchctl list and eliminate suspects.

  Filter messages from unknown senders on iPhone

To audit which items are recorded with the new framework, sfltool dumpbtm is gold: capture your exit and save it to your support report. Between tests, sfltool resetbtm It leaves you with a clean slate; remember to restart to avoid intermediate states.

Logs are your friends: with log stream --debug --info --predicate "subsystem == 'com.apple.backgroundtaskmanagement' AND category == 'mcx'" You'll get fine detail of highs, lows, and changes. Pair it with Console filtering by those same fields if you prefer a graphical interface.

Managing at scale with MDM and best practices

In managed deployments, create a XML profile that describes approval rules (by bundle ID, prefix, Team ID, tag, or label prefix). This way, when an app registers its helper, macOS will automatically approve it, and the user will see a controlled notification.

Test your standard flows (install, upgrade, uninstall) and validate the result with Declarative Device Management on macOS 14+ (status report) and with the aforementioned tools. Gather feedback from users and vendors to adapt apps to the new framework.

Document internal policy: what is authorized, under what criteria, who reviews it, how it is audited, and what to do if an element starts consuming resources. With this hygiene, you avoid surprises and improve the security, and the stability of the fleet.

Cleaning and continuous monitoring tips

If after uninstalling something the item reappears at startup, search for its .plist by name in /Library/LaunchAgents, /Library/LaunchDaemons y ~/Library/LaunchAgents. Delete the file and download the service with launchctl remove using his Label.

To increase your visibility, enable these Folder actions Commented: Every time a new .plist file appears in sensitive paths, you'll receive a notification and can intervene immediately. It's a simple measure that saves you headaches.

Keep in mind that agents are per-user and daemons are system-wide. On shared machines, you may want to prefer agents in ~/Library/LaunchAgents all with not affect other profiles, unless it is a cross-corporate task.

If you automate an app to always stay open, remember that it can block shutdown or restart when relaunched when the system attempts to shut down. Before updating or restarting, disable the service with launchctl remove or download the .plist, and re-activate it afterwards.

Finally, don't forget to check periodically System Settings > General > Startup Items and the background items section. This is the quickest way to detect "stowaways" who sneak in with careless installers.

To dominate LaunchAgents and LaunchDaemons It gives you control: you know what starts, when, and why; you can approve legitimate actions with profiles, diagnose with sfltool and logs, and strengthen security thanks to the transparency provided by SMAppService in macOS 13+. With a few clear rules (correct paths, permissions, consistent labels, and proper use of KeepAlive), you'll have stable services, informed users, and a more predictable system, without having to struggle with outdated methods.