Emacs on macOS with higher max open files
When Emacs runs lots of subprocesses (LSP servers, file watchers, TRAMP, Magit, terminals), the default macOS descriptor limits (1024) can surface as “Too many open files.” A proven mitigation is to compile Emacs with larger descriptor set size and a Darwin-specific define: -DFD_SETSIZE=10000 -DDARWIN_UNLIMITED_SELECT
[1].
This post shows how to make that build reproducible with a small, local Homebrew tap that carries a lightly patched emacs
formula.
What you need to do:
- Create a local tap to host your customized
emacs
formula. - Patch the formula to append
CFLAGS="-DFD_SETSIZE=10000 -DDARWIN_UNLIMITED_SELECT"
during build [1]. - Install from your tap now, and upgrade later with the same commands.
Prerequisites:
- Homebrew set up on macOS.
- Command Line Tools for Xcode:
xcode-select --install
(if you haven’t already).
Create a local tap
Initialize an empty tap repository you control:
brew tap-new $(id -u)/local
Seed your formula
brew extract emacs $(id -u)/local
This creates $(brew --repository)/Library/Taps/$(id -u)/homebrew-local/Formula/emacs.rb
for you to modify.
Patch the formula to raise FD limits
Open your tap’s emacs.rb
(you’ll need existing emacs installed for this to work, otherwise just find the formula it in the path above and edit it):
brew edit $(id -u)/local/emacs
Inside def install
, append the CFLAGS
before ./configure
step (this is how it looks like as of emacs@30.2
):
def install
# ...
ENV.append "CFLAGS", "-DFD_SETSIZE=1048576 -DDARWIN_UNLIMITED_SELECT"
system "./configure", *args
system "make"
system "make", "install"
# ...
end
Install from your tap
brew install $(id -u)/local/emacs
Verify the build behaves as expected
Launch Emacs and check the max open files:
M-! ulimit -n RET