Quality inspection BPMN example
Quality inspection decides whether a finished batch is released to stock, sent back for rework, or scrapped. Manufacturers map it because the decision logic is exactly where audits look: who tested what, against which specification, and what happened to failing batches. The recurring problem is an informal rework loop, where reworked product re enters production without ever passing back through inspection.
The model is a single pool with Quality and Production lanes and a chain of two exclusive gateways: the first tests the batch against tolerance, the second decides whether a failed batch can be reworked. The rework branch loops back to the sampling task, which is the modelling choice worth studying. Drawing the loop through inspection, not around it, encodes the rule that nothing reaches stock untested.
Standard BPMN 2.0 interchange XML: opens in Camunda Modeler, Signavio, Bizagi, and any other compliant tool.
The process at a glance
How to read this diagram
Inspection begins when a batch is ready in the Quality lane. An inspector draws a sample, tests it against the specification, and a script task records the results in the quality system. The gateway "Batch within tolerance?" then makes the release decision: on the Yes branch a service task releases the batch to stock and the process ends at "Batch released".
Failed batches take the default No branch to a deviation review, where the second gateway asks "Rework possible?". If Yes, Production reworks the batch and the flow loops back to "Draw inspection sample", forcing the reworked batch through the full test again. The default No branch sends the batch to Production for scrapping and the process ends at "Batch scrapped". Three outcomes, two of them terminal, and every route through the model passes the test bench at least once.
BPMN elements used
| Element | Count | In this diagram |
|---|---|---|
| Start event | 1 | Batch ready for inspection |
| End event | 2 | Batch scrapped, Batch released |
| Task | 3 | Draw inspection sample, Rework batch, Scrap batch |
| User task | 2 | Test sample against spec, Review deviation |
| Service task | 1 | Release batch to stock |
| Script task | 1 | Record test results |
| Exclusive gateway | 2 | Batch within tolerance?, Rework possible? |
View the BPMN 2.0 XML for this diagram
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:bpmn2="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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="swimdraft" exporterVersion="1.0">
<bpmn2:collaboration id="Collaboration_1">
<bpmn2:participant id="pool_qi" name="Quality inspection" processRef="Process_pool_qi" />
</bpmn2:collaboration>
<bpmn2:process id="Process_pool_qi" isExecutable="false">
<bpmn2:laneSet id="LaneSet_pool_qi">
<bpmn2:lane id="lane_qi_qa" name="Quality">
<bpmn2:flowNodeRef>start_qi</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_qi_sample</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_qi_test</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_qi_record</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>g_qi_tol</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_qi_review</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>g_qi_rework</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_qi_release</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>end_qi_rel</bpmn2:flowNodeRef>
</bpmn2:lane>
<bpmn2:lane id="lane_qi_prod" name="Production">
<bpmn2:flowNodeRef>t_qi_rework</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_qi_scrap</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>end_qi_scrap</bpmn2:flowNodeRef>
</bpmn2:lane>
</bpmn2:laneSet>
<bpmn2:startEvent id="start_qi" name="Batch ready for inspection">
<bpmn2:outgoing>fqi1</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:task id="t_qi_sample" name="Draw inspection sample">
<bpmn2:incoming>fqi1</bpmn2:incoming>
<bpmn2:incoming>fqi10</bpmn2:incoming>
<bpmn2:outgoing>fqi2</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:userTask id="t_qi_test" name="Test sample against spec">
<bpmn2:incoming>fqi2</bpmn2:incoming>
<bpmn2:outgoing>fqi3</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:scriptTask id="t_qi_record" name="Record test results">
<bpmn2:incoming>fqi3</bpmn2:incoming>
<bpmn2:outgoing>fqi4</bpmn2:outgoing>
</bpmn2:scriptTask>
<bpmn2:exclusiveGateway id="g_qi_tol" name="Batch within tolerance?" default="fqi6">
<bpmn2:incoming>fqi4</bpmn2:incoming>
<bpmn2:outgoing>fqi5</bpmn2:outgoing>
<bpmn2:outgoing>fqi6</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:userTask id="t_qi_review" name="Review deviation">
<bpmn2:incoming>fqi6</bpmn2:incoming>
<bpmn2:outgoing>fqi7</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:exclusiveGateway id="g_qi_rework" name="Rework possible?" default="fqi9">
<bpmn2:incoming>fqi7</bpmn2:incoming>
<bpmn2:outgoing>fqi8</bpmn2:outgoing>
<bpmn2:outgoing>fqi9</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:task id="t_qi_rework" name="Rework batch">
<bpmn2:incoming>fqi8</bpmn2:incoming>
<bpmn2:outgoing>fqi10</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:task id="t_qi_scrap" name="Scrap batch">
<bpmn2:incoming>fqi9</bpmn2:incoming>
<bpmn2:outgoing>fqi11</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:endEvent id="end_qi_scrap" name="Batch scrapped">
<bpmn2:incoming>fqi11</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:serviceTask id="t_qi_release" name="Release batch to stock">
<bpmn2:incoming>fqi5</bpmn2:incoming>
<bpmn2:outgoing>fqi12</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:endEvent id="end_qi_rel" name="Batch released">
<bpmn2:incoming>fqi12</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="fqi1" sourceRef="start_qi" targetRef="t_qi_sample" />
<bpmn2:sequenceFlow id="fqi2" sourceRef="t_qi_sample" targetRef="t_qi_test" />
<bpmn2:sequenceFlow id="fqi3" sourceRef="t_qi_test" targetRef="t_qi_record" />
<bpmn2:sequenceFlow id="fqi4" sourceRef="t_qi_record" targetRef="g_qi_tol" />
<bpmn2:sequenceFlow id="fqi5" name="Yes" sourceRef="g_qi_tol" targetRef="t_qi_release">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="fqi6" name="No" sourceRef="g_qi_tol" targetRef="t_qi_review" />
<bpmn2:sequenceFlow id="fqi7" sourceRef="t_qi_review" targetRef="g_qi_rework" />
<bpmn2:sequenceFlow id="fqi8" name="Yes" sourceRef="g_qi_rework" targetRef="t_qi_rework">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="fqi9" name="No" sourceRef="g_qi_rework" targetRef="t_qi_scrap" />
<bpmn2:sequenceFlow id="fqi10" sourceRef="t_qi_rework" targetRef="t_qi_sample" />
<bpmn2:sequenceFlow id="fqi11" sourceRef="t_qi_scrap" targetRef="end_qi_scrap" />
<bpmn2:sequenceFlow id="fqi12" sourceRef="t_qi_release" targetRef="end_qi_rel" />
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1">
<bpmndi:BPMNShape id="pool_qi_di" bpmnElement="pool_qi" isHorizontal="true">
<dc:Bounds x="20" y="20" width="1420" height="480" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="lane_qi_qa_di" bpmnElement="lane_qi_qa" isHorizontal="true">
<dc:Bounds x="50" y="20" width="1390" height="240" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="lane_qi_prod_di" bpmnElement="lane_qi_prod" isHorizontal="true">
<dc:Bounds x="50" y="260" width="1390" height="240" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="start_qi_di" bpmnElement="start_qi">
<dc:Bounds x="112" y="59" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="65" y="101" width="130" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_qi_sample_di" bpmnElement="t_qi_sample">
<dc:Bounds x="230" y="37" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_qi_test_di" bpmnElement="t_qi_test">
<dc:Bounds x="380" y="37" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_qi_record_di" bpmnElement="t_qi_record">
<dc:Bounds x="530" y="37" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="g_qi_tol_di" bpmnElement="g_qi_tol">
<dc:Bounds x="705" y="52" width="50" height="50" />
<bpmndi:BPMNLabel><dc:Bounds x="672" y="32" width="116" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_qi_review_di" bpmnElement="t_qi_review">
<dc:Bounds x="830" y="37" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="g_qi_rework_di" bpmnElement="g_qi_rework">
<dc:Bounds x="1005" y="52" width="50" height="50" />
<bpmndi:BPMNLabel><dc:Bounds x="986" y="32" width="89" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_qi_rework_di" bpmnElement="t_qi_rework">
<dc:Bounds x="1130" y="387" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_qi_scrap_di" bpmnElement="t_qi_scrap">
<dc:Bounds x="1130" y="277" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="end_qi_scrap_di" bpmnElement="end_qi_scrap">
<dc:Bounds x="1312" y="299" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="1291" y="341" width="79" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_qi_release_di" bpmnElement="t_qi_release">
<dc:Bounds x="830" y="147" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="end_qi_rel_di" bpmnElement="end_qi_rel">
<dc:Bounds x="1012" y="169" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="992" y="211" width="76" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="fqi1_di" bpmnElement="fqi1">
<di:waypoint x="148" y="77" />
<di:waypoint x="230" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fqi2_di" bpmnElement="fqi2">
<di:waypoint x="330" y="77" />
<di:waypoint x="380" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fqi3_di" bpmnElement="fqi3">
<di:waypoint x="480" y="77" />
<di:waypoint x="530" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fqi4_di" bpmnElement="fqi4">
<di:waypoint x="630" y="77" />
<di:waypoint x="705" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fqi5_di" bpmnElement="fqi5">
<di:waypoint x="755" y="77" />
<di:waypoint x="810" y="77" />
<di:waypoint x="810" y="187" />
<di:waypoint x="830" y="187" />
<bpmndi:BPMNLabel><dc:Bounds x="761" y="57" width="21" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fqi6_di" bpmnElement="fqi6">
<di:waypoint x="755" y="77" />
<di:waypoint x="830" y="77" />
<bpmndi:BPMNLabel><dc:Bounds x="761" y="83" width="17" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fqi7_di" bpmnElement="fqi7">
<di:waypoint x="930" y="77" />
<di:waypoint x="1005" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fqi8_di" bpmnElement="fqi8">
<di:waypoint x="1055" y="77" />
<di:waypoint x="1110" y="77" />
<di:waypoint x="1110" y="427" />
<di:waypoint x="1130" y="427" />
<bpmndi:BPMNLabel><dc:Bounds x="1061" y="57" width="21" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fqi9_di" bpmnElement="fqi9">
<di:waypoint x="1055" y="77" />
<di:waypoint x="1110" y="77" />
<di:waypoint x="1110" y="317" />
<di:waypoint x="1130" y="317" />
<bpmndi:BPMNLabel><dc:Bounds x="1061" y="83" width="17" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fqi10_di" bpmnElement="fqi10">
<di:waypoint x="1230" y="427" />
<di:waypoint x="1260" y="427" />
<di:waypoint x="1260" y="482" />
<di:waypoint x="210" y="482" />
<di:waypoint x="210" y="77" />
<di:waypoint x="230" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fqi11_di" bpmnElement="fqi11">
<di:waypoint x="1230" y="317" />
<di:waypoint x="1312" y="317" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fqi12_di" bpmnElement="fqi12">
<di:waypoint x="930" y="187" />
<di:waypoint x="1012" y="187" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>Frequently asked questions
Why loop rework back to sampling instead of straight to release?
Routing rework directly to release would let an untested batch reach stock, which defeats the point of inspection. Looping to the sampling task guarantees every reworked batch is retested under the same procedure. In BPMN terms this is an ordinary sequence flow back to an earlier activity; no special loop symbol is needed.
Why is recording results a script task rather than a user task?
Testing is human judgement, so it is a user task, but writing structured results into the quality system is a small automated step: a script task fits. Distinguishing them shows precisely where automation already exists. If your lab still records results by hand, change the type to user task and the model stays valid.
Could this be modelled with one gateway instead of two?
A single gateway with three branches (release, rework, scrap) is legal BPMN, but it merges two different questions: is the batch in tolerance, and is recovery worthwhile? Separate gateways keep each question binary, put the deviation review between them where it happens in reality, and make the default paths easier to reason about.
Related BPMN examples
Order fulfilment
An order fulfilment process as a BPMN 2.0 diagram: stock check, backorder loop, picking, and dispatch confirmation. View the swimlanes and download the .bpmn file free.
Goods receipt
A goods receipt process as a BPMN 2.0 diagram: PO matching, condition inspection, discrepancy handling, and GRN posting. See the swimlanes and download the free .bpmn file.
Shipping and dispatch
A shipping and dispatch process as a BPMN 2.0 diagram: parallel packing and paperwork, customs branch, and departure. View the swimlanes and download the .bpmn free.
Inventory replenishment
An inventory replenishment process as a BPMN 2.0 diagram: reorder trigger, policy rules, approval branch, and supplier confirmation. Free .bpmn file download included.
Generate your own version of this diagram
Describe how the process works in your organisation: plain English, meeting notes, a transcript, or a spreadsheet. Swimdraft turns it into a spec-validated BPMN 2.0 diagram you can edit in the browser and export as .bpmn, SVG, or PNG.
Start freeNo credit card required