Django login_required doesn't work with multiple gunicorn workers

So I have a project which contains multiple micro-services, the entry point is the Django micro-service(with user login & authentication).
All other Apis are wrapped with the @login_required decorator by Django.
I’ve deployed it using ngnix, gunicorn inside a kubernetes pod.
Everything works fine with 1 worker(sync) but I obviously want multiple workers, so when I increase my number of workers and threads(gthread), it doesn’t let me login redirects to login/?next=/login/5/.
After spending some time, I figured out the following:

  • Since the default value of keepalive of a worker is 2s, the worker closes connection and a new worker is assigned & since they don’t share common memory,my session cookie isn’t carried forward.
  • I tried increasing the keepalive time to 10s , now it lets me login but if someone tried to login when the worker is about to expire(around 10s), same, doesn’t login & redirects to login/?next=/login/5/.
  • Another direction I found was about fixing the secret key as in this post, but I just using the default standard value which I even hardcoded in settings.py, but no luck.
    I’ll attach my gunicorn config/logs below:
config: ./gunicorn.conf.py  
 wsgi_app: None   
bind: ['0.0.0.0:8000']  
backlog: 2048  
 workers: 2  
 worker_class: sync   
threads: 4  
worker_connections: 1000 
  max_requests: 0   
max_requests_jitter: 0  
timeout: 600  
 graceful_timeout: 30 
  keepalive: 2  
limit_request_line: 4094 
  limit_request_fields: 100  
limit_request_field_size: 8190  
 reload: False   reload_engine: auto  
reload_extra_files: []   spew: False 
  check_config: False  
print_config: False  
 preload_app: False 
  sendfile: None  
reuse_port: False 
  chdir: /app 
  daemon: False 
  raw_env: []  
pidfile: None  
 worker_tmp_dir: None 
  user: 0  
 group: 0 
  umask: 0  
initgroups: False   
tmp_upload_dir: None  
 secure_scheme_headers:{'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}   
forwarded_allow_ips: ['127.0.0.1']  
accesslog: None
   disable_redirect_access_to_syslog: False  
access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s""%(a)s"   errorlog: - 
  loglevel: debug 
  capture_output: False  
logger_class: gunicorn.glogging.Logger 
  logconfig: None  
logconfig_dict: {}  
 syslog_addr: udp://localhost:514 
  syslog: False 
syslog_prefix: None   
syslog_facility: user  
enable_stdio_inheritance: False  
 statsd_host: None  
 dogstatsd_tags: 
statsd_prefix:  
 proc_name: None   
default_proc_name:
UI-1.wsgi:application  
 pythonpath: None  
 paste: None   
on_starting:  
proxy_protocol:False   
proxy_allow_ips: ['127.0.0.1']   
keyfile: None   certfile:None   
ssl_version: 2   cert_reqs: 0   c
a_certs: None  
suppress_ragged_eofs: True   
do_handshake_on_connect: False   
ciphers:None   
raw_paste_global_conf: []   
strip_header_spaces: False
[2022-08-31 14:23:52 +0000] [9] [INFO] Starting gunicorn 20.1.0
[2022-08-31 14:23:52 +0000] [9] [DEBUG] Arbiter booted [2022-08-31
14:23:52 +0000] [9] [INFO] Listening at: http://0.0.0.0:8000 (9)
[2022-08-31 14:23:52 +0000] [9] [INFO] Using worker: gthread
[2022-08-31 14:23:52 +0000] [11] [INFO] Booting worker with pid: 11
[2022-08-31 14:23:52 +0000] [12] [INFO] Booting worker with pid: 12
[2022-08-31 14:23:52 +0000] [9] [DEBUG] 2 workers [2022-08-31 14:23:58
+0000] [11] [DEBUG] GET / 
[2022-08-31 14:23:58 +0000] [12] [DEBUG] GET / 
[2022-08-31 14:23:58 +0000] [11] [DEBUG] GET / Not Found: / Not
Found: / 
[2022-08-31 14:23:58 +0000] [11] [DEBUG] Closing connection.
[2022-08-31 14:23:58 +0000] [11] [DEBUG] Closing connection. Not
Found: / [2022-08-31 14:23:58 +0000] [12] [DEBUG] Closing connection.
[2022-08-31 14:24:13 +0000] [12] [DEBUG] GET / [2022-08-31 14:24:13
+0000] [11] [DEBUG] GET / Not Found: / Not Found: / [2022-08-31 14:24:13 +0000] [11] [DEBUG] Closing connection. [2022-08-31 14:24:13
+0000] [12] [DEBUG] Closing connection. [2022-08-31 14:24:13 +0000] [11] [DEBUG] GET / Not Found: / [2022-08-31 14:24:13 +0000] [11]
[DEBUG] Closing connection. [2022-08-31 14:24:28 +0000] [12] [DEBUG]
GET / [2022-08-31 14:24:28 +0000] [12] [DEBUG] GET / Not Found: / Not
Found: / [2022-08-31 14:24:28 +0000] [12] [DEBUG] Closing connection.
[2022-08-31 14:24:28 +0000] [12] [DEBUG] Closing connection.
[2022-08-31 14:24:28 +0000] [11] [DEBUG] GET / Not Found: /

Let me know what I am doing wrong, unable to figure that out, thanks in advance!

If this is a root issue here, then change to using the database backend for your sessions.

Side note: My understanding is that not everything you might use within Django is necessarily thread-safe. I have never used multiple threads in my workers. I always limit myself to using multiple processes only. (I have seen strange issues resolved by removing the threads configuration from uWSGI.)