Skip to content

fix: cap recursive inotify watches to prevent multi-GB memory growth#12116

Draft
warp-dev-github-integration[bot] wants to merge 1 commit into
masterfrom
fix/inotify-watch-memory-growth
Draft

fix: cap recursive inotify watches to prevent multi-GB memory growth#12116
warp-dev-github-integration[bot] wants to merge 1 commit into
masterfrom
fix/inotify-watch-memory-growth

Conversation

@warp-dev-github-integration
Copy link
Copy Markdown

Description

Cap the number of recursive inotify watches to prevent multi-GB memory growth on Linux.

Root cause: On Linux, the notify crate's inotify backend creates one watch descriptor per directory when using RecursiveMode::Recursive. For users with very large directory trees (deep node_modules, monorepos with hundreds of thousands of subdirectories), the internal HashMap<PathBuf, (WatchDescriptor, ...)> and associated Vec<u8> event buffers grow to 10+ GB, triggering Sentry memory alerts.

Heap profile evidence (event ff1830282d61):

Fix: Add a bounded directory count check (estimate_directory_count) before registering recursive watches. When a directory tree exceeds 100,000 subdirectories, the watcher falls back to RecursiveMode::NonRecursive to prevent excessive memory usage. The check uses walkdir with early termination so it doesn't traverse the entire tree.

Trade-off: Directories exceeding the threshold will only have top-level change detection (new files/dirs created or deleted directly in the root). Subdirectory changes won't trigger events. This is acceptable because the alternative is a 10+ GB memory spike that can OOM the process.

Linked Issue

Testing

  • cargo check -p watcher passes
  • cargo clippy -p watcher -- -D warnings passes
  • I have manually tested my changes locally with ./script/run

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

Conversation: https://staging.warp.dev/conversation/6007cbda-5c59-4092-b92c-d1fd7b9070a2
Run: https://oz.staging.warp.dev/runs/019e8b03-c70c-7da9-91e5-8913a6960343
This PR was generated with Oz.

On Linux, the notify crate's inotify backend creates one watch descriptor per
directory when using RecursiveMode::Recursive. For users with very large
directory trees (deep node_modules, monorepos), this causes the internal
HashMap and event buffers to grow to 10+ GB.

Add a bounded directory count check before registering recursive watches.
When a directory tree exceeds 100,000 subdirectories, the watcher falls back
to RecursiveMode::NonRecursive to prevent excessive memory usage.

Sentry issue: https://sentry.io/organizations/warpdotdev/issues/7259255054/
Root cause: notify::inotify::EventLoop::add_watch HashMap + Vec<u8> growth
(98.4% of 11.22 GB sampled heap in heap-profile.pb)

Co-Authored-By: Oz <oz-agent@warp.dev>
@cla-bot cla-bot Bot added the cla-signed label Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant