FAQ

Frequently asked questions

Everything teams ask before putting BabelQueue in front of a production queue — answered in full, in one place. The normative detail lives in the wire contract.

Do I have to replace my message broker?

No. BabelQueue runs on the broker you already operate — it changes the serialization, not the transport. There is no new broker, sidecar or proxy to deploy.

Which brokers are supported?

Seven, all GA and conformance-locked: Redis, RabbitMQ, Amazon SQS, Azure Service Bus, Apache Pulsar, Apache Kafka and Apache ActiveMQ/Artemis. The body is byte-identical on every one, so a message produced on one broker — or in one language — is consumed natively on another. Each broker ships across the SDKs (PHP × Azure Service Bus is the one documented exception).

Will it change my existing (non-BabelQueue) jobs?

No. Standard framework jobs and workers stay exactly as they are. Only connections you opt into as polyglot use the canonical envelope, so adoption is incremental.

Which languages and frameworks are supported?

All six SDKs are released at 1.0 and SemVer-stable: PHP (Laravel & Symfony), Python (Celery & Django), Go (Asynq & Machinery), Node.js (BullMQ & NestJS), Java (Spring Boot) and .NET (MassTransit) — each a framework-agnostic core plus a framework adapter, with per-broker transport modules on top.

Is the wire format stable?

Yes. The envelope is frozen at schema_version 1: within that version the existing fields, their types and their meanings do not change — no field is renamed, removed or retyped, and the required fields keep their meaning. A new field may be added only as an optional, ignorable field, and only through an architecture decision record and an explicit version decision. A consumer that does not understand an unknown field must still process the message correctly and must preserve that field when it re-emits the message.

How is a message identified across languages?

By a URN (urn:babel:<context>:<event>) carried in the envelope, never a class name — so a Go or Python consumer routes on a stable string without sharing any type with the producer.

Is there a performance cost?

Negligible. The codec adds well under 2% over the plain-JSON serialization a publisher already pays, measured against a conservative broker round-trip — and it talks straight to native drivers, with nothing in between.

How do I trace a message across services?

Every message carries a trace_id, generated by the first producer and preserved unchanged across every hop and language — so an end-to-end trace is one query away, no manual plumbing.