Skip to main content

celery-sqs-native-delay ⏳️

CI PyPI License: MIT

celery[sqs] fetches every ETA/countdown task off the queue immediately and holds it, unacked, in the worker's own memory until the ETA arrives. SQS already has a native mechanism for this. This package makes Celery use it by wrapping kombu's existing SQS transport.

How it routes

flowchart LR
    A["task published<br/>with a delay"] --> B{".fifo queue?"}
    B -->|yes| C["celery's own<br/>ETA timer"]
    B -->|no| D{"delay ≤ 900s?"}
    D -->|yes| E["SQS native<br/>DelaySeconds"]
    D -->|no| F["EventBridge Scheduler<br/>one-time schedule"]
Delay Handled by
at or below 900s SQS native DelaySeconds
above 900s an EventBridge Scheduler one-time schedule
any delay on a .fifo queue left alone, celery's own ETA timer

Install and configure

pip install celery-sqs-native-delay
app = Celery(
    "myapp",
    broker="sqs://",
    broker_transport="celery_sqs_native_delay:Transport",
    broker_transport_options={
        "eventbridge_role_arn": "arn:aws:iam::123456789012:role/celery-scheduler",
    },
)
broker_transport_options key Required Meaning
eventbridge_role_arn yes role EventBridge Scheduler assumes to call SendMessage
eventbridge_dead_letter_arn no, but recommended DeadLetterConfig on every schedule
eventbridge_retry_policy no RetryPolicy on every schedule
eventbridge_group_name no schedule group

Requirements and limitations

  • Celery protocol 2 is required. Protocol 2 has been celery's default since 4.0 (2016), so almost every app already meets this. Protocol 2 puts eta in the message headers. Protocol 1 puts it in the body, which this package never inspects, so a protocol 1 delay is invisible from here and falls back silently to celery's own local timer.
  • FIFO queues get no native delay. SQS has no per-message DelaySeconds on a .fifo queue, and EventBridge Scheduler can't be used either, since separate schedule invocations have no ordering guarantee relative to each other. A delayed publish to a .fifo queue falls back entirely to celery's own local ETA timer, exactly as if this package weren't installed.
    • The way to get delay on a FIFO queue without any of that is a queue-level DelaySeconds attribute set at queue creation. It applies uniformly to every message and preserves ordering.

IAM

Three things need permissions: the role in eventbridge_role_arn, that role again for delivery, and the publisher itself.

1. The role trusts EventBridge Scheduler to assume it:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Service": "scheduler.amazonaws.com" },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": { "aws:SourceAccount": "123456789012" },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:scheduler:us-east-1:123456789012:schedule/*/*"
        }
      }
    }
  ]
}

2. The role can deliver to your queue(s):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sqs:SendMessage",
      "Resource": "arn:aws:sqs:us-east-1:123456789012:myqueue"
    }
  ]
}

3. The publisher can create schedules and pass the role to EventBridge:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["scheduler:CreateSchedule", "sqs:GetQueueAttributes"],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resource": "arn:aws:iam::123456789012:role/celery-scheduler"
    }
  ]
}

Failure and recovery

A CreateSchedule failure (throttling, a missing role, etc) raises out of Channel._put, which propagates up through producer.publish, so celery's own task_publish_retry covers it with no extra handling needed from this package.

A schedule that fires but cannot deliver, for instance a deleted queue, a revoked role permission, or a KMS error on an encrypted queue, goes to eventbridge_dead_letter_arn if you set one. Setting it is recommended: without it, a schedule that fails to deliver leaves nothing behind, because ActionAfterCompletion='DELETE' removes the schedule once it has run.

Retries

Celery reuses one task id across every retry, but "The rule" above is applied fresh on each publish. A retry with a growing backoff can start under 900s on native DelaySeconds, then move to EventBridge Scheduler once a later retry's countdown passes 900s, with no special handling on your part:

@app.task(bind=True, max_retries=5)
def my_task(self):
    try:
        ...
    except Exception as exc:
        countdown = 300 * (2**self.request.retries)
        raise self.retry(exc=exc, countdown=countdown)

Quotas

Every delay above 900s costs one EventBridge Scheduler CreateSchedule call and one invocation. Check your account's EventBridge Scheduler quotas (schedule count, CreateSchedule rate, invocation rate) against your expected volume before relying on this path at scale.

Development

make install            # uv sync --dev
make test               # unit tests, no broker needed
make up                 # start a local ministack (https://ministack.org)
make test-integration   # integration tests against that ministack
make test-all           # integration + unit tests
make down
make lint

License

MIT, see LICENSE.

Metadata

Release files for celery-sqs-native-delay 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for celery-sqs-native-delay 0.1.0
File Size Uploaded Provenance Actions
celery_sqs_native_delay-0.1.0.tar.gz 54.4 kB Without provenance Details for celery_sqs_native_delay-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for celery-sqs-native-delay 0.1.0
File Interpreter ABI Platform Actions
celery_sqs_native_delay-0.1.0-py3-none-any.whl Python 3 none any Details for celery_sqs_native_delay-0.1.0-py3-none-any.whl

Total release size: 62.6 kB

Release files / celery_sqs_native_delay-0.1.0.tar.gz

Download URL celery_sqs_native_delay-0.1.0.tar.gz
Size 54.4 kB
Tags Source
SHA-256 checksum
How to use checksums
d37db3a8e691dc7e2725bbb56345e9f963898a8ada81b2a9ab3d40e1b946baf6
BLAKE2b-256 checksum
How to use checksums
bf72fb1176066c14b280bc174032fa9b4e7b39409fe0b17e5a6509ea604c778b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / celery_sqs_native_delay-0.1.0-py3-none-any.whl

Download URL celery_sqs_native_delay-0.1.0-py3-none-any.whl
Size 8.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d53ca72ae8084f208e261602c9047fdfd85bbe64281a4486a96149c1ad6d38f2
BLAKE2b-256 checksum
How to use checksums
c42240955f8b1bfa7000b7f0f76a08b7b3f6166b829e75ad24008baf3060d81d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for celery-sqs-native-delay 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page