Flowable CMMN timer, user and variable event listeners

Event listeners let a Flowable case react to a due time, a user action or a changed variable without a fixed sequence. This page explains how each type works, what to configure, and what to confirm before you build.

On this page

When Flowable CMMN event listeners fit a case

A Flowable CMMN case needs event listeners when work in progress has to respond to a deadline, a person's action or a change in case data, and a fixed sequence of tasks would either wait too long or act too early. A timer event listener fires when a configured time condition is met, a user event listener waits for a person to perform an action such as a manual trigger, and a generic event listener (also called a variable event listener) reacts when a case variable changes so that a condition can be evaluated. Each of these is a plan item that sits in the case model and becomes available only when its criteria allow, so the case can keep moving on other work while it waits.

Choose event listeners when the trigger is an event that can happen at any point, not a step that always follows the previous one. A supplier confirmation that may arrive late, a review that a manager must acknowledge, or a risk score that changes during an open file are typical cases. The Flowable CMMN documentation describes how each listener type is modeled and what its available conditions are, and the team should confirm those details against the version it plans to run, since the engine changes across major releases. Also decide when each listener is removed, because a listener that stays active after its purpose has passed can fire on stale data.

Before modeling, list every trigger the business cares about and name the owner who can act on it. For each one, ask whether the trigger is time-based, human-initiated or data-driven, and whether more than one variable can satisfy the same condition. Those answers decide which listener type fits and how many are needed. Confirm with your Flowable team how timers are scheduled and recovered after a restart, because the async executor manages timers from a thread pool across nodes, and that behavior affects how reliable a deadline is in production.

Timer, user and variable listeners compared

A timer event listener waits for a time-based trigger and fires when the timer expression is satisfied. The case must supply that expression, usually as a date or duration resolved from case variables, so the model is only as reliable as the data behind it. Timers also depend on the async executor, which runs timer jobs from a thread pool and recovers expired locks across nodes, so firing time depends on job execution and node availability.

  • Trigger: the timer expression is satisfied after the listener becomes active.
  • Typical uses: reminders when a customer has not responded, escalation of waiting work, or a review date tied to a contractual deadline.
  • What the case must provide: a date or duration expression built from case variables, with the time zone and date format agreed in the model.
  • Activation pitfall: a duration counted from case creation when the listener only becomes active later will fire earlier than the business expects.
  • Cluster pitfall: a timer that is due during a node outage fires when another node picks up the job, so expected timing should be described as a window, not an exact moment.

Confirm how your Flowable version evaluates timer expressions and time zones before you write business rules that depend on exact deadlines.

How to configure listeners in a Flowable case model

