Repository navigation
deps: libuv: cherry-pick fsevents path cleanup - #67293
Open
fatihguzeldev wants to merge 1 commit into
Open
fatihguzeldev wants to merge 1 commit into
fatihguzeldev wants to merge 1 commit into
Conversation
Release temporary path allocations after each FSEventStream rebuild. Include the upstream regression test for allocation balance and event delivery. Refs: libuv/libuv#5283 Fixes: nodejs#67284 Signed-off-by: Fatih Güzel <fatihguzeldev@gmail.com>
Collaborator
|
Review requested:
|
Brooooooklyn
added a commit
to oxc-project/oxc-node
that referenced
this pull request
Nov 12, 2026
…ced (#906) (#921) Closes #906. ## Cause On macOS, libuv uses one FSEvents stream for all directory watches. Every `fs.watch` open or close rebuilds that stream and leaks memory for every watched folder (libuv/libuv#5283, not in a Node release yet; nodejs/node#67293). `oxnode watch` reopened a folder's watch whenever the folder got a new inode, so replacing folders made memory grow without limit. ## Fix (macOS only) FSEvents watches the path, not the inode, so a folder's watch now follows its path: ``` folder replaced, same real path → look at its files again, no reopen folder missing → check its files once, keep the watch for `linger` (60 s) watch no longer needed → keep it for `linger`, then close new real path (link moved) → reopen ``` Linux and Windows behave as before (`linger` is 0 there, and a new inode still means a new watch). ## Results The issue's repro: 400 folders, each replaced with `mv`/`mkdir`/`mv`/`rmdir` every round, measured with `vmmap`. | | footprint | watches opened | |---|---|---| | main, Node 26, 5 rounds | 25 → 131 MB, still growing | 401 → 2915 | | this PR, Node 26, 10 rounds | about 36–40 MB, flat | 401 → 402 | Node 22 and 24 give the same shape: on main memory grows to 117–143 MB, with this PR it stays flat. ## Tests New macOS cases in `watch-units.spec.ts` use a fake `fs.watch`, so they run on every OS: - a folder replaced by `rm -rf` + `mkdir` or by a rename keeps its watch - a missing folder: its files are reported gone, its watch closes after `linger`, and the parent's watch closes once the folder is back - a parent renamed away, and a walked folder removed with its subfolders: the files in them are reported gone - a watch reached through a link that is repointed, or a folder moved away and then linked back: the watch is reopened - a watch no longer needed lingers, serves again, then closes There is also one test on real FSEvents (macOS only): 40 folders replaced 3 times open no new watch. ## Known trade-off A folder deleted for good keeps its watch for 60 s, where before it closed at the next sync. This only adds cost when a tool keeps creating and deleting new folders inside an `--include` root. The extra watches are about rate × 60 s, and their number stops growing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
cherry-picks libuv/libuv#5283 to fix the
macos fs.watch() memory leak. the fix is merged upstream but hasn't
been released yet.
fixes: #67284