1

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

  1. 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 lastly CELERY_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
    
  2. 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.")
    
  3. 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?

1
  • Any update to this issue? I'm running into a similar problem. Commented Sep 11 at 18:05

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.