ADR-0024: Lower base PHP memory_limit and Emscripten INITIAL_MEMORY for browser WASM environments¶
Status¶
Proposed
Context¶
Moodle Playground runs a full Moodle site inside a browser using PHP compiled to WebAssembly via @php-wasm. All code and mutable state live in Emscripten's MEMFS (JavaScript heap) plus the WASM linear memory. The previous default memory_limit was 512M with no explicit Emscripten INITIAL_MEMORY constraint.
Moodle's own environment checker (docs.moodle.org) states a minimum of ~96M, with 128M frequently recommended and larger values only for heavy operations. WordPress Playground uses 256M by default.
Heavy operations (install, course restore, large plugin installs) already call raise_memory_limit(MEMORY_EXTRA).
Problem¶
A 512M base memory_limit (plus the Emscripten module's default heap reservation) leads to unnecessarily high peak memory usage in the browser, increasing OOM risk on memory-constrained devices and slowing cold-start allocation.
Decision drivers¶
- Reduce peak WASM + JS heap usage in the browser.
- Align with upstream Moodle recommendations and WP Playground practices.
- Preserve correctness for Moodle workloads via
raise_memory_limiton heavy paths. - Keep Emscripten heap growth explicit and bounded at start.
Options considered¶
Option 1: Keep 512M (status quo)¶
- Pros: No risk of hitting limits in edge cases.
- Cons: Wastes browser memory; contradicts the goal of lightweight playgrounds.
Option 2: Drop to 128M base¶
- Pros: Maximum memory savings.
- Cons: Riskier for Moodle's larger footprint + plugins + theme compilation without relying entirely on raises.
Option 3: 256M base + explicit INITIAL_MEMORY + ALLOW_MEMORY_GROWTH (chosen)¶
- Pros: Good balance per Moodle docs; significant reduction from 512M; Emscripten starts smaller and grows only as needed.
- Cons: Requires validation on real devices; some very large restores may still need the raise path.
Evidence¶
- Moodle docs: https://docs.moodle.org/502/en/admin/environment/php_setting/memory_limit (min ~96M, 128M commonly recommended).
- WP Playground source:
packages/php-wasm/universal/src/lib/php.tsusesmemory_limit=256M. - Existing
raise_memory_limit(MEMORY_EXTRA)calls insrc/runtime/bootstrap.js:349andsrc/blueprint/php/helpers.js:604. - Emscripten options passed via
loadWebRuntime(seesrc/runtime/php-loader.jsand WP'sload-runtime.ts). - Bundle already trimmed (ADR-0011); snapshot + localcache seeds reduce work.
Decision¶
We will:
- Set base memory_limit = "256M", post_max_size = "64M", upload_max_filesize = "64M" in createPhpIniEntries (and mirrored in lib/config-template.js and scripts/setup-local.sh).
- Pass emscriptenOptions: { INITIAL_MEMORY: 128 * 1024 * 1024, ALLOW_MEMORY_GROWTH: 1 } to both primary and provisioning loadWebRuntime calls.
- Continue using raise_memory_limit(MEMORY_EXTRA) for install/restore/blueprint heavy steps.
- Update opcache values modestly as part of the same tuning pass where appropriate (inert under file_cache_only).
Consequences¶
Positive¶
- Lower peak memory usage at boot and during normal navigation.
- Faster WASM instantiation (smaller initial heap).
- Better experience on mobile / low-RAM browsers.
- Still safe for Moodle because of explicit raises on heavy paths.
Negative¶
- Very large one-off operations may hit the limit until
raise_memory_limittakes effect. - Requires re-testing with real blueprints and course restores.
Neutral¶
- The opcache
memory_consumption/interned_strings_bufferknobs remain largely inert underfile_cache_only=1.
Risks¶
- Under-estimating memory needs of certain third-party plugins or very large restores in a single request. Mitigated by existing raise calls and the ability to tune per-blueprint if needed.
Validation¶
- Unit tests for
createPhpIniEntriescontinue to pass. - Manual verification in browser with
?debug=trueand memory profiling. - Existing e2e tests (including blueprint-perf and restore) exercise heavy paths.
- Revisit if we observe "Allowed memory size" errors in common scenarios not covered by raises.
Follow-up work¶
- Monitor real usage; consider a blueprint
runtime.memory_limitoverride if needed. - Re-evaluate once upstream @php-wasm offers better per-instance memory controls.
References¶
- https://docs.moodle.org/502/en/admin/environment/php_setting/memory_limit
- ADR-0004 (OPcache tuning)
- ADR-0011 (bundle trim and runtime tuning)
src/runtime/config-template.jssrc/runtime/php-loader.js- WordPress Playground
php.tsandload-runtime.ts