Skip to content

--web has a fixed per-request allocation ceiling (~27KB body for a highlighted page) independent of --heap-size #515

Description

@mirchaemanuel

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions