detect-memory: raise PHP_WORKER_ESTIMATE_MB default 60→128
All checks were successful
Cloud Apache Container / Build-and-Push (74) (push) Successful in 1m22s
Cloud Apache Container / Build-and-Push (80) (push) Successful in 1m20s
Cloud Apache Container / Build-and-Push (81) (push) Successful in 1m15s
Cloud Apache Container / Build-and-Push (82) (push) Successful in 1m19s
Cloud Apache Container / Build-and-Push (83) (push) Successful in 1m17s
Cloud Apache Container / Build-and-Push (84) (push) Successful in 1m25s
Cloud Apache Container / Build-and-Push (85) (push) Successful in 1m16s
Cloud Apache Container / Build-FPM-Images (74) (push) Successful in 1m17s
Cloud Apache Container / Build-FPM-Images (80) (push) Successful in 1m14s
Cloud Apache Container / Build-FPM-Images (81) (push) Successful in 1m21s
Cloud Apache Container / Build-FPM-Images (82) (push) Successful in 1m16s
Cloud Apache Container / Build-FPM-Images (83) (push) Successful in 1m15s
Cloud Apache Container / Build-FPM-Images (84) (push) Successful in 1m23s
Cloud Apache Container / Build-FPM-Images (85) (push) Successful in 1m15s
Cloud Apache Container / Build-Shared-httpd (push) Successful in 27s

The 60 MB worker estimate was optimistic for plugin-heavy WordPress
and WooCommerce stacks. Concrete measurement on alphaone 2026-06-01:

  Container memory : 1024 MiB (later 2048 MiB)
  Pool sized by formula : pm.max_children = (1024-100)/60 = 15
  Actual per-worker RSS : ~193 MB (anon+file+shmem from kernel OOM dumps)
  Worst-case peak       : 15 × 193 MB ≈ 2.9 GB

That math put traffic-burst peak demand well over the container cap,
producing 1,586 cumulative oom_kills across alphaone's two containers
over 18 days and intermittent fork-starvation for unrelated tenants
on the host.

128 MB is a more realistic baseline: closer to actual WP+Woo+page-
builder worker footprint, still conservative enough that lighter
sites continue to get reasonable concurrency. The matrix at common
container tiers:

  Tier (MiB)  | old children | new children | new peak demand
  256         | 2 (floored)  | 2 (floored)  | ~256 MB
  512         | 6            | 3            | ~384 MB
  768         | 11           | 5            | ~640 MB
  1024        | 15           | 7            | ~896 MB
  2048        | 15 (capped*) | 15           | ~1.9 GB
  (* old formula returned 32 at 2 GiB but production containers were
    booted at lower tiers and never recalculated; see whp01 audit.)

Existing containers keep their boot-time pm.max_children until they
are recreated — this change only affects new containers. Customers
or operators can override per-container via FPM_MAX_CHILDREN env.
This commit is contained in:
Claude Code
2026-06-01 08:23:09 -07:00
parent d5d027c0ab
commit 1756d496e5

View File

@@ -69,7 +69,15 @@ esac
# --- PHP-FPM parameters (skipped for httpd_only) ---
if [ "$CONTAINER_ROLE" != "httpd_only" ]; then
PHP_WORKER_ESTIMATE_MB=${PHP_WORKER_ESTIMATE_MB:-60}
# PHP_WORKER_ESTIMATE_MB sizes the divisor for pm.max_children. The
# previous default of 60 was optimistic for modern Woo/Elementor stacks:
# the alphaone 2026-06-01 incident measured ~193 MB resident per worker
# against the 60 MB assumption, and 15 calculated children put peak
# demand (15 * 193 = 2.9 GB) over the 1-2 GiB container cap. 128 lands
# closer to plugin-heavy WP reality while remaining conservative for
# leaner sites. Customers can still override via the FPM_MAX_CHILDREN
# env var on the container if a different shape is justified.
PHP_WORKER_ESTIMATE_MB=${PHP_WORKER_ESTIMATE_MB:-128}
calc_max_children=$((PHP_BUDGET_MB / PHP_WORKER_ESTIMATE_MB))
# Floor at 2, cap at 50