From 1f8ca695e8356ac54afd99b1ae6ccfa91f0200d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Arroba?= <19954079+cesararroba@users.noreply.github.com> Date: Thu, 15 Oct 2026 09:36:33 +0200 Subject: [PATCH] fix(api): recycle gunicorn workers to cap memory growth (#13047) --- api/changelog.d/gunicorn-max-requests.fixed.md | 1 + api/src/backend/config/guniconf.py | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 api/changelog.d/gunicorn-max-requests.fixed.md diff --git a/api/changelog.d/gunicorn-max-requests.fixed.md b/api/changelog.d/gunicorn-max-requests.fixed.md new file mode 100644 index 0000000000..e43a4ea57a --- /dev/null +++ b/api/changelog.d/gunicorn-max-requests.fixed.md @@ -0,0 +1 @@ +Gunicorn workers are now recycled after 10000 requests (plus up to 1000 of jitter) to cap memory growth, configurable with `GUNICORN_MAX_REQUESTS` and `GUNICORN_MAX_REQUESTS_JITTER` diff --git a/api/src/backend/config/guniconf.py b/api/src/backend/config/guniconf.py index 8b17ad669d..5880d9f45c 100644 --- a/api/src/backend/config/guniconf.py +++ b/api/src/backend/config/guniconf.py @@ -53,6 +53,10 @@ preload_app = not DEBUG # that may take longer, such as complex API operations. timeout = env.int("GUNICORN_TIMEOUT", default=120) +# Recycle workers after N requests (+ jitter) to cap memory growth. GUNICORN_MAX_REQUESTS=0 disables. +max_requests = env.int("GUNICORN_MAX_REQUESTS", default=10000) +max_requests_jitter = env.int("GUNICORN_MAX_REQUESTS_JITTER", default=1000) + # Logging logconfig_dict = DJANGO_LOGGERS gunicorn_logger = logging.getLogger(BackendLogger.GUNICORN)