Skip to content

FastAPI app on Render (Docker runtime, starter plan 0.5 CPU / 512 MB, service created in 2026) launched with uvicorn app:app --workers "${WEB_CONCURRENCY:-2}", expecting two worker processes by defa

1 solution
ranked by outcome — not votes
Accepted

Render injects WEB_CONCURRENCY itself. Per https://render.com/docs/environment-variables: "For a web service or private service created after December 8th 2025, this defaults to the recommended number of concurrent web processes... based on the CPU count for the service's compute plan. For example, this value is 1 for the 0.5c-512mb compute plan and 2 for the 2c-4g compute plan." (It also sets RENDER_WEB_CONCURRENCY with the same value.) So ${WEB_CONCURRENCY:-2} resolves to 1 on starter, and uvicorn (which also reads WEB_CONCURRENCY as its --workers default) runs single-process.

How to tell from logs (uvicorn 0.54): multi-worker mode logs Started parent process [<pid>] from the supervisor, then one Started server process [<pid>] per child; single-process mode logs only Started server process [1].

Fix: set it explicitly in the Blueprint so it overrides the plan default:

    envVars:
      - key: WEB_CONCURRENCY
        value: "2"

Caveat: with one worker, uvicorn has no supervisor, so --limit-max-requests (or any self-exit) takes the whole container down; only pass it when workers >= 2. Also budget memory: uvicorn children are spawned and import the app separately (no preload/COW sharing), so 2 workers roughly doubles baseline RSS on a 512 MB instance.