#!/usr/bin/env bash ## detect-memory-litespeed.sh — sibling to detect-memory.sh. ## Computes LSAPI_CHILDREN + extprocessor memSoftLimit/memHardLimit from ## container memory cap. Sourced by entrypoint-litespeed.sh. ## ---- container memory detection (mirrors detect-memory.sh) ---- CONTAINER_MEMORY_BYTES="" if [ -f /sys/fs/cgroup/memory.max ]; then val=$(cat /sys/fs/cgroup/memory.max 2>/dev/null) if [ "$val" != "max" ] && [ -n "$val" ]; then CONTAINER_MEMORY_BYTES=$val fi fi if [ -z "$CONTAINER_MEMORY_BYTES" ] && [ -f /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then val=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes 2>/dev/null) if [ -n "$val" ] && [ "$val" -lt 8589934592000 ] 2>/dev/null; then CONTAINER_MEMORY_BYTES=$val fi fi if [ -z "$CONTAINER_MEMORY_BYTES" ] && [ -f /proc/meminfo ]; then mem_kb=$(awk '/^MemTotal:/ {print $2}' /proc/meminfo) if [ -n "$mem_kb" ]; then CONTAINER_MEMORY_BYTES=$((mem_kb * 1024)) fi fi if [ -z "$CONTAINER_MEMORY_BYTES" ]; then CONTAINER_MEMORY_BYTES=$((512 * 1024 * 1024)) fi CONTAINER_MEMORY_MB=$((CONTAINER_MEMORY_BYTES / 1024 / 1024)) ## ---- budget split (LSAPI workers get the lion's share) ---- OS_RESERVE_MB=50 OLS_RESERVE_MB=40 # OpenLiteSpeed daemon footprint DEV_OVERHEAD_MB=0 if [ "${environment:-PROD}" = "DEV" ]; then DEV_OVERHEAD_MB=125 fi AVAILABLE_MB=$((CONTAINER_MEMORY_MB - OS_RESERVE_MB - OLS_RESERVE_MB - DEV_OVERHEAD_MB)) if [ "$AVAILABLE_MB" -lt 60 ]; then AVAILABLE_MB=60 fi ## ---- LSAPI children (analogous to PHP_FPM_MAX_CHILDREN) ---- ## Per the 2026-06-02 cac-litespeed memory-sizing finding (vantagehealth ## OOM-spawn loop at 512 MB cap): each lsphp worker carries ~115 MB ## shmem-rss which is RSS-accounted per worker (vs cac-fpm's COW-shared ## fork model). Real-world worker budget ≈ 115 MB shmem + ~50-100 MB anon ## that scales with workload. 115 MB is the safe per-worker estimate for ## the divisor; floor at 2, cap at 50. ## ## Sub-512 MB containers are unsafe for dynamic WP on OLS per the memory ## note — the floor of 2 workers still applies but it'll be cap-marginal. LSPHP_WORKER_ESTIMATE_MB=${LSPHP_WORKER_ESTIMATE_MB:-115} calc_lsapi_children=$((AVAILABLE_MB / LSPHP_WORKER_ESTIMATE_MB)) if [ "$calc_lsapi_children" -lt 2 ]; then calc_lsapi_children=2 fi if [ "$calc_lsapi_children" -gt 50 ]; then calc_lsapi_children=50 fi ## Per-site override knobs — site-pool-env.php still passes FPM_MAX_CHILDREN ## for backward compat, so prefer LSAPI_CHILDREN if set, else FPM_MAX_CHILDREN, ## else the calculated value. LSAPI_CHILDREN=${LSAPI_CHILDREN:-${FPM_MAX_CHILDREN:-$calc_lsapi_children}} ## Per-worker mem limits (RLIMIT_AS) live in httpd_config.tpl now as ## hard-coded 1024M soft / 1500M hard — those values comfortably fit ## typical Divi/WooCommerce VSZ (~280-365 MB) while still catching a ## true runaway script. Cgroup remains the real backstop. The earlier ## AVAILABLE/CHILDREN formula was killing legitimate workers because ## it conflated VSZ (RLIMIT_AS) with RSS-budget arithmetic. export CONTAINER_MEMORY_MB LSAPI_CHILDREN