C.W.K.
Stream
Lesson 08 of 10 · published

System Services (brew services, launchctl)

~10 min · services, launchctl, brew

Level 0Window Tourist
0 XP0/95 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

Long-running processes that boot with the Mac

Web servers, databases, message brokers — they need to start when the machine boots and restart on crash. macOS uses launchd to manage them. Two convenient front ends sit on top:

  • brew services — for tools installed via Homebrew.
  • launchctl — the raw command for any plist.

brew services

brew install postgresql@16
brew services start postgresql@16
brew services list
brew services stop postgresql@16
brew services restart postgresql@16
# Run without auto-start at login
brew services run postgresql@16

Behind the scenes brew writes a LaunchAgent plist into ~/Library/LaunchAgents/ and loads it.

launchctl directly

# See what's loaded for your user
launchctl list | grep -v com.apple
# Bootstrap (load) a plist
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/com.me.svc.plist
# Bootout (unload)
launchctl bootout gui/$UID/com.me.svc
# Restart cleanly
launchctl kickstart -k gui/$UID/com.me.svc

LaunchAgent vs LaunchDaemon

  • LaunchAgent — runs as your user when you log in. Lives under ~/Library/LaunchAgents/ or /Library/LaunchAgents/.
  • LaunchDaemon — runs as root at boot, before any user logs in. Lives under /Library/LaunchDaemons/.

For Pippa's pippa serve, a LaunchAgent is enough — it runs as you, after login. Don't reach for LaunchDaemons unless you need root and a no-user-required start.

Logs

The plist's StandardOutPath and StandardErrorPath tell launchd where to send output. Without them, output is dropped. Always set them when debugging.

Code

brew services workflow·bash
brew install redis
brew services start redis
brew services list
redis-cli ping     # PONG
brew services stop redis

External links

Exercise

If you have postgres or redis installed via brew, run brew services list. Start one, run a tiny client check (redis-cli ping, psql -l), stop it. Then launchctl list | grep -v com.apple | head to see launchd entries.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.