brew services restart versus parallel version install for a small Homebrew service upgrade
0 reputation · 29 Jul 2023, 00:12 UTC
0 reputation · 29 Jul 2023, 00:12 UTC
Upgrading a small background service installed via Homebrew with no downtime window creates a decision between two documented Homebrew behaviors.
Homebrew installs formulae into versioned prefixes and exposes them through brew link symlinks. brew services manages launchd on macOS and systemd on Linux, and a restart is a stop followed by a start. Some software is available as versioned formulae that can be installed side by side under separate prefixes. Homebrew does not provide a built-in zero-downtime rolling upgrade for a single formula.
Versioned formulae are not available for every package, and changing the linked prefix or PATH while a process is running can leave running processes using the old binary while new processes use the new one. Service behavior and permissions also differ between macOS and Linux.
What determines whether a formula supports a parallel version installation? Can a service be switched to a new versioned prefix without first unlinking the currently linked version? Does brew services restart guarantee a stop before start across launchd and systemd configurations?
35275 reputation · 29 Jul 2023, 10:49 UTC
For a background service that you want to upgrade without a downtime window, you have two practical options:
brew services restart. This stops the current instance, then starts a new one using the upgraded binary.foo@2.3) if the maintainer has published one, then point the service to that prefix. This allows the old and new binaries to coexist, but you still need to stop the service before switching the symlink to avoid running a process that was started with a different binary.Homebrew does not provide an atomic, zero‑downtime mechanism for a single formula. The choice depends on whether a versioned formula is available for your package.
/usr/local/Cellar (or /opt/homebrew/Cellar) and exposes the executables through a single set of symlinks in /usr/local/bin (or /opt/homebrew/bin).brew services restart <formula> sends a stop signal to the launchd or systemd unit, waits for the process to exit, and then starts the unit again. The unit file points to the symlinked binary, so the new instance uses the upgraded executable.Because Homebrew keeps a single symlink for each binary, the system cannot automatically switch an already‑running service to a new binary without restarting it. If a versioned formula exists, you can install it to a separate prefix, but you still need to stop the service before updating the symlink that the unit file references.
Check for a versioned formula:
brew search <service-name> | grep '@'
If a versioned formula exists, install it:
brew install <service-name>@<version>
Verify the new prefix:
brew --prefix <service-name>@<version>
Switch the symlink (this is safe only after stopping the service):
brew services stop <service-name>
brew unlink <service-name>
brew link <service-name>@<version> --force
brew services start <service-name>
If no versioned formula exists, upgrade the current one:
brew upgrade <service-name>
brew services restart <service-name>
Does the service you are upgrading provide a versioned Homebrew formula (e.g., service@2.4)? Knowing this will determine whether the parallel‑install path is viable.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.