Celery polling Redis every second
I have a Django application with two celery tasks set up. Both the tasks need to run only once at one minute after midnight (12:01 AM). This is just to update some statuses which change from "ACTIVE" to "INACTIVE" at 12:01 AM.
My goal is to reduce the number of times Celery polls Redis. Currently, it polls every second which is problematic.
I took three steps
I tried to change the settings in Django for Celery inlcuding using paramters such as
CELERY_IGNORE_RESULT
,CELERY_WORKER_CONCURRENCY
,CELERY_BROKER_HEARTBEAT
and lastlyCELERY_BEAT_MAX_LOOP_INTERVAL
CELERY_RESULT_BACKEND = None CELERY_IGNORE_RESULT = True # Ignore task results to reduce Redis usage CELERY_ACCEPT_CONTENT = ["json"] CELERY_TASK_SERIALIZER = "json" CELERYD_PREFETCH_MULTIPLIER = 1 # Fetch only 1 task at a time CELERY_ACKS_LATE = True # Acknowledge tasks after completion to avoid re-execution on failure # Celery transport options CELERY_BROKER_TRANSPORT_OPTIONS = { 'ssl': { 'ssl_cert_reqs': ssl.CERT_NONE # Suggestion: CERT_REQUIRED for stronger security }, 'visibility_timeout': 3600, # Timeout for long-running tasks 'polling_interval': 30 # Poll every 30 seconds } CELERY_RESULT_BACKEND_TRANSPORT_OPTIONS = { 'ssl': { 'ssl_cert_reqs': ssl.CERT_NONE # Same as broker for consistency } } # Reduce the number of threads/processes CELERY_WORKER_CONCURRENCY = 1 # Disable sending task events CELERY_WORKER_SEND_TASK_EVENTS = False # Disable remote control commands CELERY_WORKER_ENABLE_REMOTE_CONTROL = False # Disable broker heartbeat messages CELERY_BROKER_HEARTBEAT = None CELERY_BEAT_MAX_LOOP_INTERVAL = 3600 # Check for scheduled tasks every hour
Secondly, I even tried to set up dynamic polling so that the polling schedule is more frequent in during night time and reduced again
def set_polling_interval(): now = datetime.now() if now.hour == 23 and now.minute >= 59 or now.hour == 0 and now.minute <= 15: # Between 11:59 PM and 12:15 AM, poll more frequently app.conf.broker_transport_options = {'polling_interval': 30} # Poll every 30 seconds logger.info("Polling every 30 seconds between 11:59 PM and 12:15 AM.") else: # During the rest of the day, poll less frequently (every 24 hours) app.conf.broker_transport_options = {'polling_interval': 86400} # Poll every 24 hours logger.info("Polling every 24 hours outside the midnight window.")
Lastly, because I have Django Celery Beat installed, I tried tweaking the settings there directly in the "Intervals" and "Crontabs" section, but that did not help either.
Despite these efforts, Celery is still polling Redis every second. I checked the documentation for optimization, but struggled to find a solution there https://docs.celeryq.dev/en/stable/userguide/optimizing.html
The following article was also referred so that maybe I can do the opposite of it but that did not work either
Can I use celery for every-second task?