Multi tenancy support


We are experimenting with Axon framework for our multi tenant application and it need to have a different schema for each tenant which will include Event store, read model and all Axon default tables per tenant.

Axon server is excluded from project and MYSQL is configured as an event store.

  • Request interceptor is fetching tenantID from header and inserting in thread local.
  • Inserting tenantID in message metadata using CorrelationDataProvider.
  • On projection event handler using MessageHandlerInterceptor to pass tenantID into thread local.
  • Thread local is used inside AbstractRoutingDataSource for database switching dynamically.
  • Events are being saved successfully in tenant specific event stores.
  • Now problem is with projection not being updated and looks like nothing is being published. No handler is being fired on projections.


Great, you’ve already hit the majority of the configurable components you’d need to touch to make multi-tenancy work.

I am guessing the missing link right now as how your Event Processors are configured. Out of the box, an Event Handling Component (read: the class with @EventHandler annotated methods in it) will be configured to an Event Processor. In turn an Event Processor may control several Event Handling Components, typically grouping those closes which logically belong to one another.

To control where an Event Handling Component is place, you can either change the assignment rules for event handlers in the EventProcessingConfigurer, or you can use the @ProcessingGroup annotation. The latter would mean every Event Handling Component which belongs in the same processing group, would carry the @ProcessingGroup("my-processing-group") annotation.

I felt the above was worth sharing, as I don’t know how far you went with configuring your Event Handlers. With this in place, you can validate what type of message source your Event Processor are using. By default, this would be the EventStore. You have however adjusted the EventStore to store events in different tables, on the fly. Have you validated whether reading on the fly switches to the type of source you need?

Chances are high something’s amiss with how the source for your Event Processor is defined. If you have any configuration on this, please share it in the thread. Based on that we can look further how to resolve the problem at hand.

PS, note that a RDBMS will eventually not be the optimal solution as an Event Store. This recording from Allard Buijze clearly states why AxonIQ has constructed Axon Server as a dedicated Event Store solution. Regardless of which road you will take, checking that out can be worthwhile to better understand the ideas behind an Event Store.