Retry Celery tasks with exponential back off
The task.request.retries
attribute contains the number of tries so far,so you can use this to implement exponential back-off:
from celery.task import task@task(bind=True, max_retries=3)def update_status(self, auth, status): try: Twitter(auth).update_status(status) except Twitter.WhaleFail as exc: self.retry(exc=exc, countdown=2 ** self.request.retries)
To prevent a Thundering Herd Problem, you may consider adding a random jitter to your exponential backoff:
import randomself.retry(exc=exc, countdown=int(random.uniform(2, 4) ** self.request.retries))
As of Celery 4.2 you can configure your tasks to use an exponential backoff automatically: http://docs.celeryproject.org/en/master/userguide/tasks.html#automatic-retry-for-known-exceptions
@app.task(autoretry_for=(Exception,), retry_backoff=2)def add(x, y): ...
(This was already in the docs for Celery 4.1 but actually wasn't released then, see merge request)