# Apache Pulsar: a multi-tenant pub-sub platform for teams that outgrew a single broker

> Apache Pulsar separates message serving from message storage, and the README sells that separation as the way to run millions of topics as a hosted service. Here is what the repository actually shows, how to get a broker running, and where the design costs you.

**apache/pulsar** — Apache Pulsar - distributed pub-sub messaging system

- Repository: https://github.com/apache/pulsar
- Website: https://pulsar.apache.org/
- Stars: 15,342 · Forks: 3,759
- Language: Java
- License: Apache-2.0
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/apache-pulsar

## What Apache Pulsar solves, and for whom

The problem Pulsar targets is stated plainly in its README: it is a distributed pub-sub messaging platform designed for deployment as a hosted service. The feature list names multi-tenancy, authentication, authorization, quotas, and support for mixing very different workloads, with optional hardware isolation. That is a service-provider problem, not a single-application problem. If one team owns one broker and one set of topics, most of that list is dead weight.

The intended user is an organisation running messaging for several internal teams or external customers, where one tenant's backlog must not starve another's, and where topic counts run into the millions. The README claims horizontal scalability to millions of independent topics and millions of messages published per second, and strong ordering and consistency guarantees. Those are the two properties that pull people away from simpler brokers: topic count at scale, and per-key ordering that survives a broker restart.

Pulsar also carries queue semantics alongside topic semantics, so a single system covers both the fan-out case and the work-queue case. Teams that currently run two systems for those two patterns are the clearest fit.

## How Pulsar splits serving from storage

The repository layout is the fastest way to understand the architecture. At the top level there is pulsar-broker, managed-ledger, pulsar-client-api, pulsar-client-admin, pulsar-broker-common, and a set of auth modules: pulsar-broker-auth-athenz, pulsar-broker-auth-oidc, pulsar-broker-auth-sasl. The broker module is the serving layer. The managed-ledger module is the storage abstraction that sits underneath it.

That split is the defining design choice. Brokers are stateless with respect to message data, so a topic can be moved between brokers without copying its backlog. Storage is handled by the ledger layer, and consumer cursor position is tracked by the system rather than by the application. Geo replication is listed as a feature, which follows from having a storage layer that can be told to write to more than one region. Transparent batching and transparent handling of partitioned topics mean the client does not have to know whether a logical topic is split into partitions.

Administration is exposed through a REST API for provisioning, admin and stats, with a separate pulsar-client-admin module for Java callers. The README also points to Pulsar Manager and Dekaf UI as dashboard and management tools, both in separate repositories, so neither is part of this codebase. Note what is not in this repository: connectors are bundled under pulsar-io, and the README marks the standalone Pulsar Connectors repository as archived, with the code now living inside this tree.

## Installing Pulsar and publishing a first message

The README does not give a step-by-step local install. It points at https://pulsar.apache.org for downloads, and the repository ships a docker/ directory and a docker-compose/ directory, plus a docker pull badge for the apachepulsar/pulsar-all image. For a running broker, the container image is the path the project itself advertises.

```bash
docker pull apachepulsar/pulsar-all
```

The README states that Pulsar Docker images come with the most recent Java version at the time of release, and the compatibility table lists the Docker image Java runtime as 21 for Pulsar 3.3 through 4.0 and for 4.1 and later. So the image is self-contained; you do not pick the JDK yourself.

For a source build, the requirements section gives the JDK per version. The master branch accepts JDK 21, 25 or 26. Release 4.0 and later needs JDK 21. 2.11 and later needs JDK 17. The build instructions themselves live in CONTRIBUTING.md under Building, and the Gradle infrastructure is documented in ARCHITECTURE.md under Build infrastructure. The wrapper scripts gradlew and gradlew.bat are at the repository root, and the README points to CONTRIBUTING.md for the full build and lint commands.

On the client side, the README recommends setting specific system properties and JVM options when using the Java client, and links to the client-libraries-java-setup page for that. It does not reproduce those properties here, so read that page before tuning. Java client compatibility is broad across releases: 8, 11, 17 or 21 for Pulsar 3.3 through 4.0, and 17 or 21 for 4.1 and later. The README also warns about JDK-8351933, a JVM bug that can cause stability issues in Pulsar, fixed in Java 17.0.17+ and Java 21.0.8+. Pin your JDK above those patch levels.

## Where Pulsar is the wrong tool

The clearest limitation is operational surface. The repository contains a broker, a managed-ledger storage layer, a REST admin service, several authentication modules, a CLI, and separate client implementations for .NET, C++, Go, NodeJS, Python and reactive Java, each in its own repository. Running a production cluster means running the broker tier and the storage tier, and the README does not describe a supported single-process production deployment. If your workload fits on one machine, this is a large amount of infrastructure for the problem.

The Java version table is a second real constraint. Pulsar 4.1 and later requires JDK 21 for the broker, functions and IO. If your organisation standardises on JDK 17 for server software, you are pinned to Pulsar 4.0.x, which the table lists as JDK 21 as well. Only 2.11 and later accept JDK 17, and 2.10 and earlier want JDK 11. Upgrading Pulsar can therefore force a JVM upgrade across your whole deployment, and the README's own bug note about JDK-8351933 shows that running an older patch of a supported major version is a stability risk, not a neutral choice.

