How to post a task on a celery-rabbitmq queue in PHP?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
PHP can publish messages to RabbitMQ easily, but publishing a task that a Celery worker will actually accept is more specific than just dropping JSON into a queue. Celery has its own task message protocol, so the PHP producer must match the queue, serializer, headers, and body structure expected by the Python worker.
Understand The Real Constraint
RabbitMQ is only the broker. Celery is the task system that defines how messages are encoded and interpreted. That means this PHP code is not enough:
Publishing to the queue name alone does not make the message a valid Celery task. The worker still expects a Celery-compatible payload.
For current Celery protocol v2, metadata such as the task name and task id lives in headers, while the serialized arguments live in the body. That is the part most ad hoc examples leave out.
Publish A Celery-Compatible Task From PHP
Using php-amqplib, you can publish a minimal task message like this:
This example assumes:
- the Celery worker is consuming from the
celeryqueue - the worker accepts JSON serialization
- the task name is
tasks.add
If the worker uses a different queue or serializer, the PHP side must match it exactly.
Match The Python Worker Configuration
A compatible Celery worker might look like this:
If the PHP producer sends JSON but the worker only accepts pickle or msgpack, the task will not be processed correctly.
That is why Celery interoperability is not only about RabbitMQ connectivity. The application-level protocol has to line up too.
When A Bridge Service Is Simpler
For one-off integrations, directly publishing a Celery message from PHP can work. But for long-term maintenance, a small Python bridge API is often cleaner.
Instead of reimplementing Celery protocol details in PHP, the PHP app can call an internal HTTP endpoint, and that Python service can use app.send_task(...) or apply_async(...) natively.
That approach reduces drift when Celery configuration changes, especially around:
- serialization
- routing
- retries
- result backends
It also avoids duplicating Celery-specific message assembly logic in another language.
Common Pitfalls
One common mistake is publishing a plain JSON object with task, args, and kwargs in the body and assuming the Celery worker will always accept it. Current Celery protocol uses headers as part of the task envelope.
Another issue is sending the message to the celery queue when the worker actually listens on a custom queue.
A third problem is mismatched serializers. If the worker is configured to accept JSON only, a differently encoded PHP message will be rejected.
Finally, many examples ignore retries, result handling, or exchange routing and only work in a toy local setup. Production interoperability needs those details to be deliberate.
Summary
- RabbitMQ is only the broker; Celery defines the task message format.
- PHP can publish Celery tasks, but the queue, serializer, headers, and body must match the worker configuration.
- For Celery protocol v2, important metadata such as task name and id lives in headers.
- A
php-amqplibpublisher can work for controlled cases where the protocol is stable and known. - For larger systems, a small Python bridge service is often easier to maintain than handcrafting Celery messages in PHP.
Related reading
- How to post messages to RabbitMQ from SQL Server?
- How to prevent duplicate SQS Messages?
- How to Process a kafka KStream and write to database directly instead of sending it another topic
- how to process data in chunks/batches with kafka streams?
- How to preserve insertion order in HashMap?
- How to pretty print nested dictionaries?
- How to process logs from distributed log broker (Eg Kafka) exactly after 1 week?
- How to produce a json object message into kafka topic using java(spring)?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.