This sequence takes a case from design to tested behavior, so each timer, user and variable event listener fires on the trigger it was meant for and nowhere else.

  1. Model the case and its plan items

    A case designer lays out the stages, human tasks and milestones the listeners will react to, and names each plan item in terms the business uses. Confirm which plan items must be active before a listener can meaningfully fire, because a listener only matters once its surrounding stage or task is in play. Done when every plan item that a listener will watch or wait on has a stable, unique identifier in the model, and a reviewer can point to the work each one represents.

  2. Add each listener with its trigger and condition

    For each requirement, choose the listener type that matches the trigger: a timer listener for elapsed time, a user event listener for a person acting on the case, or a generic event listener for a change in case data. Write the available condition, the expression that must be true before the listener can complete, and confirm the exact element names and expression syntax against the Flowable CMMN documentation for your engine version. Done when each listener in the model has one written trigger, one written condition, and a reviewer has confirmed that no two listeners claim the same event.

  3. Define the variables and roles each listener depends on

    Declare every case variable a condition reads, including the variables that multiple variable event listeners watch, and set the types and default values the expressions expect. Identify the user or group that may trigger each user event listener, and record where those assignments come from in your identity system. Confirm with your application team that the code paths that set these variables run in the order the model assumes. Done when every variable referenced in a condition is declared, every user event listener has a named assignee source, and a test data set exists that sets each variable.

  4. Deploy the case definition to a test environment

    Package the case model and deploy it through the same pipeline your team uses for process definitions, then start a case instance in a non-production environment with the expected identity and variable setup. Check the deployed definition in the engine's repository or REST API to confirm the listeners appear as expected and that the version number is the one you intended. Done when the deployed definition lists each listener, the case starts without deployment errors, and the listeners report the state the model predicts on a fresh instance.

  5. Test a timer listener fires once the expected time passes

    Start a case instance, let the timer's configured time pass in a controlled test environment, and observe whether the timer listener triggers exactly once and moves the case to the next state. Repeat with the time set just before the threshold to confirm the listener does not fire early. Check the job or history records the engine writes so you can show when the timer was scheduled and when it fired. Done when the timer fires once at the expected point, and the case state after firing matches the model.

  6. Test a user event listener with an authorized and an unauthorized user

    Trigger the user action the listener is waiting for, first as a user the model authorizes and then as a user it should reject, and record the result of each attempt. Confirm that the authorized action completes the listener and that the unauthorized attempt leaves the case unchanged. Include a case where the required precondition is missing, so you can see that the listener waits rather than firing. Done when both outcomes match the written expectations and the audit trail shows who acted and when.

  7. Test variable event listeners with set and changed values

    Set the watched variables to values that satisfy the condition, then to values that do not, and confirm the listener reacts only to the first case. Where multiple variable event listeners watch different variables, change each variable in turn and in combination to confirm that each listener responds to its own trigger without interfering with the others. Done when every variable test produces the expected result, and the test records show no listener completing on a variable it does not watch.

  8. Run a full test case per trigger and confirm removal

    Run one end-to-end test case for each trigger, covering the path where the listener fires and the path where the case completes or the listener is removed before firing. Confirm that listeners removed automatically once their plan item terminates do not fire later, and record the final case state. Keep these tests in your regression set so any later model change is checked against each trigger. Done when every trigger has a passing end-to-end test, the removal behavior is verified, and the team has signed off the test evidence before production deployment.

Listener options and when each fits

This table compares the four ways a Flowable CMMN case can react to events: timer, user event, generic event on a variable and multiple variable event listeners, along with the available conditions that gate them. Read each row as a question about your case: what triggers the reaction, what it depends on, and how much testing it takes to trust it. The main takeaway is that timer and user listeners are the simplest to reason about, while variable listeners need the most careful condition design and testing.

Listener optionTypical use caseDependencies and setupTesting effort
Timer event listenerReacting after a deadline, such as escalating a case that has waited too longDue date or timer expression evaluated by the engine's async job handlingModerate: verify date logic and the async executor in a test environment
User event listenerLetting a case worker trigger an action such as cancelling or reopening a stageApplication or REST call to complete the listener, plus an authorization check you buildLow to moderate: test the trigger path and who is allowed to fire it
Generic event listener on a variableReacting when case data changes, such as a credit score or document status being setVariable name and an available condition evaluated on the changeModerate to high: test each change path and the condition on edge values
Available conditionLimiting when a listener can fire, such as only when a stage is activeExpression tied to case or plan item variables, reviewed in the modelModerate: each condition needs a positive and negative test case
Multiple variable event listeners on one caseReacting to several data points in one case, each with its own ruleMore listeners increase model complexity and overlapping trigger behaviorHigh: test combinations of variables and their ordering
Automatic removal of listenersCleaning up listeners that are no longer relevant after a stage or case endsDepends on the case lifecycle in the model; confirm exact behavior in the Flowable CMMN docsModerate: test that listeners stop firing after completion or termination

How timer events depend on the async executor

