launchd: macOS
launchd: the macOS init system that sets everything in motion
`launchd` is the central init system of macOS, responsible for starting, managing, and stopping systems and tasks during and after the computer boots. It is the engine behind the scenes that ensures services, applications, and background processes are activated at the right time. The system is designed to be flexible, efficient, and reliable, and replaces a range of older Unix mechanisms such as `init`, `cron`, `inetd`, and `rc` scripts. launchd is not just a tool or a daemon: it is the building block of modern macOS system management.
It was introduced with Mac OS X 10.4 Tiger, which was officially released on April 29, 2005. With the arrival of Tiger, Apple brought a range of new features, and launchd was one of the most far-reaching technical innovations. Sources explicitly describe it as a "new startup daemon" and state that it was designed as a replacement for existing methods of starting processes at boot or on demand. Through this integration, Apple was able to create a more uniform, faster, and more manageable system in which the complexity of multiple separate initiators (such as cron for time-based tasks and inetd for network requests) was consolidated into a single central instance.
The development of launchd was led by Dave Zarzycki, an engineer at Apple who designed and programmed the software. His contribution marked a significant step in the evolution of macOS kernel-level management. Zarzycki's design focused on efficiency and safety: processes are only started when they are actually needed, which saves energy and system resources. This "on-demand" principle is a core feature of launchd. Unlike traditional init systems that load all daemons at boot, launchd waits until a request comes in – for example, when a user activates a particular service or a network request arrives.
Apple publicly announced Mac OS X 10.4 Tiger during WWDC 2005, the annual developer conference. The official keynote took place on June 6, 2005, at 10:00 AM in Moscone West, San Francisco. During this presentation, the introduction of launchd was highlighted as part of the new technical foundations of the operating system. Although the conference was aimed at developers and interested parties, this announcement marked the beginning of broader recognition of launchd within the technical community. The software would not only remain within macOS but would also influence other Unix-like systems, particularly FreeBSD, which would later adopt parts of launchd or learn from it.
An important aspect of launchd is that Apple has made its source code public. The public version was released under the Apple Public Source License (APSL), tied to the release of Mac OS X 10.4. This made it possible for developers and researchers to study, modify, and understand how the system works. The availability of the source code has contributed to the transparency and trust in the system, and has made it possible for other projects, such as FreeBSD, to integrate elements of it into their own init systems. The FreeBSD wiki page confirms this public release and mentions both the Apple source code and the license, which is an important external verification of this fact.
On a technical level, launchd is responsible for managing "jobs" – a general term for processes or tasks defined by the system or users. These jobs are described in XML files with the `.plist` extension (property list). Each job has a unique identifier, such as `com.harry.backup`, and contains settings such as when the process should start, under which user it should run, whether it should automatically restart on crash, and whether it should respond to certain events.
These `.plist` files are stored in different directories, depending on the type of job and its scope. For user-specific tasks, they are stored in `~/Library/LaunchAgents/`. For system-wide tasks, which are active regardless of which user is logged in, they are located in `/Library/LaunchDaemons/` or `/System/Library/LaunchDaemons/`. The distinction between "Agents" and "Daemons" is important: Agents run in the context of a user and only start once that user is logged in, while Daemons operate as system processes and can already be active during boot.
To work with launchd, one uses the `launchctl` command in Terminal. This is the primary interface for managing jobs. With `launchctl list`, you get an overview of all loaded jobs. By combining this output with `grep`, such as in `launchctl list | grep com.harry`, a user can quickly look up their own or specific tasks. Jobs can be manually loaded or disabled with `launchctl load` or `launchctl unload`, followed by the path to the `.plist` file. A job can also be temporarily started with `launchctl start`, without the underlying trigger (such as a time or event) actually having occurred.
An example of a LaunchAgent file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.harry.backup</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/backup-script.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>2</integer>
<key>Minute</key>
<integer>30</integer>
</dict>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>This file ensures that a backup script is executed every day at 2:30 AM, and also starts immediately when the job is loaded. It demonstrates how launchd not only replaces cron (via `StartCalendarInterval`), but also rc-scripts (via `RunAtLoad`).
launchd is not only responsible for starting jobs, but also for managing their lifecycle. It can track whether a process is still running, restart it after a crash (with settings such as `KeepAlive`), and shut it down correctly during system shutdown. All of this happens in a way that is transparent to the user, but is crucial for the stability of the system.
In addition, launchd supports socket activation: a daemon does not need to run continuously, but can be started as soon as a connection is made to a specific port or socket. This significantly reduces memory and CPU usage. A well-known example is the Apache HTTP Server, which can be managed via launchd with `apachectl start`, which ultimately activates a launchd job under the name `org.apache.httpd`.
In the context of system security, launchd is also integrated with the more modern macOS security architecture, including sandboxing and permission management. Although Docker Desktop on macOS makes limited use of launchd, it does require specific configurations that are made possible through system-level access – access that ultimately also depends on the permissions that launchd grants to certain processes.
launchd is therefore more than an init system: it is an integrated solution for system automation, efficiency, and security. It is part of the evolutionary line of macOS as a modern Unix-derived operating system, and remains to this day the backbone of system management on Apple's desktop platform.