diff --git a/.envs/.local/.django b/.envs/.local/.django index 36568b3e1..5f65ac07c 100644 --- a/.envs/.local/.django +++ b/.envs/.local/.django @@ -15,6 +15,10 @@ REDIS_URL=redis://redis:6379/0 # NATS NATS_URL=nats://nats:4222 +# Upload size limit (integer, binary MiB — multiplied by 1024*1024). 100 MiB default +# is fine for local dev. Raise only if testing large ML result payloads locally. +# DJANGO_DATA_UPLOAD_MAX_MEMORY_MB=100 + # Celery / Flower CELERY_FLOWER_USER=QSocnxapfMvzLqJXSsXtnEZqRkBtsmKT CELERY_FLOWER_PASSWORD=BEQgmCtgyrFieKNoGTsux9YIye0I7P5Q7vEgfJD2C4jxmtHDetFaE2jhS7K7rxaf diff --git a/.envs/.production/.django-example b/.envs/.production/.django-example index c30d88dc0..75a29757d 100644 --- a/.envs/.production/.django-example +++ b/.envs/.production/.django-example @@ -27,6 +27,17 @@ REDIS_URL=redis://redis:6379/0 # Tune higher only after confirming postgres connection-pool headroom. CELERY_WORKER_CONCURRENCY=16 +# Django +# ------------------------------------------------------------------------------ + +# Maximum in-memory request body size (integer, binary MiB — multiplied by 1024*1024). +# Default is 100 MiB. Raise if ADC workers posting large ML result batches (detection + +# classification payloads) return HTTP 413. global_moths_2024 batches have been +# observed at 139–321 MiB on staging. Must be raised in lockstep with nginx client_max_body_size +# on the fronting proxy — Django will never see a request nginx rejects. +# See RolnickLab/antenna#1223 for the longer-term fix (incremental result posting). +DJANGO_DATA_UPLOAD_MAX_MEMORY_MB=512 + # Flower CELERY_FLOWER_USER= CELERY_FLOWER_PASSWORD= diff --git a/config/settings/base.py b/config/settings/base.py index 787ad837e..e3ca14047 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -458,8 +458,16 @@ def _celery_result_backend_url(redis_url): CELERY_BROKER_CONNECTION_MAX_RETRIES = None # Retry forever -# Allow large request bodies from ML workers posting classification results -DATA_UPLOAD_MAX_MEMORY_SIZE = 100 * 1024 * 1024 # 100MB (default 2.5MB) +# Maximum in-memory request body size for multipart form data and request.body access. +# ML detection+classification payloads for a single batch can exceed the Django +# default (2.5 MB). Configurable via env (integer, binary MiB — multiplied by +# 1024*1024) so operators can tune without a code change. See RolnickLab/antenna#1223 +# for the longer-term fix (worker-side incremental result posting). +# +# Note: this setting does NOT apply to DRF JSON bodies — DRF parsers read from the +# raw WSGI stream, bypassing request.body where Django enforces this limit. +# nginx client_max_body_size is the hard cap for all request types. +DATA_UPLOAD_MAX_MEMORY_SIZE = env.int("DJANGO_DATA_UPLOAD_MAX_MEMORY_MB", default=100) * 1024 * 1024 # django-rest-framework # -------------------------------------------------------------------------------