Homebrew’s services subcommand isn’t just for keeping your development tools running; it’s a full-fledged system for managing background processes on macOS, treating them like proper system services.
Let’s say you’ve installed something with Homebrew that you want to run in the background, like a database or a local web server, and you want to control it like a system daemon.
Here’s how you can interact with Homebrew services:
First, you need to know what services are available. You can list all services that Homebrew knows about, whether they’re currently running or not:
brew services list
This command will output a table showing the name of the service, its status (e.g., started, stopped, none), and the user it’s running as.
To start a service:
brew services start <formula_name>
For instance, to start the PostgreSQL database:
brew services start postgresql
When you start a service this way, Homebrew sets it up to launch automatically when you log into your macOS user account. It creates a launchd plist file in ~/Library/LaunchAgents/ and registers it with launchd, the macOS system service manager.
To stop a service:
brew services stop <formula_name>
If you wanted to stop PostgreSQL:
brew services stop postgresql
Stopping a service not only terminates the running process but also prevents it from automatically starting the next time you log in.
Restarting is a common operation, and Homebrew provides a direct command for it:
brew services restart <formula_name>
This is equivalent to running brew services stop <formula_name> followed immediately by brew services start <formula_name>, but it’s a single, convenient command. To restart PostgreSQL:
brew services restart postgresql
If you want to ensure a service is running and start it if it’s not, you can use the start command. Homebrew is smart enough not to try starting a service that’s already running.
Conversely, if you want to ensure a service is stopped, you can use the stop command.
Sometimes, you might want to change how a service is managed. For example, to stop a service from automatically starting on login, you can use the --disable flag with the start command. This will start the service now but won’t set it up to launch on future logins.
brew services start --disable <formula_name>
To re-enable automatic startup for a service that was previously disabled:
brew services start <formula_name>
This will start the service and ensure it launches on subsequent logins.
You can also manage all services at once. To stop all Homebrew services:
brew services stop --all
And to start all services that are configured to run automatically:
brew services start --all
Homebrew’s services subcommand leverages launchd, macOS’s native daemon management system. When you use brew services start, Homebrew generates a .plist file in ~/Library/LaunchAgents/ (for user-specific services) or /Library/LaunchDaemons/ (for system-wide services, though Homebrew primarily uses LaunchAgents). This .plist file contains instructions for launchd, telling it when and how to run your Homebrew-installed program. The brew services list command queries launchd to determine the status of these managed services.
The true power of brew services lies in its ability to integrate with launchd’s more advanced features, such as automatic restart policies on crash or system reboot, though these are often configured by the formula itself. You can, however, manually edit the generated .plist files in ~/Library/LaunchAgents/ to fine-tune these behaviors if needed, though this is rarely necessary for typical use cases.
Understanding that brew services is a wrapper around launchd is key. If a service isn’t starting correctly, checking launchd’s logs (often via log stream --predicate 'process == "launchd"' or by looking at Console.app) can provide deeper insights than Homebrew itself might offer.
The next step after mastering service management is understanding how to configure the services themselves, often through configuration files specific to the installed formula.