Skip to content

macOS launchctl Complete Guide: A Powerful Tool for System Service Management ​

macOS launchctl system service management powerful tool diagram

launchctl is a macOS system service management tool used to load, unload, start, and stop Daemon processes (Daemons) and Agents (Agents). It is based on launchd The service management system is one of the core components of macOS.

If you are a macOS developer, operations personnel, or advanced user, master launchctl Allows you to better manage system services and automate tasks.

1. The relationship between launchd and launchctl ​

  • launchd: macOS's init system, responsible for loading services during system startup and managing background processes (similar to Linux's systemd).

  • launchctl: Command-line tool for use with launchd Interaction, management services.

2. launchd service type ​

TypeStorage locationExecution permissionPurpose
System Daemons/System/Library/LaunchDaemons/rootSystem-level background service
User Daemons/Library/LaunchDaemons/rootGlobal services installed by the administrator
System Agents/System/Library/LaunchAgents/Current userUser-level services provided by the system
User Agents~/Library/LaunchAgents/Current userUser-defined background tasks

3. launchctl Basic Usage ​

3.1 Loading/Unloading Service ​

bash
# Load service (do not start automatically)
launchctl load /path/to/plist

# Load and start immediately (recommended method, macOS 10.10+)
launchctl bootstrap gui/$UID /path/to/plist

# Older versions of macOS use the -w parameter
launchctl load -w /path/to/plist

# Uninstall service
launchctl unload /path/to/plist
launchctl bootout gui/$UID /path/to/plist    # macOS 10.10+

3.2 Start/Stop Service ​

bash
# Start the service (must be loaded first)
launchctl start com.example.service

# Stop service
launchctl stop com.example.service

3.3 Check service status ​

bash
# List all loaded services
launchctl list

# Check the status of a service
launchctl print gui/$UID/com.example.service

3.4 Debugging Service ​

bash
# View logs (in conjunction with the log command)
log stream --predicate 'sender == "com.example.service"'

# Run the service directly (to test whether the configuration is correct)
/path/to/your/daemon -f

4. Detailed Explanation of the plist Configuration File ​

launchd Service usage .plist(Property List) file definition, usually stored in the corresponding Service Catalog Middle.

Example: a simple plist file ​

xml
<?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.example.myapp</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/myapp</string>
        <string>--daemon</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/var/log/myapp.log</string>
    <key>StandardErrorPath</key>
    <string>/var/log/myapp.err</string>
</dict>
</plist>

Key configuration items description ​

ParametersExplanation
LabelService unique identifier (e.g.com.example.myapp)
ProgramArgumentsThe command to execute (array form)
RunAtLoadWhether to run immediately on load
KeepAliveAutomatically restart after crash
StartIntervalScheduled run interval (seconds)
StartCalendarIntervalCalendar scheduled run
StandardOutPathStandard output log path
StandardErrorPathError log path

4.1 Practical Case: APIServer Backend Service Configuration ​

The following is used in a real production environment launchd Configuration file, used to manage an API backend service:

xml
<?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>Description</key>
    <string>APIServer - Backend Service</string>
    <key>Disabled</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>flower.com.apiserver</string>
    <key>ProcessType</key>
    <string>Background</string>
    <key>ProgramArguments</key>
    <array>
      <string>/usr/local/bin/apiserver/apiserver.darwin.amd64</string>
      <string>--config-dir</string>
      <string>/usr/local/etc/apiserver</string>
      <string>--config-name</string>
      <string>config.yaml</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>/usr/local/var/log/apiserver.log</string>
    <key>StandardOutPath</key>
    <string>/usr/local/var/log/apiserver.log</string>
    <key>Version</key>
    <string>v0.1.0</string>
    <key>WorkingDirectory</key>
    <string>/usr/local/var</string>
  </dict>
</plist>

Configuration Item Interpretation ​

