Start Process always on the last day of the month at 10:00 am

Hi all,

how can a Timer Start Event always be triggered on the last day of the month at 10:00 am (on Camunda Platform 8)?

This (or even a simpler requirement like “every 15th day of the month at 10:00”) is not possible with Timer events | Camunda Platform 8

Camunda Platform 7 supports cron which could solve the simpler requirement and possibly also the initial requirement. Are there any plans to support cron on Camunda Platform 8?


  1. The “cron” could be a scheduler in the (Spring Boot) application and this triggers the Start Event but we would need to make sure we don’t have multiple instance of the application.
  2. Alternatively, the timer event could be configured to be triggered daily (R/P1D) and then we filter out all days we’re not interested in. But how do we make sure that this is always at 10:00 am?

How would you solve this?

Update: found this (Feature Request: On Timer events add scheduling at specific time · Issue #3038 · camunda/zeebe · GitHub) which is related but would not solve my question either.


Hi Tobias,

thank you for raising this up. It is an interesting question!

Cron expressions are not planned yet.

One way would be to write a cycle FEEL expression for the timer. For example:

firsDayOfMonth: date(today().year, today().month, 01),
lastDayInMonth: firsDayOfMonth + duration("P1M") - duration("P1D"),
nextLastDayInMonth: if(today() < lastDayInMonth) then lastDayInMonth else lastDayInMonth + duration("P1M"),
scheduleTime: date and time(nextLastDayInMonth, time("10:00:00Z")),
durationToSchedule: scheduleTime - now(),
cycle: cycle(durationToSchedule)

It calculates the duration until the next end of the month and put it into a cycle expression (i.e. R/...).

Does this work for you?

Best regards,


Hi @Philipp_Ossler ,

thanks a lot for that creative approach!

With your hint I found the documentation mentioning cycle(...) on Expressions | Camunda Platform 8

Where is the syntax you used: {....}.cycle documented?

Actually, the solution is not quite correct because the cycle always has the duration “durationToSchedule” but actually this is only the correct value until the first timer event. All following need a cycle duration of one month.


1 Like

If I am not mistaken, I believe {…} is simply a JSON object and .cycle is used to access the cycle attribute of the object.

Yes, I agree.

1 Like

No. It is not that simple :smiley:

First, the expression is evaluated each time when the timer is triggered. So, it calculates the duration for the next month each time.

Second, the logic to trigger a timer at the end of the month is tricky. The months have a different number of days. If it’s the end of June (2022-06-30) and you add one month (+ P1M) then the date is not the end of July (2022-07-30 != 2022-07-31).

1 Like

It is good to know that expression is evaluated each time the timer gets triggered.
This is really a clever workaround solution @Philipp_Ossler

In one of the other systems I worked with, we used to see a lot of:
LastDayOfMonth= date(today().year, today().month+1, 00)
Which honestly I think takes advantage of a few bugs (eg. most Java runtimes understand that 2021-13 = 2022-01 and that DayOfMonth 00 = First of the Month -1)

I feel like Phillipp’s expression is a lot clearer to the reader


Thanks @Philipp_Ossler . The solution works for me :+1:

Just a note to myself (and anyone else interested): remember to put = before {....}.cycle so that it is interpreted correctly as a FEEL expression.


Hi @tobiasschaefer. Currently I am supporting cron expression parsing feature. :man_technologist:
If you are interested, please keep following this PR :facepunch:

EDIT: This PR camunda/zeebe#9674 has been merged. :rocket: