# Apache EventMesh strips the broker down to a write-ahead log

> Apache EventMesh is a serverless event middleware where the message queue is deliberately reduced to an append-only write-ahead log with no consumer groups and no tags, and a stateless runtime holds the subscription registry, offsets and delivery semantics over HTTP and CloudEvents 1.0. That inversion buys backend-independent delivery semantics at the cost of putting every delivery guarantee in the runtime you operate.

**apache/eventmesh** — EventMesh is a new generation serverless event middleware for building distributed event-driven applications.

- Repository: https://github.com/apache/eventmesh
- Website: https://eventmesh.apache.org/
- Stars: 1,759 · Forks: 659
- Language: Java
- License: Apache-2.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/apache-eventmesh

## The broker loses consumer groups, tags and subscription semantics

The architecture decision that defines EventMesh is stated in one sentence: it adopts a unified CloudEvents-over-MQ architecture in which the message queue acts as a pure write-ahead log for durable storage only. There are no consumer groups, no tags, and no broker-side subscription semantics.

That is a large subtraction. EventMesh moves all of it into the runtime. The stateless EventMesh Runtime owns the delivery logic through a SubscriptionManager that maintains both the subscription registry and offset tracking, and dispatches with load-balance, broadcast and multicast semantics. The stated benefit is consistent behavior across any storage backend, because the semantics no longer come from whichever broker you picked. The stated cost is that EventMesh itself now owns reliability, delivered through self-managed offsets and explicit ACK, which is how the project claims at-least-once delivery.

The application-facing side is correspondingly thin. Interaction happens through a lightweight HTTP and CloudEvents 1.0 SDK with three operations: publish, subscribe and unsubscribe. There is no heavyweight client library. Integration with external systems is not done inside that SDK but by a separate standalone Connector Runtime reached through a connector SPI, so the path for talking to a SaaS or database is a process boundary rather than a method call.

## Three transports, one ReliableDispatcher

Subscribers choose how events reach them. The options given are HTTP long-polling, Server-Sent Events and WebSocket push, with request-reply support alongside them. That matters operationally: a client behind a corporate proxy that cannot hold a WebSocket open can still subscribe by long-polling without a different event model.

The capability table reveals how these transports relate. SSE and WebSocket push are marked Beta and usable, and the note explains that ACK-tracked redelivery and dead-letter handling are shared with long-polling because both go through the same ReliableDispatcher. The practical meaning is that moving from long-polling to push does not change your delivery guarantees, only the transport. An end-to-end suite against a real broker is tracked in pull request #5389.

