Timeout Migration

Axon Framework 5 keeps the same handler- and processing-timeout behavior introduced in Axon Framework 4.11, with the same default values. The Spring Boot property names and the programmatic configuration API have both changed to match Axon Framework 5’s terminology and configuration model. For a complete description of the current behavior, see Timeouts.

The most notable changes are:

  • Property rename: axon.timeout.transaction. becomes axon.timeout.unit-of-work., matching the ProcessingContext/UnitOfWork terminology used throughout Axon Framework 5. The query bus property also changes from axon.timeout.transaction.query. to axon.timeout.unit-of-work.query-bus., for consistency with command-bus.

  • Handler-level properties unchanged: axon.timeout.handler.events/commands/queries.* and axon.timeout.enabled keep the same names.

  • Deadline timeouts removed: axon.timeout.handler.deadlines. and axon.timeout.transaction.deadline. have no equivalent, since Axon Framework 5 has no DeadlineManager or @DeadlineHandler. See Migrating deadlines.

  • Configuration API overhaul: the mutable, setter-based HandlerTimeoutConfiguration and the manually registered UnitOfWorkTimeoutInterceptor are replaced by immutable HandlerTimeoutConfiguration/TimeoutUnitOfWorkFactoryConfiguration components, registered once on the ComponentRegistry and applied automatically to every CommandBus, QueryBus, and EventProcessor.

Spring Boot properties

Axon Framework 4 property Axon Framework 5 property

axon.timeout.enabled

axon.timeout.enabled

axon.timeout.handler.events.*

axon.timeout.handler.events.*

axon.timeout.handler.commands.*

axon.timeout.handler.commands.*

axon.timeout.handler.queries.*

axon.timeout.handler.queries.*

axon.timeout.handler.deadlines.*

Removed

axon.timeout.transaction.command-bus.*

axon.timeout.unit-of-work.command-bus.*

axon.timeout.transaction.query.*

axon.timeout.unit-of-work.query-bus.*

axon.timeout.transaction.event-processors.*

axon.timeout.unit-of-work.event-processors.*

axon.timeout.transaction.event-processor.<name>.*

axon.timeout.unit-of-work.event-processor.<name>.*

axon.timeout.transaction.deadline.*

Removed

Each property still has timeout-ms, warning-threshold-ms, and warning-interval-ms suffixes, unchanged.

Handler timeout configuration

Axon Framework 4 required a mutable HandlerTimeoutConfiguration, configured through setters and registered via a HandlerEnhancerDefinition on the Configurer. Axon Framework 5 registers an immutable HandlerTimeoutConfiguration component directly on the ComponentRegistry. The framework applies it automatically, with no separate HandlerEnhancerDefinition registration needed.

  • Axon Framework 4

  • Axon Framework 5

public class MyTimeoutConfigurerModule implements ConfigurerModule {

    @Override
    public void configureModule(@NotNull Configurer configurer) {
        HandlerTimeoutConfiguration config = new HandlerTimeoutConfiguration();
        config.getEvents().setTimeoutMs(30000);
        // Set any timeouts and warning thresholds you would like here
        configurer.registerHandlerEnhancerDefinition(c -> new HandlerTimeoutHandlerEnhancerDefinition(config));
    }
}
public void configureTimeoutBehavior(MessagingConfigurer configurer) {
    configurer.componentRegistry(cr -> cr.registerComponent(
            HandlerTimeoutConfiguration.class,
            c -> new HandlerTimeoutConfiguration(
                    HandlerTimeoutConfiguration.DEFAULT.getEvents().timeoutMs(30000),
                    HandlerTimeoutConfiguration.DEFAULT.getCommands(),
                    HandlerTimeoutConfiguration.DEFAULT.getQueries()
            )
    ));
}

The @MessageHandlerTimeout annotation is unchanged between Axon Framework 4 and 5, except that it no longer applies to @DeadlineHandler methods, since deadlines do not exist in Axon Framework 5.

Processing context (Unit of Work) timeout configuration

Axon Framework 4 required registering a UnitOfWorkTimeoutInterceptor by hand as a handler interceptor on each component (CommandBus, QueryBus, every EventProcessor), including a startup-ordering workaround to make sure the interceptor was registered before the component started dispatching messages. Axon Framework 5 replaces this with a single TimeoutUnitOfWorkFactoryConfiguration component: the framework decorates the UnitOfWorkFactory of every CommandBus, QueryBus, and EventProcessor with it automatically.

  • Axon Framework 4

  • Axon Framework 5

public class MyTimeoutConfigurerModule implements ConfigurerModule {

    @Override
    public void configureModule(@NotNull Configurer configurer) {
        configurer.eventProcessing().registerDefaultHandlerInterceptor((c, name) -> new UnitOfWorkTimeoutInterceptor(
                "EventProcessor " + name,
                30000,
                25000,
                1000));

        // Register a transaction timeout for the command bus
        configurer.onStart(Integer.MIN_VALUE, () -> {
            configurer.buildConfiguration().commandBus().registerHandlerInterceptor(new UnitOfWorkTimeoutInterceptor(
                    "CommandBus",
                    30000,
                    25000,
                    1000));
            // You can do this for the queryBus() and deadlineManager() as well
        });
    }
}
public void configureTimeoutBehavior(MessagingConfigurer configurer) {
    configurer.componentRegistry(cr -> cr.registerComponent(
            TimeoutUnitOfWorkFactoryConfiguration.class,
            c -> new TimeoutUnitOfWorkFactoryConfiguration(
                    new TaskTimeoutSettings(30000, 25000, 1000), // command bus
                    new TaskTimeoutSettings(30000, 25000, 1000), // query bus
                    new TaskTimeoutSettings(30000, 25000, 1000), // event processors without specific settings
                    Map.of()                                     // settings per named event processor
            )
    ));
}

For settings that must be computed dynamically, register a ConfigurationEnhancer instead of a static component:

// Spring users can make a Spring bean of the ConfigurationEnhancer to auto inject it into Axon.
public class TimeoutConfigurationEnhancer implements ConfigurationEnhancer {

    @Override
    public void enhance(ComponentRegistry registry) {
        registry.registerIfNotPresent(
                TimeoutUnitOfWorkFactoryConfiguration.class,
                c -> new TimeoutUnitOfWorkFactoryConfiguration(
                        new TaskTimeoutSettings(30000, 25000, 1000), // command bus
                        new TaskTimeoutSettings(30000, 25000, 1000), // query bus
                        new TaskTimeoutSettings(30000, 25000, 1000), // event processors without specific settings
                        Map.of("slow-processor", new TaskTimeoutSettings(60000, 50000, 1000))
                )
        );
    }
}

// Somewhere in your configuration class...
public void registerTimeoutEnhancer(MessagingConfigurer configurer) {
    configurer.componentRegistry(
            cr -> cr.registerEnhancer(new TimeoutConfigurationEnhancer())
    );
}

Disabling timeouts

The axon.timeout.enabled=false Spring Boot property still disables all timeouts, unchanged from Axon Framework 4. For declarative configuration, Axon Framework 5 adds explicit DISABLED constants, rather than requiring you to leave the configuration unregistered:

public void configureTimeoutBehavior(MessagingConfigurer configurer) {
    configurer.componentRegistry(
            cr -> cr.registerComponent(
                    TimeoutUnitOfWorkFactoryConfiguration.class,
                    c -> TimeoutUnitOfWorkFactoryConfiguration.DISABLED
            ).registerComponent(
                    HandlerTimeoutConfiguration.class,
                    c -> HandlerTimeoutConfiguration.DISABLED
            )
    );
}