Summary
Under elephc --web, a request handler that allocates/emits more than
roughly 100 KB total, or a real page whose per-request working set (multiple
copies of a body through find → rebox → highlight → render → layout) exceeds
~27 KB of source body, kills the worker (empty response, usually with no
"heap memory exhausted" message in the log at all). --heap-size does not
help — the ceiling is identical at 8 MB and 64 MB, and gets worse at
256 MB (crashes even at ~50 KB in the minimal repro), consistent with
workers dying on startup at 256 MB noted elsewhere. This looks like a fixed
per-request allocation ceiling in the --web runtime, independent of the
configured heap size.
Environment
- elephc v0.26.0 (release, commit
892ff162), macOS ARM64
- PHP (
php -S): unaffected at these sizes
Minimal reproduction
Handler using str_repeat + htmlspecialchars + implode + echo:
responds fine up to roughly 50–80 KB of generated output, dies (empty
response) above that.
Real-world bisection: syntax-highlighted paste page
A pastebin's syntax-highlighted view (find() → re-box → highlight()
[escape + tokenize] → renderPaste() → layout) makes several copies of the
paste body per request, so its effective ceiling is much lower than the
minimal repro's:
- 100-line PHP paste, 4159-byte body: served OK by the native view
- 110-line PHP paste, 4619-byte body: worker dies (empty response)
- Body-size bisection on a single worker: 26 KB OK, 28 KB crash
--heap-size does not move this ceiling: identical at 8 MB and 64 MB, and
worse at 256 MB (crashes even at ~50 KB in the plain str_repeat repro —
consistent with the separately-observed fact that workers die on startup
altogether at a 256 MB heap size). The ceiling is also independent of how
the output string is built: reproduced identically with an older
Highlighter implementation that used a .= accumulator instead of
array+implode.
Impact
Pastes above ~27 KB can be created and read via a raw/unprocessed view
(which serves up to ~50 KB), but the syntax-highlighted view crashes the
worker for the same content. An end-to-end regression fixture uses a 20 KB
paste specifically to stay under this ceiling.
Expected
A single request's total allocation working set on the order of tens of KB
should not crash the worker regardless of --heap-size; if there is an
intentional per-request budget it should fail gracefully (matching, e.g.,
the --max-body-size 413 behavior on the request side) rather than
producing a bare empty response.
Notes
Found building a pastebin single-binary app (--web) for the Discord
contest. The app's syntax-highlighted paste view is the real-world trigger;
the str_repeat/htmlspecialchars handler above isolates the ceiling
without any app-specific code.
Summary
Under
elephc --web, a request handler that allocates/emits more thanroughly 100 KB total, or a real page whose per-request working set (multiple
copies of a body through find → rebox → highlight → render → layout) exceeds
~27 KB of source body, kills the worker (empty response, usually with no
"heap memory exhausted" message in the log at all).
--heap-sizedoes nothelp — the ceiling is identical at 8 MB and 64 MB, and gets worse at
256 MB (crashes even at ~50 KB in the minimal repro), consistent with
workers dying on startup at 256 MB noted elsewhere. This looks like a fixed
per-request allocation ceiling in the
--webruntime, independent of theconfigured heap size.
Environment
892ff162), macOS ARM64php -S): unaffected at these sizesMinimal reproduction
Handler using
str_repeat+htmlspecialchars+implode+echo:responds fine up to roughly 50–80 KB of generated output, dies (empty
response) above that.
Real-world bisection: syntax-highlighted paste page
A pastebin's syntax-highlighted view (
find()→ re-box →highlight()[escape + tokenize] →
renderPaste()→ layout) makes several copies of thepaste body per request, so its effective ceiling is much lower than the
minimal repro's:
--heap-sizedoes not move this ceiling: identical at 8 MB and 64 MB, andworse at 256 MB (crashes even at ~50 KB in the plain
str_repeatrepro —consistent with the separately-observed fact that workers die on startup
altogether at a 256 MB heap size). The ceiling is also independent of how
the output string is built: reproduced identically with an older
Highlighterimplementation that used a.=accumulator instead ofarray+
implode.Impact
Pastes above ~27 KB can be created and read via a raw/unprocessed view
(which serves up to ~50 KB), but the syntax-highlighted view crashes the
worker for the same content. An end-to-end regression fixture uses a 20 KB
paste specifically to stay under this ceiling.
Expected
A single request's total allocation working set on the order of tens of KB
should not crash the worker regardless of
--heap-size; if there is anintentional per-request budget it should fail gracefully (matching, e.g.,
the
--max-body-size413 behavior on the request side) rather thanproducing a bare empty response.
Notes
Found building a pastebin single-binary app (
--web) for the Discordcontest. The app's syntax-highlighted paste view is the real-world trigger;
the
str_repeat/htmlspecialcharshandler above isolates the ceilingwithout any app-specific code.