The GA target surface is HTTP plus CloudEvents, described as the primary user path with CloudEventsClient and the /events/* endpoints. If you are designing against this project, that path is the one with a target of GA, and it is the one the recommendation column points at.

Runtime instances are stateless, which is what makes horizontal scaling cheap: adding instances needs no rebalancing, because no instance owns subscription state exclusively. Offsets and the registry live centrally in the SubscriptionManager rather than in any one process.

## Running it with docker run and no broker at all

The quickest way to see EventMesh is with the default in-memory storage backend, which needs nothing else running. The capability table gives the exact invocation:

```bash
docker run apache/eventmesh
```

No broker, no dependency, nothing to install first. This is described as the dev and CI default backend, and the table is blunt about its limits: state is process-local, and it is not for production.

The way out is a configuration key rather than a code change. Switch EVENTMESH_STORAGE_TYPE to kafka, rocketmq or rocketmq5 when you need durability. Those three backends, Kafka and RocketMQ at 4.x and 5.x, are the GA target storage plugins and are described as TCK-covered through a MeshStoragePluginTCK, which is the sort of conformance suite that makes swapping backends a defensible move rather than a hope.

More storage backends plug in through the MeshStoragePlugin SPI, and the meta service uses the same SPI. Nacos ships today and is described as handling multi-instance coordination, which is the piece that makes several stateless runtime instances agree on the subscription registry. If you deploy more than one runtime and are not using a coordination backend, the registry has no obvious source of truth.

For your own build, the repository is a Gradle project: build.gradle and settings.gradle at the root, with gradlew and gradlew.bat wrappers and an install.sh script. The docker/ and deploy/ directories hold the container packaging.

## maturity.md is the file to read before you plan anything

EventMesh ships a capability status table that it calls the single source of truth, with module-level docs linking to it rather than restating status. The file is at the root of the repository as maturity.md. This is unusual and useful: instead of discovering that a feature is a Beta after you have built on it, you read one table.

As written, the statuses are: HTTP plus CloudEvents at GA target, recommended as the primary user path. Kafka and RocketMQ storage at GA target, recommended as pluggable WAL backends. Memory storage at Beta as the default dev backend, with the note to switch EVENTMESH_STORAGE_TYPE away from it for anything real. SSE and WebSocket push at Beta, usable. Connector Runtime at Beta, usable, with all 23 plugins implemented since pull request #5394, no template stubs remaining, data-loss hardening in #5328 and unit tests across all 23 plugins since #5412. The A2A and Agent Gateway surface is also marked Beta and usable.

The Connector Runtime row is the most informative because it names its own exit criteria: promotion to GA waits on the remaining review items in #5296, which it describes as real-backend integration tests per plugin and a connector-runtime high-availability story. Read that as an honest statement: the plugins work end to end, and what is missing is per-plugin testing against real backends plus a documented HA design for the connector runtime itself.

Practically, this table is your risk register. If your design depends on the connector runtime being a stable tier-one component, you are building on a Beta surface with an acknowledged open HA question.

## The agent features sit on top of the same runtime

Two features extend EventMesh beyond plain pub/sub, and both are recent enough to be worth sizing up before you commit.

The first is A2A, a built-in Agent-to-Agent protocol described in docs/feature/a2a.md. Its stated purpose is to turn the mesh into an agent collaboration bus, bridging synchronous MCP and JSON-RPC 2.0 tool calls with asynchronous event-driven pub/sub, for LLM and multi-agent systems. The interesting part is the bridge: synchronous request-reply tool calls and asynchronous events are different interaction styles, and routing both over one mesh is the claim.

The second is an LLM streaming agent runtime, a standalone agent process documented at docs/feature/agent-tools.md. It hosts OpenAI-compatible LLM streaming sessions on the mesh and adds function-calling tools. The extension points are worth noting: any connector becomes an agent tool, custom tools ship as agent plugins through the eventmesh-agent-plugin/ directory using the SPI, and topics can drive agents as event triggers with decisions published back for sink delivery. That last part is the mechanism that closes the loop, an event on a topic triggers an agent, and the agent's output is published to a sink.

Both are marked Beta. The agent runtime also has its own top-level module, eventmesh-agent-runtime/, and the README does not describe resource isolation, cost control or concurrency behaviour for streaming sessions, so those are open questions rather than known properties. The repository topics list does include serverless-workflow, and event orchestration is handled by a Serverless workflow engine implementing the Serverless Workflow specification, with filtering and transformation listed as separate capabilities.

## Where EventMesh differs from just deploying a broker

The honest alternative to EventMesh is to skip the middleware and use Kafka or RocketMQ directly with a client library. The difference in approach is not performance, it is where the subscription state lives.

You get the broker's own delivery semantics, its own tooling, its own ecosystem of connectors, and no additional runtime to operate. What you do not get is a single set of semantics that behaves the same whichever backend you pick, nor a CloudEvents envelope that stays vendor-neutral from producer through to every subscriber, nor one HTTP contract that non-JVM services can use without a client library.

EventMesh trades that for operational surface. You now run a stateless runtime with a centralized SubscriptionManager, plus a coordination backend such as Nacos for multi-instance agreement, plus the broker underneath. This adds operational components, and the at-least-once guarantee depends on the runtime's self-managed offsets rather than on the broker's.

If you only have one backend and one language, the direct approach is usually the cheaper answer. EventMesh earns its extra machinery when you have several storage backends to unify, several languages to serve over one HTTP contract, or external systems to reach through connectors without writing to each one's native API.

The licence is Apache 2.0, with a NOTICE file and a.licenserc.yaml at the root indicating header checking is enforced in the repository. The default branch is develop, not master, which matters when you pin a branch or a tag in CI.

## Conclusion

Adopt Apache EventMesh if you want one delivery semantic set across storage backends, need CloudEvents 1.0 on the wire, and can run a stateless runtime plus a durable broker in the same deployment. Do not adopt it if you want broker-native consumer groups, or if the in-memory backend looks attractive: the capability table marks that backend Beta and process-local, explicitly not for production. Verify first which surfaces you actually need by reading maturity.md, because the A2A gateway, the LLM streaming agent runtime and the Connector Runtime are all Beta while HTTP plus CloudEvents and the Kafka and RocketMQ storage plugins are the GA targets.

## FAQ

### How do I run Apache EventMesh locally without installing a broker?

Run the container with the default in-memory storage backend: docker run apache/eventmesh. The capability table marks that backend Beta and process-local, and says to switch EVENTMESH_STORAGE_TYPE to kafka, rocketmq or rocketmq5 for anything beyond development.

### Which EventMesh features are GA and which are still Beta?

The capability status table in maturity.md marks HTTP plus CloudEvents and the Kafka and RocketMQ storage plugins as GA targets. Memory storage, SSE and WebSocket push, the Connector Runtime and the A2A or Agent Gateway are marked Beta, and the table is described as the single source of truth for status.

### Does Apache EventMesh use Kafka consumer groups?

No. The README states the message queue acts as a pure write-ahead log with no consumer groups, no tags and no broker-side subscription semantics. A SubscriptionManager inside the stateless runtime holds the subscription registry and offset tracking and dispatches with load-balance, broadcast and multicast semantics.

## Sources

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

---

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