Meet Axon Framework & Axon Server
Get introduced to Axon Framework and Axon Server, the toolkit that implements CQRS and event sourcing's plumbing for you, and bring up a local Axon Server instance to connect a Spring Boot service to.
Learning objectives
- Explain what Axon Framework and Axon Server each do, and why they are two separate things
- Run Axon Server locally with Docker for development
- Add the Axon Spring Boot starter to a service and point it at Axon Server
- Recognize and avoid the most common startup connection mistake
◆ Story
Say you need to ship ten packages this week. One option is to build your own delivery operation from scratch: trucks, drivers, sorting facilities, a tracking system. It would eventually work, but you'd spend months building infrastructure before a single package moved. The obvious alternative is to hand your packages to an existing courier that has already solved routing, delivery, and confirmation at scale, and let their system do the work.
Building a reliable event-sourcing engine by hand is a similar amount of work. You'd need something that durably stores every event a system produces, replays those events in the right order to rebuild an object's state, and routes commands and queries to the correct handler across possibly several running services. Getting all of that right — especially the concurrency, since multiple commands can arrive for the same object at nearly the same time — is a genuinely serious project on its own, independent of any actual business logic you wanted to write.
Axon Framework and Axon Server exist to remove that project from your plate. Axon Framework is a Java library you add to a Spring Boot service; it gives you annotations and interfaces for expressing commands, events, and queries. Axon Server is separate infrastructure that Framework talks to over the network: it stores events durably and routes messages between services. Together, they let you focus entirely on deciding what a command should do and what event it should produce, while the framework and server handle storage, replay, and delivery underneath you.
From here on you will use both pieces constantly: Axon Framework's annotations inside your Java classes, and Axon Server as the always-on infrastructure those classes connect to.
It helps to be precise about what each piece is actually responsible for, because conflating them is a common source of early confusion.
Axon Framework is a library, not a service. You add it as a dependency to your Spring Boot project, and it contributes a set of annotations and classes — @Aggregate, @CommandHandler, @EventSourcingHandler, @EventHandler, @QueryHandler, along with gateways like CommandGateway and QueryGateway — that you write against inside your own code. Nothing about Axon Framework runs outside your application's process; it's compiled into your service just like any other library.
Axon Server is different: it's a standalone piece of infrastructure your service connects to over the network, much like a database or a message broker. It plays two roles at once. First, it's the event store — the durable, append-only log that every event your services publish ends up written into, permanently. Second, it's the message router: when one service sends a command, publishes an event, or issues a query, Axon Server is what actually delivers that message to whichever handler, in whichever service, is registered to receive it.
That second role matters more as soon as you have more than one microservice. Picture a bank-style system split across Customer, Accounts, Cards, and Loans services. An event published inside the Customer service — say, a customer's email address changed — might matter to a projection running inside the Accounts service too. Neither service needs to know the other exists on the network, know its address, or manage a direct connection to it. Both simply connect to Axon Server, and Axon Server takes care of getting the event from wherever it was published to everyone who's registered interest in it.
Without this separation, every service would need its own hand-rolled way of storing events durably and its own way of discovering and calling every other service that might care about a given message — exactly the kind of plumbing this framework and server exist to remove from your list of problems.
Getting a working setup takes two steps: start Axon Server itself, then tell a Spring Boot service how to find it.
Axon Server ships as a Docker image, which makes local development straightforward — no manual installation, no separate JVM to manage by hand. Running the container exposes two ports that matter. Port 8024 serves Axon Server's own web dashboard, a browser UI where you can inspect the event store directly, watch events arrive in real time, and confirm the server is actually healthy. Port 8124 is the gRPC port your Spring Boot services connect through to send commands, publish events, and issue queries — this is the port your application configuration needs to know about, not 8024.
Once the container is running, opening http://localhost:8024 in a browser and seeing the dashboard load is the fastest way to confirm Axon Server is actually up before you try connecting anything else to it.
On the application side, adding Axon to a Spring Boot service is a normal Maven dependency plus a small amount of configuration in application.yml pointing at the gRPC port. Once that's in place and the service starts successfully, it registers itself with Axon Server and is ready to have commands routed to it, publish events into the shared event store, and answer queries.
▲ Common mistake
Starting your Spring Boot service before Axon Server itself is up and healthy is an easy trap early on. You'll see connection errors in your service's logs that look alarming — stack traces, retry warnings — but they almost always just mean "Axon Server isn't reachable yet," not that anything is actually broken. Before troubleshooting your service's own configuration, always check that Axon Server's dashboard is loading successfully first.
💻 Code example
# 1. Start Axon Server locally with Docker. # Port 8024 = web dashboard, port 8124 = gRPC (your services connect here). docker run -d --name axonserver \ -p 8024:8024 -p 8124:8124 \ axoniq/axonserver # 2. Add the Axon Spring Boot starter to your service's pom.xml. <dependency> <groupId>org.axonframework</groupId> <artifactId>axon-spring-boot-starter</artifactId> <version>4.9.3</version> </dependency> # 3. Tell the service where Axon Server is, in application.yml. axon: axonserver: servers: localhost:8124
Beyond the startup-ordering mistake already covered, a few other habits trip up teams new to this stack.
Treating Axon Server as optional infrastructure you can skip in production, the way you might skip a local cache, is a serious misunderstanding of what it does. Axon Server is not a convenience layer sitting in front of a database you also maintain — for a service using event sourcing, it usually is the durable store of truth for that service's events. Losing it, or misconfiguring it so events silently fail to persist, is equivalent to losing your primary database.
Another common mistake is assuming every microservice needs its own separate Axon Server instance. In practice, a single Axon Server deployment (or an Axon Server Enterprise cluster in production, for high availability) typically serves many microservices at once, each connecting to it as a shared piece of infrastructure — much like several applications sharing one message broker.
Finally, teams sometimes assume the version of Axon Framework and the version of Axon Server must always match exactly. They don't need to be identical, but you should still track compatibility between the two, particularly across major versions, since protocol-level features can change between releases.
▲ Edge case
If a service reconnects to Axon Server after a network blip, any commands or queries it was mid-handling when the connection dropped may need to be retried by the caller — Axon Framework does not silently guarantee delivery across a full disconnect without some cooperation from the client issuing the original request. Building retry-awareness into callers of your command and query gateways is worth doing early, not as an afterthought once a flaky network causes a real incident.
This combination of Axon Framework and Axon Server is not a teaching-only simplification of CQRS and event sourcing — it's a stack genuinely used in production by companies that need strong consistency guarantees and a full audit trail of everything that happened in their system.
Financial services are a particularly natural fit, and not by coincidence: a bank-style system built this way, where every balance change, every loan approval, and every account modification exists as a permanent, ordered event, gives you an audit trail for free. Regulators asking "prove exactly what happened to this account, in what order, and why" can be answered directly from the event store, rather than by reconstructing history from scattered application logs and update timestamps.
Logistics and order-management systems benefit for a related reason: tracking a shipment or an order through many state changes (placed, paid, packed, shipped, delivered, returned) maps naturally onto a sequence of events, and different services can each maintain their own read-optimized view of that history without needing to query each other directly for it.
AxonIQ, the company behind Axon Framework, has published case studies of real companies in exactly these kinds of industries running this stack at production scale — this is genuinely used to build serious, high-consistency systems in domains where getting the history of "what happened and when" wrong is expensive, not a toy framework meant only for tutorials.
-
Q: What's the difference between Axon Framework and Axon Server? A: Axon Framework is the Java library you code against inside your Spring Boot service. Axon Server is separate infrastructure — the shared event store and message router that services connect to over gRPC.
-
Q: Why does an event published by one microservice reach a handler in a completely different microservice? A: Because both services connect to the same Axon Server instance, which routes the event to every registered handler, wherever it's running, without the publisher needing to know or care who's listening.
-
Q: What are ports 8024 and 8124 used for when running Axon Server? A: 8024 serves Axon Server's web dashboard for inspecting the event store; 8124 is the gRPC port your Spring Boot services actually connect through.
-
Q: You start your Spring Boot service and see alarming connection errors in the logs. What should you check first? A: Whether Axon Server itself is actually up and healthy — a service started before Axon Server is reachable is the most common cause of this exact symptom.
-
Q: Is Axon Server optional infrastructure you can skip in production? A: No — for a service using event sourcing, Axon Server is typically the durable store of truth for that service's events, not a convenience layer in front of some other primary database.
Want a visual for this concept?
Generate a diagram tailored to “Meet Axon Framework & Axon Server” — the AI picks whichever visual (flowchart, comparison, sequence, etc.) best fits.
Sign in to generate a visual →