Timer events in a Flowable case are not fired by the case engine on its own schedule. They are handled as jobs by the async executor, which runs timers and asynchronous jobs from a thread pool. According to the Flowable advanced documentation, the executor coordinates multiple nodes through lock owners and lock expiration times stored in the database. A node that claims a timer job sets a lock with an expiry. If that node stops before finishing, the lock expires and another node picks the job up. For a timer listener, this means the moment the condition fires is only as reliable as the executor that runs it, so the executor settings belong in the design review for any case that depends on a deadline.

In a clustered deployment, the practical consequences are about where timers run and how long a lock can be held. Every node that shares the database competes for the same jobs, so you should confirm that all nodes point at the same database and use the same executor configuration, and that the lock duration is set with your longest job in mind. Plan a test where one node is stopped while a timer is pending and check that another node fires the listener after the lock expires. Also confirm how many executor threads each node runs, because a busy node with a full thread pool will delay timers even when no lock is involved.

Timer accuracy depends on two things you should confirm with Flowable and in your own environment rather than assume: the clock used to compare due dates on each node, and the timestamp precision of your database. The Flowable configuration documentation notes that MySQL versions below 5.6.4 lack millisecond precision, which affects how exact due times are stored. Keep the application servers' clocks synchronized with a common time source, and test a short timer on your exact database and platform version before you promise a business deadline. Record the expected firing tolerance in the case design so operations knows what a late timer looks like.

Security and operational risks in listener-driven cases

Event listeners let a case react to time, user actions and data without a person starting each step, which moves control decisions into listener definitions and conditions. The risks below sit at the boundary between the engine and your application, so they need owners on both sides before go-live.

User events need business authorization

The engine checks that a user event can be raised on a listener, but it does not decide whether this user may trigger this transition on this case. A user event listener that completes a review or approves a payment must be backed by an authorization check in your application or REST layer. Confirm who may raise each user event, and test that a user outside the role is refused through the same API your front end calls.

Sensitive data in event conditions

Available conditions and variable event listeners read case variables, so any personal or financial value placed there can end up in expressions, logs and history. Keep sensitive values out of variables a listener evaluates where you can, pass references instead, and check which variables appear in history retention and audit output. Review each condition expression with the people who own the data.

Listener actions without an audit trail

When a listener fires, a plan item may start, complete or terminate without any user action, and the reason may be hard to reconstruct later. Decide which transitions must be attributable, record who or what raised each user event, and confirm that the history your compliance team relies on includes listener-triggered changes. Test this with a trace of one complete case.

Overlapping listeners repeating transitions

Two listeners watching the same variable or event can both fire for one change, and a timer can reopen work that a user has already closed. Map every listener to the plan items it can start or terminate, and identify pairs that can act on the same case instance. Add a guard condition or a single owning listener for each outcome, then test repeated variable updates.

Misconfigured timers creating unexpected work

A timer with the wrong duration, time zone or repeat setting can start tasks in large numbers or at times no one planned, and the async executor will run them on whatever nodes are available. Review each timer expression against business calendars, and check how timers behave across cluster nodes and after restarts. Ask your vendor or the docs which timer behaviors apply to your engine version.

Listener behavior after an upgrade

Listener semantics, expression handling and event processing can change between major versions, so a case that behaved correctly on one release may act differently on the next. Version 7 moved to Java 17, Spring Boot 3 and Jakarta EE, and version 8 moved to Spring Framework 7 and Spring Boot 4. Before any upgrade, rerun listener test cases against the target version and compare results with the release notes.

Questions teams ask before building listener-driven cases

How much more effort is a listener-driven case than a fixed plan?

A listener-driven case usually takes more design and test effort than a fixed plan, because every timer, user action and variable event listener adds a path the team must model, reason about and verify. A fixed plan has one sequence to check. A listener-driven case has to answer what happens when the event arrives early, late, twice, or never, and what happens to work already in progress. The extra effort sits mostly in the design review and the test matrix, not in the diagram itself. Ask any partner to show how they will enumerate listener combinations before they quote.

What does the work need from our team?

