Cap maxWorkers and bump heap to bound Fantom Metro memory (#56529)#56529
Closed
rubennorte wants to merge 1 commit into
Closed
Cap maxWorkers and bump heap to bound Fantom Metro memory (#56529)#56529rubennorte wants to merge 1 commit into
rubennorte wants to merge 1 commit into
Conversation
|
@rubennorte has exported this pull request. If you are a Meta employee, you can view the originating Diff in D101791795. |
rubennorte
added a commit
to rubennorte/react-native
that referenced
this pull request
Apr 21, 2026
Summary: Fantom runs every test through a single shared Metro server (started in `globalSetup`). Jest's default `maxWorkers` is `numCpus - 1`, so on a high-core box (e.g. 176 CPUs) ~175 workers fire bundle requests at Metro concurrently. Each in-flight request makes Metro materialize a full dependency `Graph` (transformed modules, source maps, inverse-deps, file-watcher subscription), which is hundreds of MB. The per-test `DELETE` eviction added in D101652820 only releases that memory after the bundle response completes, so the simultaneous in-flight set still blows past the previous Node `--max-old-space-size=8192` ceiling in `scripts/fantom.sh` — the Metro process aborts with `FATAL ERROR: Ineffective mark-compacts near heap limit` after just a handful of test suites. Two coordinated changes that balance throughput and safety: - `scripts/fantom.sh`: bump the Node heap from 8 GB to 16 GB so we have headroom over the observed steady-state peak. - `private/react-native-fantom/config/jest.config.js`: cap `maxWorkers` at `min(numCpus - 1, 16)`. With 8 workers the heap peaked at ~3 GB (~400 MB / worker), so 16 workers fits comfortably under a 16 GB cap with ~40% headroom. This is intentionally a balance rather than a hard worker cap — bumping the heap alone would still leave 100+ in-flight graphs racing GC, and capping workers alone leaves throughput on the table on big machines. Changelog: [Internal] Differential Revision: D101791795
477f262 to
d6c9318
Compare
Summary: Pull Request resolved: react#56529 Fantom runs every test through a single shared Metro server (started in `globalSetup`). Jest's default `maxWorkers` is `numCpus - 1`, so on a high-core box (e.g. 176 CPUs) ~175 workers fire bundle requests at Metro concurrently. Each in-flight request makes Metro materialize a full dependency `Graph` (transformed modules, source maps, inverse-deps, file-watcher subscription), which is hundreds of MB. The per-test `DELETE` eviction added in D101652820 only releases that memory after the bundle response completes, so the simultaneous in-flight set still blows past the previous Node `--max-old-space-size=8192` ceiling in `scripts/fantom.sh` — the Metro process aborts with `FATAL ERROR: Ineffective mark-compacts near heap limit` after just a handful of test suites. Two coordinated changes that balance throughput and safety: - `scripts/fantom.sh`: bump the Node heap from 8 GB to 16 GB so we have headroom over the observed steady-state peak. - `private/react-native-fantom/config/jest.config.js`: cap `maxWorkers` at `min(numCpus - 1, 16)`. With 8 workers the heap peaked at ~3 GB (~400 MB / worker), so 16 workers fits comfortably under a 16 GB cap with ~40% headroom. This is intentionally a balance rather than a hard worker cap — bumping the heap alone would still leave 100+ in-flight graphs racing GC, and capping workers alone leaves throughput on the table on big machines. Changelog: [Internal] Reviewed By: andrewdacenko Differential Revision: D101791795
d6c9318 to
9dc5a62
Compare
Collaborator
|
This pull request was successfully merged by @rubennorte in 0f9b8e4 When will my fix make it into a release? | How to file a pick request? |
|
This pull request has been merged in 0f9b8e4. |
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.
Summary:
Fantom runs every test through a single shared Metro server (started in
globalSetup). Jest's defaultmaxWorkersisnumCpus - 1, so on ahigh-core box (e.g. 176 CPUs) ~175 workers fire bundle requests at Metro
concurrently. Each in-flight request makes Metro materialize a full
dependency
Graph(transformed modules, source maps, inverse-deps,file-watcher subscription), which is hundreds of MB.
The per-test
DELETEeviction added in D101652820 only releases thatmemory after the bundle response completes, so the simultaneous in-flight
set still blows past the previous Node
--max-old-space-size=8192ceilingin
scripts/fantom.sh— the Metro process aborts withFATAL ERROR: Ineffective mark-compacts near heap limitafter just ahandful of test suites.
Two coordinated changes that balance throughput and safety:
scripts/fantom.sh: bump the Node heap from 8 GB to 16 GB so we haveheadroom over the observed steady-state peak.
private/react-native-fantom/config/jest.config.js: capmaxWorkersat
min(numCpus - 1, 16). With 8 workers the heap peaked at ~3 GB(~400 MB / worker), so 16 workers fits comfortably under a 16 GB cap
with ~40% headroom.
This is intentionally a balance rather than a hard worker cap — bumping
the heap alone would still leave 100+ in-flight graphs racing GC, and
capping workers alone leaves throughput on the table on big machines.
Changelog: [Internal]
Reviewed By: andrewdacenko
Differential Revision: D101791795