Skip to content

Fix/re2 wasm heap leak#210

Open
costateixeira wants to merge 3 commits into
HealthIntersections:mainfrom
costateixeira:fix/re2-wasm-heap-leak
Open

Fix/re2 wasm heap leak#210
costateixeira wants to merge 3 commits into
HealthIntersections:mainfrom
costateixeira:fix/re2-wasm-heap-leak

Conversation

@costateixeira
Copy link
Copy Markdown
Contributor

https://chat.fhir.org/#narrow/channel/179252-IG-creation/topic/crash.20tx.2Efhir.2Eorg.3F/with/594892934

re2-wasm has a fixed 16 MB WASM linear-memory heap with no real free():
every new RE2(pattern, flags) permanently consumes a few KB regardless of whether the JS object is later GC'd. After enough compiles the heap is full and any further call aborts with Cannot enlarge memory arrays to size 16781312 bytes (OOM).

Reproducer: compiling the same trivial pattern 2965 times in a loop is enough to OOM on a fresh Node process. In production tx.fhir.org hit this via repeated $validate-code calls against the IPS lab-observations ValueSet, whose LOINC CLASS regex filter is recompiled per call.

Cache compiled RE2 objects by (pattern, flags). Same pattern -> single compile -> single leak. Does not fix the underlying leak;
a proper fix is to replace re2-wasm with the native re2 package, which has real free() semantics.

@costateixeira costateixeira force-pushed the fix/re2-wasm-heap-leak branch from f3c848f to 119d46f Compare May 14, 2026 17:50
re2-wasm has a fixed 16 MB WASM linear-memory heap with no real free():
every `new RE2(pattern, flags)` permanently consumes a few KB regardless
of whether the JS object is later GC'd. After enough compiles the heap
is full and any further call aborts with `Cannot enlarge memory arrays
to size 16781312 bytes (OOM)`.

Reproducer: compiling the same trivial pattern 2965 times in a loop is
enough to OOM on a fresh Node process. In production tx.fhir.org hit
this via repeated $validate-code calls against the IPS lab-observations
ValueSet, whose LOINC `CLASS regex` filter is recompiled per call.

Cache compiled RE2 objects by (pattern, flags). Same pattern -> single
compile -> single leak. Does not fix the underlying leak; a proper fix
is to replace re2-wasm with the native `re2` package, which has real
free() semantics.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant