13. Timer Events

Timer events enable deadline-based workflow automation. Flowable evaluates timers using its async executor.

Timer Event Types

Type BPMN Element Purpose
Boundary (Interrupting) <boundaryEvent cancelActivity="true"> Cancels the task and takes alternate path
Boundary (Non-Interrupting) <boundaryEvent cancelActivity="false"> Triggers action but keeps task active
Intermediate Catch <intermediateCatchEvent> Pauses process for a duration

Timer Duration Formats (ISO 8601)

Format Example Meaning
Minutes PT30M 30 minutes
Hours PT2H 2 hours
Days P1D 1 day
Combined P3DT4H 3 days and 4 hours
Repeating R/PT1H Repeat every hour indefinitely
Limited Repeats R3/PT1H Repeat 3 times, every hour

Pattern 1: Auto-Skip After Timeout

Task automatically skips after a duration. The process continues to the next step.

<userTask id="optionalApproval" name="Optional Approval" flowable:candidateGroups="ROLE_APPROVER"/>

<!-- Interrupting timer: cancels task after 48 hours -->
<boundaryEvent id="timeout" attachedToRef="optionalApproval" cancelActivity="true">
    <timerEventDefinition>
        <timeDuration>PT48H</timeDuration>
    </timerEventDefinition>
</boundaryEvent>

<!-- Both paths lead to the same next step -->
<sequenceFlow sourceRef="optionalApproval" targetRef="nextStep"/>
<sequenceFlow sourceRef="timeout" targetRef="nextStep"/>

Pattern 2: Escalation (Reassign After Timeout)

Task is reassigned to a different user or role after a timeout. Uses reassignTask delegate.

<userTask id="employeeTask" name="Employee Review" flowable:assignee="${initiator}"/>

<!-- Non-interrupting timer: triggers escalation but keeps task -->
<boundaryEvent id="escalateTimer" attachedToRef="employeeTask" cancelActivity="false">
    <timerEventDefinition>
        <timeDuration>P2D</timeDuration>
    </timerEventDefinition>
</boundaryEvent>

<sequenceFlow sourceRef="escalateTimer" targetRef="doEscalation"/>

<!-- Reassign to manager role -->
<serviceTask id="doEscalation" flowable:delegateExpression="${reassignTask}">
    <extensionElements>
        <flowable:field name="targetCandidateGroups" stringValue="ROLE_MANAGER"/>
        <flowable:field name="clearExisting" stringValue="true"/>
    </extensionElements>
</serviceTask>

ReassignTaskDelegate Fields

Field Description
targetAssignee Email of specific user to assign to
targetCandidateUsers Comma-separated list of user emails
targetCandidateGroups Comma-separated list of roles (e.g., ROLE_MANAGER,ROLE_ADMIN)
clearExisting If "true", clears existing assignee before adding new ones

Pattern 3: Delayed Actions (e.g., Follow-up Email)

Execute an action after a specified delay.

<userTask id="submitRequest" name="Submit Request" flowable:assignee="${initiator}"/>

<sequenceFlow sourceRef="submitRequest" targetRef="waitTimer"/>

<!-- Wait for 24 hours -->
<intermediateCatchEvent id="waitTimer" name="Wait 24 Hours">
    <timerEventDefinition>
        <timeDuration>PT24H</timeDuration>
    </timerEventDefinition>
</intermediateCatchEvent>

<sequenceFlow sourceRef="waitTimer" targetRef="sendFollowUp"/>

<serviceTask id="sendFollowUp" flowable:delegateExpression="${sendReminder}">
     <extensionElements>
        <flowable:field name="to" expression="${initiator}"/>
        <flowable:field name="subject" stringValue="Follow-up"/>
        <flowable:field name="body" stringValue="24 hours have passed since submission."/>
    </extensionElements>
</serviceTask>


Pattern 4: Repeating Email Reminders

Send reminder emails on a schedule while task is pending. Uses sendReminder delegate.