Apply a new event after a delay: scheduled event or deadline?

We are developing an Axon application (version 3.4) and have a need to wait for an external party without receiving any acknowledgement from them that they are ready.

Steps are:

  1. Handle events that offers have been made to applicants.
  2. On an external schedule (e.g. daily), collate those offers by institution into files and upload them into a collection area.
  3. Send a notification email to each institution.
  4. Wait 2 hours.
  5. Send notifications to each of the applicants about their offers.
    I am looking for the best way to implement step 4. We need to reliably wait for two hours and then send notifications to all the applicants, surviving loss of any of our application cluster nodes.

Using QuartzDeadlineManager.schedule on the Offer aggregate seems the simplest solution. When we tried that with a short delay (10 seconds) but the @DeadlineHandler method was never called.

Perhaps our Spring Boot configuration of QuartzDeadlineManager was not correct. Does anybody have some Spring Java / Kotlin configuration they can share that would help us?

Thanks in advance
Michael Strasser

Hi Michael,

The deadline message you schedule in the Offer aggregate, is it that exact aggregate instance which has the @DeadlineHandler in it as well, or is that handler contained in the Applicant (aggregates)?
Note that the DeadlineManager schedules a message in the scope of a single aggregate or saga instance.

If you want to span several instances with a given deadline, you should either:

  1. Schedule this deadline in all the aggregate instances which should react to it, or
  2. React on the scheduled deadline in a Saga which regulates this ‘complex business transaction’ between the Offer and all it’s Applicants.

Hope this helps Michael!


Hi Steven

Thanks for your reply.

We did have @DeadlineHandler on a method in the Offer aggregate and found that it worked when using the SimpleDeadlineManager. So the answer to my issue appears to be in configuring QuartzDeadlineManager correctly.

We have since adopted a different approach, which is working for us.


Hi Michael,

That’s a bothersome, and interesting, situation you have encountered there.
Did you by any chance perform some tests to verify the QuartzDeadlineManager was actually storing and trigger a deadline message in your setup?
If you have any information on this, that would be valuable, as I would very much like to remove any bugs present in the QuartzDeadlineManager.

Additionally, I’d be interested to know what the different approach is you took to scheduling these triggers.


Hi Steven

No, sorry, we didn’t follow up on QuartzDeadlineManager. I am reasonably sure that correct Quartz + Spring configuration would have sorted it out.

We never saw the log message generated by this code in the Offer aggregate (Kotlin):

@DeadlineHandler(deadlineName = “notifyDeadline”)
fun onDeadline() {“Deadline {} handled”, this.notifyDeadline)

When I used SimpleDeadlineManager I did see the log message. Sorry, but I do not have time to pursue it further.

Our approach was to not use Axon timing but to have an external scheduler that runs a check function at regular intervals (e.g. every 5 minutes):

  • The check function, which runs on multiple nodes, uses Spring Integration leader election to determine which is the current leader. (We are using this technique in a couple of places.)
  • The leader check function queries a projection of offers to select those without applicantNotifiedTimestamp and whose sentToInstitution timestamps are more than 2 hours old.
  • Send a NotifyApplicantCommand to each of those Offer aggregates.

This is working well enough for our needs. In the future we will probably start using sagas and deadlines. Then we will need robust, Quartz-based timing.


Hi Michael,

Thanks for the background on this.
Might proof to be useful somewhere in the future.

For now, I am happy to hear you’ve found a worthwhile solution in your use case.

As soon as you start using Sagas + DeadlineMessages and you hit the same wall, you know where to find us.

However, I hope it’ll just work out of the box at that point in time. :wink: