Self-hosted service
apache/rocketmq avatar
apache/rocketmq

Apache RocketMQ: a Java messaging and streaming platform you can run locally, in Docker or on Kubernetes

Apache RocketMQ is a cloud native messaging and streaming platform, making it simple to build event-driven applications.

22,622 stars12,025 forksJavaApache-2.0

At a glance

What is it?
Apache RocketMQ is a distributed messaging and streaming platform written in Java and licensed under Apache-2.0. Its quick start covers a local binary release, Docker containers and a Kubernetes operator, and its feature list leans on transactional messages, ordered delivery and message retroactivity.
Who is it for?
Adopt RocketMQ when your workload needs transactional messages, strict ordering inside a queue, or replay by time and offset, and when running a NameServer plus Broker pair is acceptable operational overhead. Skip it if you want a single-node broker with no separate routing component, or if you need a client language that only exists in the remoting-based set.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What RocketMQ solves, and who ends up running it

RocketMQ is a message broker for event-driven applications. The README describes it as a distributed messaging and streaming platform with low latency, high performance and reliability, and it lists the messaging patterns it covers: publish/subscribe, request/reply and streaming. The feature list is where the target user becomes clear. Financial grade transactional messages, reliable FIFO and strict ordered messaging in the same queue, and message retroactivity by time or offset are not features you pick up by accident. They are the requirements of teams moving money, order state or inventory events, where a message that arrives twice or out of order is a bug report rather than a metric.

The second group is teams with accumulation problems. The README claims million-level message accumulation capacity in a single queue and message retroactivity by time or offset. A consumer that falls behind for an hour is normal in that setting, and the broker is expected to hold the backlog rather than drop it. The third group is big-data and streaming pipelines: the project points at RocketMQ Flink for source and sink connectors, RocketMQ Streams as a lightweight stream computing engine, and RocketMQ Exporter for Prometheus. If your consumers are Flink jobs and your dashboards are Grafana, the surrounding repositories matter as much as the broker.

What RocketMQ is not is a drop-in single binary. There is a NameServer and a Broker, and the quick start starts them as two processes. That split is the first thing to weigh, because it shapes every deployment decision afterward.

NameServer, Broker and the routing layer between them

The repository layout shows the architecture more plainly than the README does. namesrv/ is the name service, broker/ is the broker, store/ is the storage engine, remoting/ is the network layer, client/ is the client library, proxy/ is the proxy component, controller/ implements the DLedger Controller, and tieredstore/ is a separate tiered storage module. auth/, filter/, srvutil/, tools/ and container/ fill in authorization, message filtering, shared utilities, admin tooling and container support.

The data flow in the quick start is short. The NameServer listens at 0.0.0.0:9876. The Broker registers with it, and the quick start passes the address directly: mqbroker -n localhost:9876. Clients ask the NameServer where a topic lives and then talk to the Broker. That is why the README warns you to make sure port 9876 is not used by another process on the machine. If the NameServer is unreachable, nothing routes, even if the Broker process is healthy.

The Broker log line in the README, broker[broker-a, 192.168.1.2:10911] boot success, exposes the second port. 10911 is the Broker's listening port, and the log prints the IP and broker name alongside it. In a single-machine setup the broker name is broker-a. In a cluster, that name and address pair is what the NameServer hands back to clients, so a Broker that advertises an address clients cannot reach is a configuration failure that looks like a network failure.

High availability sits in controller/ rather than in the default local path. The README points at the DLedger Controller quick start for built-in fault tolerance and high availability configuration. That is a deliberate separation: the two-process local setup gives you a working broker, not a fault-tolerant one.

Installing RocketMQ locally and producing a first message

The README states that RocketMQ runs on all major operating systems and requires only a Java JDK version 8 or higher. Verify that first, because the broker will not start without it:

bash
$ java -version
java version "1.8.0_121"

On macOS and Linux the quick start downloads the 5.5.1 binary release from the Apache mirror and unpacks it:

bash
$ wget https://dist.apache.org/repos/dist/release/rocketmq/5.5.1/rocketmq-all-5.5.1-bin-release.zip
$ unzip rocketmq-all-5.5.1-bin-release.zip
$ cd rocketmq-all-5.5.1-bin-release/bin

Windows users are told to download the same 5.5.1 binary release, unpack it to a local disk such as D:\rocketmq, and set ROCKETMQ_HOME to that path before running mqnamesrv.cmd.

Start the NameServer in the background and confirm it came up by tailing its log. The README says the NameServer listens at 0.0.0.0:9876 and that the log should show a boot success line:

bash
$ nohup sh mqnamesrv &
$ tail -f ~/logs/rocketmqlogs/namesrv.log
The Name Server boot success...

Then start the Broker, pointing it at the NameServer you just started. The README's expected log line includes the broker name and its IP and port:

bash
$ nohup sh mqbroker -n localhost:9876 &
$ tail -f ~/logs/rocketmqlogs/broker.log
The broker[broker-a, 192.168.1.2:10911] boot success...

If you would rather not unpack a release, the README gives a Docker path that uses the host network so the listening ports are exposed directly. Two containers, one for each component:

bash
$ docker run -it --net=host apache/rocketmq ./mqnamesrv
$ docker run -it --net=host --mount type=bind,source=/tmp/store,target=/home/rocketmq/store apache/rocketmq ./mqbroker -n localhost:9876

The bind mount on the second command keeps the message store on the host at /tmp/store instead of inside the container. The README does not document what happens to that store when you remove the container, so treat the path as yours to manage.

For Kubernetes, the README points at the separate RocketMQ Operator repository. You clone it, run make deploy, and check that the CRDs exist:

bash
$ git clone https://github.com/apache/rocketmq-operator
$ cd rocketmq-operator && make deploy
$ kubectl get crd | grep rocketmq.apache.org

The expected output lists brokers.rocketmq.apache.org, consoles.rocketmq.apache.org, nameservices.rocketmq.apache.org and topictransfers.rocketmq.apache.org. A cluster instance is then created from the operator's example directory with kubectl create -f rocketmq_v1alpha1_rocketmq_cluster.yaml, and kubectl get sts should show broker-0-master, broker-0-replica-1 and name-service. Note that the README's own example output shows a 107m age on those stateful sets, which is copied sample output rather than a promise about your cluster.

Where RocketMQ is the wrong tool

The two-process model is the first real cost. A NameServer and a Broker must both run, and the NameServer is a routing dependency with no message storage of its own. If your problem fits a single broker process with embedded routing, you are paying for a component you do not need. Teams that want a queue they can start, use and stop inside one test process will find the quick start heavier than they expect.

The second limitation is client coverage, and it is easy to misread. The README splits clients into two groups. The gRPC/protobuf-based clients live in the separate rocketmq-clients repository, which is where you find the modern protocol implementations. The remoting-based clients are listed individually: C++, Go, Python and Node.js, each in its own repository. There is no line in the README stating that every language has a client in both families. Before designing around a language, check which family actually ships a client for it, and decide whether you are committing to the remoting protocol or the gRPC one. Mixing the two across a codebase is a decision the README does not address.

The third limitation is that fault tolerance is not free. Built-in high availability is described in terms of DLedger Controller configuration, which the README links to a separate quick start under docs/en/controller/. The local quick start creates one instance of each component and says so explicitly. That is a development and testing configuration. Anyone reading the quick start as a production recipe is reading it wrong.

Finally, the README does not document rollback or downgrade for the broker, and it does not document what happens to the on-disk store across version changes. The store/ and tieredstore/ modules exist in the repository, but the README itself is silent on migration paths between 5.4.0, 5.5.0 and 5.5.1. If you are upgrading an existing cluster, that silence is the gap to close before you start, not after.

RocketMQ against Kafka and RabbitMQ: what actually differs

The comparison people ask about most is RocketMQ versus Kafka, and the honest difference starts with the routing component. Kafka's brokers coordinate partition leadership among themselves; RocketMQ puts a NameServer in front and has the Broker register with it. That changes what you operate and what fails. In RocketMQ, a NameServer outage stops routing but does not touch stored messages; in a broker-coordinated design, the equivalent failure mode is distributed across the cluster.

The second difference is in the feature list. RocketMQ ships transactional messages, request/reply as a first-class pattern, message retroactivity by time or offset, and SQL and Tag filtering. Kafka's ecosystem reaches the same outcomes through different machinery, but the RocketMQ README presents these as built-in rather than assembled. If request/reply is central to your design, that is a concrete reason to look here.

