From 24658892c344319647dd49230e313435a70c034a Mon Sep 17 00:00:00 2001 From: Raghu Betina Date: Sun, 17 May 2026 18:47:32 -0400 Subject: [PATCH] Run Puma in single mode on Render free tier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WEB_CONCURRENCY=1 was set with the comment "Single worker to fit in 512MB", but that's the opposite of what it does: WEB_CONCURRENCY is the *worker* count Puma forks *in addition to* the master, so =1 actually means master + 1 worker = 2 Puma processes in cluster mode. Adding SOLID_QUEUE_IN_PUMA on top spawns four more subprocesses (supervisor, dispatcher, worker, scheduler). That's six Ruby processes in one 512MB container: master (~150MB) + worker (~150MB) + 4 SQ procs (~80MB each) ≈ 620MB → exceeds 512MB → OOM-loop Setting WEB_CONCURRENCY=0 drops Puma into single mode (master serves HTTP directly, no fork). That saves the ~150MB worker process and brings steady-state RSS under the cap. With only one Puma process there's no throughput benefit from cluster mode anyway — the worker is pure overhead. Hit by: - raghubetina/aplace running an identical config (Puma cluster + SOLID_QUEUE_IN_PUMA on Render Starter, also 512MB). The deploy appeared green but the container OOM-restarted every ~90s, serving HTTP 502 most of the time. Fixed by the same change. Any student project on this template that adds memory-hungry gems (image_processing, ML/embedding clients, etc.) will hit the same wall — best to fix it in the template before more forks inherit the bug. --- render.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/render.yaml b/render.yaml index 56e817e..d503e24 100644 --- a/render.yaml +++ b/render.yaml @@ -11,7 +11,12 @@ services: sync: false # Memory optimization for Render free tier (512MB RAM) - key: WEB_CONCURRENCY - value: "1" # Single worker to fit in 512MB + # 0 = Puma single mode (the master process serves HTTP directly, + # no forked workers). Any value ≥ 1 spawns that many worker + # processes on top of the master, each adding ~150MB. Combined + # with the four Solid Queue subprocesses below, anything above + # single mode OOMs on the 512MB free tier. + value: "0" - key: RAILS_MAX_THREADS value: "3" # Cap threads to reduce memory - key: MALLOC_ARENA_MAX