From db75ca79d1b9b0520e741812d3468e2da6f9e3e1 Mon Sep 17 00:00:00 2001 From: "benjamin.baker" Date: Thu, 3 Sep 2026 12:36:28 -0400 Subject: [PATCH] [ALERT] Serve gunicorn with threaded workers so bad clients cannot starve the UI Untrusting or half-deployed agents that fail the TLS handshake retry in a loop. With 4 blocking sync workers a few of them pinned every worker, and real UI requests queued for 20+ seconds while CPU sat idle. Switch to gthread (4 workers x 8 threads) and drop the timeout to 30s so a stuck connection frees its thread quickly and one misbehaving client cannot exhaust request capacity. --- docker-compose.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 326966a5..ec2628a8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -79,10 +79,19 @@ services: - gunicorn - --bind - 0.0.0.0:5001 + # Threaded workers so one blocked request (e.g. an agent that fails the TLS + # handshake and retries in a loop) cannot pin a whole worker and starve the + # UI. With sync workers a handful of stuck clients exhausted all capacity. + - --worker-class + - gthread - --workers - "4" + - --threads + - "8" + # Shorter timeout so a hung connection frees its thread quickly instead of + # holding it for a full minute. - --timeout - - "60" + - "30" - --access-logfile - "-" - --error-logfile