Configuration itemvalueExplanation
Labelflower.com.apiserverUnique service identifier, following the reverse domain name naming convention
DescriptionAPIServer - 后台服务Service description, for easy identification
ProgramArguments[/usr/local/bin/apiserver/..., --config-dir, ...]Complete command-line arguments, supporting passing the configuration file path
WorkingDirectory/usr/local/varSpecify the working directory for the service at runtime
KeepAlivetrueAutomatically restart the process when it exits abnormally to ensure high service availability.
RunAtLoadtrueStarts immediately after the service is loaded, suitable for automatic startup at boot scenarios.
ProcessTypeBackgroundMark it as a background process, and the system will give it an appropriate resource scheduling priority.
DisabledtrueDisabled by default; must be enabled manually (can be done via launchctl enable Enable)
StandardOutPath/StandardErrorPath/usr/local/var/log/apiserver.logMerge standard output and error output into the same log file for unified viewing.

Usage of this configuration file ​

bash
# 1. Place the plist file in the corresponding service directory
sudo cp flower.com.apiserver.plist /Library/LaunchDaemons/

# 2. Load and enable the service (Note: Disabled is true, so it needs to be enabled first)
sudo launchctl enable system/flower.com.apiserver
sudo launchctl bootstrap system /Library/LaunchDaemons/flower.com.apiserver.plist

# 3. Check service status
sudo launchctl print system/flower.com.apiserver

# 4. View service logs
tail -f /usr/local/var/log/apiserver.log

💡 Note

This service is a system-level daemon (System Daemon), and requires the use of sudo Permission management, and the configuration file should be stored in /Library/LaunchDaemons/ Under the directory.

5. Common real-world use cases ​

5.1 Boot Autostart Script ​

bash
# 1. Create a plist file
cat > ~/Library/LaunchAgents/com.example.myscript.plist <<EOF
<?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.example.myscript</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/zsh</string>
        <string>-c</string>
        <string>echo "Hello, launchd!" >> ~/mylog.txt</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
EOF

# 2. Load and start
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/com.example.myscript.plist

5.2 Scheduled Tasks (Alternative to cron) ​

xml
<!-- Run once every 1 hour -->
<key>StartInterval</key>
<integer>3600</integer>

<!-- or run at 2:00 AM every day -->
<key>StartCalendarInterval</key>
<dict>
    <key>Hour</key>
    <integer>2</integer>
    <key>Minute</key>
    <integer>0</integer>
</dict>

5.3 Managing Homebrew Services ​

bash
# Homebrew uses launchctl to manage services.
brew services list          # View Services
brew services start nginx   # Start
brew services stop nginx    # Stop

6. Common Issues and Debugging Tips ​

6.1 Difference between launchctl load and bootstrap ​

  • load(Old version) and bootstrap(New version) has similar functions, but bootstrap This is the recommended method (macOS 10.10+).

  • bootout Corresponding unload.

6.2 Permission Issues ​

  • System Daemons Need sudo:
bash
sudo launchctl load /Library/LaunchDaemons/com.example.service.plist
  • User Agents No root privileges required.

6.3 Debugging Tips ​

Check plist format:

bash
plutil -lint /path/to/plist

View service logs:

bash
tail -f /var/log/system.log

Force reload service (use with caution):

bash
sudo launchctl kickstart -k system/com.apple.audio.coreaudiod

7. Service Dependency Management ​

In some scenarios, you may need to ensure that when one service starts, another service is already running successfully. Regarding using in the macOS environment launchctl How to implement service dependencies when managing services, please refer to:Detailed explanation of launchctl service dependency configuration

8. Summary ​

  • launchctl is a macOS service management tool, based on launchd.

  • through .plist File definition service, supports Boot startup, scheduled tasks, process supervision.

  • Recommended to use bootstrap/bootout(macOS 10.10+)。

  • Pay attention during debugging Permissions, logs, plist syntax.

Master launchctl It can better manage system services and automation tasks, and is suitable for developers, operations and maintenance staff, and advanced users.

Further reading ​

Last updated on11/07/2026, 02:16 PM
@fishfinal | @fishfinals | [email protected]