Multi-Tenancy

Multi-tenancy support lets a single application instance serve multiple tenants while keeping each tenant’s data separated, both in transit and at rest. Each tenant is represented by a dedicated Axon Server context: commands, events, and queries are routed to the context of the tenant they belong to, and every tenant’s events are stored in its own event store.

Tenant management

Covers how tenants become known to the application: static configuration at startup, dynamic discovery and removal at runtime through Axon Server, filtering which contexts are treated as tenants, and how the tenant of a message is resolved during processing.

See Tenant management for details.

Tenant-scoped components

Covers registering application-specific, tenant-scoped components, such as a per-tenant SQL datasource, and injecting the correct tenant’s instance into message handling methods.

See Tenant-scoped components for details.

Commands

Covers routing each command to the Axon Server context of its resolved tenant, and re-establishing tenant information on the handling side.

Event storage

Covers per-tenant event stores: appending to and sourcing from the event store of the tenant resolved from the message, including per-tenant snapshots.

See Tenant-aware event storage for details.

Event processing

Covers consuming every tenant’s events in one event processor, keeping each tenant’s projection separated, and picking up tenants added or removed at runtime, either from one merged stream over the per-tenant event stores or from a persistent stream per tenant.

Queries

Covers routing each query to the Axon Server context of its resolved tenant, mirroring the approach used for commands.

Example application

A runnable demo runs the university domain for several tenants at once, showing these features wired into a working application.

Adding the module

Multi-tenancy support ships in the axoniq-multi-tenancy module:

<dependency>
    <groupId>io.axoniq.framework</groupId>
    <artifactId>axoniq-multi-tenancy</artifactId>
    <version>${axoniq.version}</version>
</dependency>