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)