The RabbitMQ comparison turns on the queue model. RabbitMQ is built around exchanges and routing keys with per-message acknowledgement. RocketMQ is built around topics and queues with pull and push consumption, and the README's ordering guarantee is scoped precisely: reliable FIFO and strict ordered messaging in the same queue. That scoping matters. Ordering holds within a queue, so the producer's choice of which queue a message lands in determines whether order is preserved. RabbitMQ users moving over should expect to think about queue selection explicitly rather than relying on exchange routing to do it.

Pulsar and ActiveMQ come up in the same searches. The README does not compare RocketMQ to either, so any claim about how they differ would be mine rather than the project's. What the README does establish is the protocol surface: gRPC, MQTT, JMS and OpenMessaging are all listed as supported messaging protocols. If protocol breadth is your deciding factor, that list is the part to read closely.

Maintenance, licensing and what an upgrade costs you

The repository is not archived, and the last push was on 2026-09-20. Releases are on a steady cadence: rocketmq-all-5.4.0 on 2025-12-24, rocketmq-all-5.5.0 on 2026-04-10 and rocketmq-all-5.5.1 on 2026-08-20. That is roughly a minor release every four months, with a patch release four months after 5.5.0. The quick start in the README is written against 5.5.1, including the download URLs, so the documentation tracks the current release rather than lagging behind it.

The licence is Apache-2.0, and the repository carries both LICENSE and NOTICE files at the top level. Apache-2.0 is a permissive licence that permits commercial use and modification. This is not legal advice, and the NOTICE file and the .licenserc.yaml in the repository are the places to look if you redistribute the project or bundle it into a product.

The upgrade cost is where the material runs out. Release notes are not reproduced here, so the compatibility surface between 5.4.0, 5.5.0 and 5.5.1 cannot be stated. What can be said is structural: the repository contains remoting/, proxy/, controller/, store/ and tieredstore/ as separate modules, and the README presents the gRPC clients as living in a different repository from the remoting clients. A version bump can move any of those boundaries. Before upgrading a running cluster, read the release notes for the version you are moving to, and check whether your client library is in the gRPC or the remoting family, because that determines which repository you need to follow for client-side changes.

The operational cost of the two-process model does not go away at scale. NameServer and Broker are separate things to monitor, and the admin dashboard is described as feature-rich for configuration, metrics and monitoring, which implies it is a component you deploy and watch as well.

Editorial conclusion

Adopt RocketMQ when your workload needs transactional messages, strict ordering inside a queue, or replay by time and offset, and when running a NameServer plus Broker pair is acceptable operational overhead. Skip it if you want a single-node broker with no separate routing component, or if you need a client language that only exists in the remoting-based set. Before committing, check the client repository for your language, confirm whether you want the remoting or gRPC protocol, and decide whether the DLedger Controller or the Operator fits how you run infrastructure.

Frequently asked questions

What is Apache RocketMQ?

It is a distributed messaging and streaming platform written in Java and licensed under Apache-2.0. The README describes it as offering publish/subscribe, request/reply and streaming patterns, plus transactional messages, ordered messaging in the same queue, and message retroactivity by time or offset.

What are the key differences between RabbitMQ and RocketMQ?

The README frames RocketMQ ordering as reliable FIFO and strict ordered messaging in the same queue, so ordering is scoped to a queue rather than to a routing exchange. RocketMQ also lists transactional messages, request/reply and message retroactivity by time or offset as built-in features.

How does Apache RocketMQ compare with Kafka?

The README does not compare the two directly. The structural difference visible in the repository is that RocketMQ runs a NameServer at 0.0.0.0:9876 that the Broker registers with, and clients route through it, rather than relying on broker-to-broker coordination alone.

What are the alternatives to RocketMQ?

The search results for this question point at Kafka, RabbitMQ, Pulsar and ActiveMQ. The README does not compare RocketMQ against any of them, so the only comparison it supports is the feature list: transactional messages, ordered messaging in the same queue, replay by time or offset, and gRPC, MQTT, JMS and OpenMessaging protocol support.

Official sources

  1. apache/rocketmq on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/apache-rocketmq.svg)](https://hysenlabs.com/projects/apache-rocketmq)
Community notes

Community notes