Skip to content

BPMN Activity

An activity is a piece of work in a process model. The facts cover several kinds.

Embedded subprocess. It groups process elements inside the parent process. It must have exactly one none start event, which is a start event with no trigger.

Collapsed subprocess. The diagram hides its inner steps to reduce complexity. This is for display only. It does not make the content reusable.

Call activity. It invokes another process that is stored as a separate BPMN file. Several processes can invoke that file. For reusable processes, call activities are the recommended choice.

Event subprocess. It sits inside its scope, much like a boundary event (see the article Boundary Event). A boundary event is attached to the edge of an activity. An event subprocess can be interrupting or non-interrupting. An interrupting one fires only once and ends the active instances of its containing scope. A non-interrupting one can fire many times.

Multi-instance markers. A multi-instance activity runs several times, either in sequence or in parallel. Three horizontal lines at the bottom mean sequential. Three vertical lines mean parallel. In the parallel case, all instances are created when the multi-instance body activates.

Task types. A service task is a work item with a specific type. The article BPMN Task Marker and Task Type covers task types in general.

An order process contains a step “Check customer”. Its inner steps sit behind a collapsed subprocess, so the main diagram stays readable. “Calculate shipping” is a call activity, and other processes call the same stored shipping process. “Pack item” carries a parallel multi-instance marker, so all items in an order are packed at once. A non-interrupting event subprocess answers “customer asks for status” as often as needed.

A collapsed subprocess keeps a diagram simple, but it is for display only. It gives no reuse. A call activity gives reuse across processes, but the logic lives in a separate file. Readers must open that file to see the steps. An interrupting event subprocess ends the active work in its scope and fires only once. A non-interrupting one can fire repeatedly.

A process with a collapsed-style embedded subprocess, a call activity and a parallel multi-instance task.

Diagram source
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" targetNamespace="http://example.com/bpmn">
<process id="order" isExecutable="false">
<startEvent id="s" name="Order received">
<outgoing>f1</outgoing>
</startEvent>
<subProcess id="check" name="Check customer">
<incoming>f1</incoming>
<outgoing>f2</outgoing>
<startEvent id="cs">
<outgoing>c1</outgoing>
</startEvent>
<task id="ct" name="Verify data">
<incoming>c1</incoming>
<outgoing>c2</outgoing>
</task>
<endEvent id="ce">
<incoming>c2</incoming>
</endEvent>
<sequenceFlow id="c1" sourceRef="cs" targetRef="ct" />
<sequenceFlow id="c2" sourceRef="ct" targetRef="ce" />
</subProcess>
<callActivity id="ship" name="Calculate shipping" calledElement="shippingProcess">
<incoming>f2</incoming>
<outgoing>f3</outgoing>
</callActivity>
<serviceTask id="pack" name="Pack item">
<incoming>f3</incoming>
<outgoing>f4</outgoing>
<multiInstanceLoopCharacteristics />
</serviceTask>
<endEvent id="e" name="Order done">
<incoming>f4</incoming>
</endEvent>
<sequenceFlow id="f1" sourceRef="s" targetRef="check" />
<sequenceFlow id="f2" sourceRef="check" targetRef="ship" />
<sequenceFlow id="f3" sourceRef="ship" targetRef="pack" />
<sequenceFlow id="f4" sourceRef="pack" targetRef="e" />
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_order">
<bpmndi:BPMNPlane id="BPMNPlane_order" bpmnElement="order">
<bpmndi:BPMNShape id="BPMNShape_s" bpmnElement="s">
<dc:Bounds x="80" y="102" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="68" y="143" width="60" height="28" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_check" bpmnElement="check">
<dc:Bounds x="216" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_ship" bpmnElement="ship">
<dc:Bounds x="416" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_pack" bpmnElement="pack">
<dc:Bounds x="616" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_e" bpmnElement="e">
<dc:Bounds x="816" y="102" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="798" y="143" width="73" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="BPMNEdge_f1" bpmnElement="f1">
<di:waypoint x="116" y="120" />
<di:waypoint x="216" y="120" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_f2" bpmnElement="f2">
<di:waypoint x="316" y="120" />
<di:waypoint x="416" y="120" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_f3" bpmnElement="f3">
<di:waypoint x="516" y="120" />
<di:waypoint x="616" y="120" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_f4" bpmnElement="f4">
<di:waypoint x="716" y="120" />
<di:waypoint x="816" y="120" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
<bpmndi:BPMNDiagram id="BPMNDiagram_check">
<bpmndi:BPMNPlane id="BPMNPlane_check" bpmnElement="check">
<bpmndi:BPMNShape id="BPMNShape_cs" bpmnElement="cs">
<dc:Bounds x="80" y="102" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_ct" bpmnElement="ct">
<dc:Bounds x="216" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_ce" bpmnElement="ce">
<dc:Bounds x="416" y="102" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="BPMNEdge_c1" bpmnElement="c1">
<di:waypoint x="116" y="120" />
<di:waypoint x="216" y="120" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="BPMNEdge_c2" bpmnElement="c2">
<di:waypoint x="316" y="120" />
<di:waypoint x="416" y="120" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
  • Reusable process logic is modeled as a call activity, not as a collapsed subprocess.
  • Each embedded subprocess has exactly one none start event.
  • Each event subprocess is marked clearly as interrupting or non-interrupting.
  • Multi-instance activities show the correct marker: horizontal lines for sequential, vertical lines for parallel.