Milestone releases are another trap. v5.0.0-M2 is dated 2026-09-16, and the M suffix marks it as a milestone, not a general-availability release. The stable lines in the recent release list are v4.2.4 and v4.0.13, both dated 2026-08-03. A team that grabs the newest tag because it sorts highest is running pre-release code.

## Pulsar against Kafka and NATS

Apache Kafka is the obvious comparison. Kafka's storage is tied to the broker that owns a partition: a partition lives on a broker, and moving it means replicating it. Pulsar's managed-ledger layer decouples the two, which is what makes broker-level load balancing and topic reassignment cheap. Kafka's ecosystem is larger and its operational literature is deeper; the Pulsar README does not make a comparison claim, and it should not be read as one.

NATS takes the opposite approach from both. It is a lightweight messaging system with a much smaller deployment footprint, and its JetStream layer adds persistence. If your topic count is in the hundreds and your team is small, NATS is the smaller commitment. Pulsar's advantage only materialises when multi-tenancy, quotas and geo replication are requirements you actually have.

A more relevant internal comparison is Pulsar against its own client surface. The README lists six language clients in separate repositories, plus the Java client in this one. Adopting Pulsar means adopting a client matrix, and a feature that exists in the Java client is not automatically present in the Go or NodeJS client. Check the client repository you will actually use before committing to a language.

## Maintenance, release cadence and licence

The repository is not archived, and the last push was on 2026-09-21. Three releases appear in the recent list: v5.0.0-M2 on 2026-09-16, and v4.2.4 and v4.0.13 both on 2026-08-03. That pattern, a milestone on the next major line plus simultaneous patch releases on two older lines, indicates parallel maintenance of more than one branch. It also means upgrade planning has to pick a line deliberately rather than following the highest version number.

Upgrade cost is dominated by the Java version table. Moving from the 4.0 line to 4.1 or later keeps the broker on JDK 21, so that step is comparatively contained. Moving from 2.x to 4.x crosses JDK 11 to JDK 17 to JDK 21, and the client compatibility window narrows at the same time: the Java client supports 8, 11, 17 or 21 on 3.3 through 4.0, but only 17 or 21 on 4.1 and later. Any service still compiled against Java 8 has to move before the broker does.

The licence is Apache-2.0, held by the Apache Software Foundation. The README's header carries the standard ASF notice and points to the LICENSE and NOTICE files, and the repository root contains both. Apache-2.0 includes an explicit patent grant and permits commercial use and redistribution. This is a description of the licence text, not legal advice; if you redistribute Pulsar inside a product, read the NOTICE file and your own legal review, not this article.

## Conclusion

Adopt Pulsar when several teams need isolated namespaces, quotas and geo replication on one cluster, and when you can staff a broker plus BookKeeper plus metadata store. Do not adopt it as a drop-in replacement for a single-node broker on one machine; the README's own feature list assumes a hosted-service deployment, and nothing in the repository documents a supported single-process production mode. Before committing, verify the Java version your target release requires against the compatibility table, confirm the release you plan to run is not a milestone build, and read the SECURITY.md and CONTRIBUTING.md files at the repository root for the project's own process.

## FAQ

### What Java version does Apache Pulsar need?

It depends on the Pulsar version. The README's table lists JDK 21 for the broker on 4.1 and later and on 3.3 through 4.0, JDK 17 for 2.11 and later, and JDK 11 for 2.8 through 2.10. The master branch accepts JDK 21, 25 or 26.

### Is the Apache Pulsar Docker image self-contained?

The README states that Pulsar Docker images come with the most recent Java version at the time of release, and lists the Docker image Java runtime as 21 for 3.3 through 4.0 and for 4.1 and later. The repository also ships docker/ and docker-compose/ directories.

### Which Apache Pulsar release is stable?

The recent release list shows v4.2.4 and v4.0.13, both dated 2026-08-03, alongside v5.0.0-M2 dated 2026-09-16. The M suffix marks a milestone build, so the 4.2 and 4.0 lines are the general-availability releases named in the repository.

### What language clients does Apache Pulsar provide?

The README lists .NET/C#, C++, Go, NodeJS, Python and reactive Java clients in separate repositories, with the Java client in this repository. Because they are maintained separately, feature coverage differs between them.

### What licence is Apache Pulsar under?

Apache-2.0, held by the Apache Software Foundation. The repository root contains the LICENSE and NOTICE files, and the README header carries the standard ASF licence notice.

## Sources

- [apache/pulsar on GitHub](https://github.com/apache/pulsar)
- [License: Apache-2.0](https://github.com/apache/pulsar/blob/master/LICENSE)
- [Project website](https://pulsar.apache.org/)
- [README](https://github.com/apache/pulsar/blob/master/README.md)
- [Releases](https://github.com/apache/pulsar/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/apache-pulsar
