#15819·chatwoot

[PERF] Missing WEB_CONCURRENCY in .env.example leaves Puma in single-process mode, causing request starvation on multi-core servers

Author: md-riazCreated Sep 15, 2026Updated Sep 16, 2026
LabelsperformanceBug

Describe the bug

config/puma.rb is configured to support Puma clustered mode:

ruby
workers ENV.fetch('WEB_CONCURRENCY', 0)
preload_app!

However, WEB_CONCURRENCY is completely omitted from .env.example and default self-hosted environment templates.

Because it is missing from .env.example, almost all self-hosted administrators (across Docker and Linux VM deployments) leave this setting unset. Consequently, Puma defaults to workers = 0 (single-process mode with only 5 threads: RAILS_MAX_THREADS=5).

Under Ruby's Global VM Lock (GVL), any CPU-intensive operations (such as ActiveRecord serialization of message payloads, conversation metadata queries, or Ruby GC cycles taking 200–300ms) block the entire process. When multiple support agents are active or when webhooks (WhatsApp/Facebook/SMS) arrive simultaneously, the 5 threads become fully saturated, and all subsequent web requests queue up in Puma's backlog and time out (504 Gateway Timeout or >3000ms latency), even on servers with 4, 8, or 16 CPU cores.

To Reproduce

  1. Set up Chatwoot following the standard installation guide using .env.example.
  2. Notice that .env.example only specifies RAILS_MAX_THREADS=5 and never defines or mentions WEB_CONCURRENCY.
  3. Check running processes on a multi-core production server:
    bash
    ps aux | grep puma
    Only 1 single Puma process is running.
  4. Under moderate agent activity and incoming webhooks, check request latency or test the /health_check endpoint: Requests queue behind long-running ActiveRecord/serialization calls and experience severe latency or timeouts because all 5 threads in the single process are busy.

Expected behavior

  1. .env.example should include WEB_CONCURRENCY with clear comments and recommended production sizing (e.g. WEB_CONCURRENCY=2 or 4 depending on available CPU cores and RAM).
  2. The self-hosted deployment documentation should explain Puma Clustered Mode with Copy-on-Write (preload_app!) to help administrators properly size their instances.

Environment

Linux VM

Cloud Provider

Other [please specify in the description]

Operating system

Ubuntu 22.04 LTS

Proposed Fix

In .env.example (around line 72 next to RAILS_MAX_THREADS), add:

bash
# Specifies the number of Puma worker processes to boot in clustered mode.
# On multi-core production systems (>= 4 vCPUs and >= 4GB RAM), setting this to 2-4
# enables clustered mode and prevents Ruby GVL thread starvation under concurrent traffic.
# Defaults to 0 (single process) if unset.
# WEB_CONCURRENCY=2