brew pin stops a formula from being upgraded when you run brew upgrade. It does not stop everything: the Homebrew manual warns that packages depending on newer versions of a pinned formula may fail, and that pinned casks with auto_updates true may update themselves outside Homebrew. Use pins sparingly and keep a review date.
What the manual says
From the Homebrew manual page:
- pin: prevents the specified package from being upgraded when issuing brew upgrade.
- unpin: allows it to be upgraded again.
- upgrade: upgrades outdated, unpinned packages. If you name a package, it upgrades only that, unless it is pinned.
The manual also warns that other packages which depend on newer versions of a pinned formula might not install or run correctly. And pinned casks with auto_updates true may update themselves outside Homebrew.
Where pinning helps
Pinning is a temporary tool for a specific problem: a newer version of a compiler, database client or CLI breaks your workflow and you need time to fix it. Pin, work around, then unpin.
brew pin postgresql@16
brew unpin postgresql@16
Where it hurts security
A pin freezes a patch level. If the pinned package has a security fix in a newer release, brew upgrade will not apply it. That is the exact situation patch management exists to prevent, so a pin is a risk acceptance, not a neutral setting.
The dependency warning cuts the other way too. A pinned formula can block upgrades of others that need its newer version, leaving a half-updated machine.
Casks that update themselves
Many GUI applications update through their own mechanism. The manual's note about auto_updates true means the cask can change without Homebrew involved, so a pin does not guarantee a stable version. If you need strict control, check the application's own update settings too, such as those covered in how to control VS Code updates across a team.
A sensible policy for developer laptops
| Case | Action |
|---|---|
| Routine tools | Upgrade weekly, no pins |
| A tool that broke on a new release | Pin with a ticket and a review date |
| Team needs identical versions | Use a versioned toolchain per project, not Homebrew pins |
| Self-updating app | Control through the app's own policy |
Keep a list of pins
Run brew list with the pinned filter occasionally, or record pins in your setup script, so they do not outlive their reason. A pin from last year is a forgotten decision.
Safeguard's asset discovery and dependency scanning help you see versions across projects, which is the visibility a pin tends to hide. Try a free scan at gold.safeguard.sh/scan.
Common mistakes
People pin to fix a one-off problem and then never unpin. Others pin a library without noticing it holds back tools that depend on a newer one. A third assumes a pin covers a self-updating app. Write each pin down with a reason and a date in your setup notes, and review the list when you review other exceptions.
Quick check
Does brew upgrade skip pinned formulae?
Yes. The manual says upgrade handles outdated, unpinned packages, and a named package is skipped if pinned.
Can a pinned cask still change?
Yes, if it has auto_updates true it may update itself outside Homebrew, per the manual.
Sources
Last reviewed: 19 October 2026.