Three groups are needed. Domain experts must define which events matter to the business, what counts as a valid trigger, and which outcomes are acceptable when time passes without action. A Java developer must write or review the listener logic, expressions and any delegates that set or read case variables. Your team also needs a test environment that matches the production database and job executor settings closely enough to exercise timers. Agree on who owns each decision before the build starts, because unresolved ownership is one of the most common causes of delay.

Can our own team build a listener-driven case alone?

A team with Flowable CMMN experience and Java skills can build a listener-driven case without a partner, provided it has someone who understands the case model, the timer semantics of the async executor and the test approach for time-based behavior. Teams new to CMMN often underestimate how much time goes to explaining listener lifecycle and removal behavior to reviewers. A partner is most useful for the design review, a second pair of eyes on edge cases and a planned test suite. Whichever path you choose, the Flowable documentation on advanced topics is the reference to check timer and job behavior against.

How do timing and testing affect the schedule?

Timing and testing usually set the critical path. Timer listeners depend on the job executor, so tests that wait for real time are slow and fragile, and teams need a way to advance or inspect time in their test setup. Each user action listener needs a scenario that completes, one that is ignored, and one that arrives out of order. Plan a block of time for testing against a database that matches production, including the database type you run, because timer precision and locking behavior vary by database. Confirm the expected test duration with your partner or internal lead rather than relying on a general estimate.

What is the risk of timers and listeners running in a multi-node deployment?

Timers and asynchronous jobs run on the Flowable async executor, which coordinates nodes through lock owners and lock expiration times stored in the database. This means a timer should fire once across a cluster, and expired locks let another node pick up work from a node that failed. Your design still needs to be idempotent, so that a listener action that runs twice does not create duplicate plan items or send duplicate notifications. Ask your team to confirm how your deployment sizes the executor and how your database handles locking before going live.

What drives the cost of a listener-driven case up or down?

The main cost drivers are the number of distinct events the case reacts to, how many of those events interact with each other, and how many external systems supply the events. Multiple variable event listeners that watch several variables at once raise the design and test load because each combination can change which plan items are available. Integration with identity, notification or document systems adds build and test work on both sides. Costs fall when the event model is narrowed to what the business needs, when the case reuses existing delegates and when test data and scenarios are defined early. Ask any quote to itemize listeners, integrations, test scenarios and documentation separately, and to state which items are one-time and which recur during maintenance.

What should we ask for in a written scope before work starts?

Ask for a list of every timer, user and variable event listener with its trigger, its available condition and the plan item it affects. Ask for the removal behavior of each listener, including what happens when the case completes or the plan item terminates. Request the test scenarios that will prove each path, the environment used for testing and the handover material your team will keep. Ask how the work handles future changes to the case model, since listeners often need updating when a new version is deployed. DeployOpen plans most engagements as fixed scope, with scope, deliverables and timelines agreed in writing before work begins.

How DeployOpen scopes listener work on Flowable

DeployOpen scopes Flowable listener work in writing before any build starts. For timer, user and variable event listeners, the written scope names each listener on each case plan item, the trigger it reacts to, the available condition that gates it, the case variables it reads or sets, and the test cases that prove the behavior. The scope also states where the case definitions are deployed and how changes move from a development environment into production inside your own cloud accounts, data centers or air-gapped network. Agreeing these points early matters because listener behavior is hard to reason about from the model alone, and a timer that fires on a condition nobody tested is the kind of defect that surfaces months later.

Your team should confirm several decisions before the scope is signed. Decide which events must be handled by a timer listener, which by a user event listener for a human action, and which by a generic or variable event listener that waits for data to change, including whether multiple variable event listeners on one plan item are needed and how their conditions interact. Confirm how automatic removal of listeners is expected to behave for each case type, and who owns the test data that exercises each path. Ask for the Flowable version your engines will run on, since the release notes for Flowable 8.0.0 list baseline changes that affect the build and test stack. Ongoing work after go-live, such as adding listeners as cases evolve or responding to engine upgrades, can be covered by a retainer agreed alongside the fixed-scope build.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.