Mermaid flowchart loop syntax: repeat and iteration patterns
Loops are everywhere in real workflows: "retry until success," "process each item in a batch," "repeat until the condition changes." Most flowchart tools force you to draw the same box multiple times with arrows looping back—cluttered and hard to read. Mermaid's loop node solves this with a single, reusable abstraction that makes iteration intent crystal clear.
This guide teaches you Mermaid loop syntax, shows practical patterns from API retry logic to data pipelines, and explains when to use loops versus other control structures.
What a loop node represents
A loop node (shown as a rectangle with a curved left edge, sometimes called a "repeat" or "do-while" symbol) represents one or more repetitions of an action or group of actions.
flowchart TD
A([Start]) --> B["Initialize counter"]
B --> C{counter < 10?}
C -->|Yes| D["Process item"]
D --> E["Increment counter"]
E --> C
C -->|No| F([End])
This is the traditional way—explicit arrows, explicit decisions. It's clear but verbose. The same logic as a loop node:
flowchart TD
A([Start]) --> B["Initialize counter"]
B --> C{{"Process while counter < 10"}}
C --> D["Increment counter"]
D --> C
C --> E([End])
Wait—Mermaid doesn't have a native "loop node" shape like Visio does. So we use subgraphs with a label to represent loops semantically, or we use alt blocks in sequence diagrams for loops. Let me clarify with the actual Mermaid pattern.
Mermaid loop patterns
Pattern 1: Explicit loop with a decision diamond
The most readable pattern uses a decision diamond + arrow feedback:
flowchart TD
A([Start]) --> B["Initialize: items = []"]
B --> C["Fetch page 1"]
C --> D["Add items to list"]
D --> E{More pages?}
E -->|Yes| F["page += 1"]
F --> C
E -->|No| G["Return items"]
G --> H([End])
How to read it:
- Start with initialization
- Do the action (fetch, process, etc.)
- Check the loop condition
- If true, loop back (the arrow from E back to C)
- If false, exit
Pattern 2: Retry loop for error handling
A common pattern: try something, catch errors, retry with exponential backoff:
flowchart TD
A([Start payment]) --> B["Attempt charge"]
B --> C{Payment approved?}
C -->|Yes| D["Confirm order"]
D --> E([Success])
C -->|No| F{Retries < 3?}
F -->|Yes| G["Wait 2^n seconds"]
G --> H["Increment retry count"]
H --> B
F -->|No| I["Email customer"]
I --> J([Failed])
Key insight: The inner loop (B → C → F → G → H → B) repeats the charge attempt. When retries are exhausted, it breaks to J (failed path).
Pattern 3: Data processing loop (map over collection)
Process every item in a collection:
flowchart TD
A([Start]) --> B["items = get_all_users()"]
B --> C["index = 0"]
C --> D{index < items.length?}
D -->|Yes| E["user = items[index]"]
E --> F["Send reminder email"]
F --> G["index += 1"]
G --> D
D -->|No| H["Log: completed"]
H --> I([End])
Real-world: Daily email campaign that loops through all users, sends reminders, then marks done.
Pattern 4: Nested loops (loops within loops)
Process a matrix (e.g., rows and columns):
flowchart TD
A([Start]) --> B["row = 0"]
B --> C{row < 10?}
C -->|Yes| D["col = 0"]
D --> E{col < 10?}
E -->|Yes| F["matrix[row, col] *= 2"]
F --> G["col += 1"]
G --> E
E -->|No| H["row += 1"]
H --> C
C -->|No| I([End])
Structure:
- Outer loop: rows (C → ... → H → C)
- Inner loop: columns (E → ... → G → E)
- Each cell (F) runs once per inner iteration
Use clear naming (row, col) to distinguish loop variables.
Real-world examples
CI/CD pipeline with retry logic
flowchart TD
A([PR merged]) --> B["Run tests"]
B --> C{Tests pass?}
C -->|Yes| D["Build artifact"]
D --> E["Deploy to staging"]
E --> F{Smoke tests pass?}
F -->|Yes| G["Deploy to production"]
F -->|No| H["Rollback"]
H --> I["Alert team"]
I --> J([Failed])
C -->|No| K{Retries < 2?}
K -->|Yes| L["Clear cache"]
L --> B
K -->|No| M["Notify developers"]
M --> J
G --> N([Success])
Loops here:
- Test retry (B → C → K → L → B): re-run tests if they fail (up to 2 times)
- Smoke test feedback (F → H → I → J): on failure, rollback and alert
Data pipeline with batching
flowchart TD
A([Start]) --> B["batch = []"]
B --> C["Read next record"]
C --> D["Add to batch"]
D --> E{batch.size == 1000?}
E -->|Yes| F["Send batch to warehouse"]
F --> G["Reset batch"]
G --> B
E -->|No| H{More records?}
H -->|Yes| B
H -->|No| I{batch is not empty?}
I -->|Yes| F
I -->|No| J([Complete])
Loop insight: Processes records one by one, accumulates a batch, sends when full (1000 items), then resets and continues. At the end, sends any remaining partial batch.
Cleanup loop (repeat until a resource is freed)
flowchart TD
A([Request: delete old files]) --> B["today = now()"]
B --> C["file = oldest file"]
C --> D{file exists?}
D -->|Yes| E{file age > 30 days?}
E -->|Yes| F["Delete file"]
F --> G["freed += file.size"]
G --> H["Next file"]
H --> D
E -->|No| I["Stop"]
D -->|No| I
I --> J["Return freed"]
J --> K([End])
Loop: Iterate over files, delete old ones, free up disk space. Stops when no more old files exist.
Loop vs. alt blocks in sequence diagrams
Flowchart loops show iteration logic. Sequence diagrams show interactions over iterations using loop blocks:
sequenceDiagram
participant Client
participant API
Note over Client: Retry loop: up to 3 attempts
loop Retry until success or 3 attempts
Client->>API: POST /data
alt Success
API-->>Client: 200 OK
break
else Timeout
API-->>Client: 504 Timeout
end
end
When to use each:
- Flowchart loop → show the decision tree and retry logic (business process)
- Sequence diagram loop → show which systems are involved in each iteration (technical implementation)
Ideally, use both in your documentation.
Best practices for readable loops
1. Label loop conditions clearly
Bad:
C -->|Yes| B
Good:
C -->|More items to process| B
2. Show loop initialization
Always initialize before the loop. Readers need to see where counter, batch, or index starts:
flowchart TD
A([Start]) --> B["counter = 0"]
B --> C{counter < 10?}
C -->|Yes| D["Do work"]
D --> E["counter += 1"]
E --> C
Without B, it's unclear what counter is or where it comes from.
3. Make the exit condition obvious
The "No" or "False" path from the loop condition should lead out of the loop. Don't hide it:
flowchart TD
A --> B{Continue?}
B -->|Yes| C["Action"]
C --> D["Update state"]
D --> B
B -->|No| E["Exit"]
E --> F([End])
4. Use consistent variable names
If you have multiple loops, use consistent names:
index/counterfor numeric iterationitemfor collection itemsretriesfor retry countsbatchfor accumulated data
Comparison with similar patterns
| Pattern | Best for | Example |
|---|---|---|
| Loop | Repeating a process until a condition | Retry logic, batching, polling |
| If-then-else | One-time decision | Route based on status |
| Subgraph | Grouping related steps | A phase or sub-process |
| Parallel (swimlanes) | Concurrent tasks | Multiple teams/systems |
Most workflows combine these: an outer loop with if-then-else branches inside it.
FAQ
Can I loop based on external input (e.g., "ask the user to try again")?
Yes. The decision diamond can represent a human choice or a system state check. Both cause loops:
flowchart TD
A["Attempt operation"]
B{Success?}
B -->|No| C["Show error to user"]
C --> D{Try again?}
D -->|Yes| A
D -->|No| E([Cancel])
What's the difference between a loop and recursion?
Loops iterate in a sequence; recursion is a function calling itself. Mermaid flowcharts show loops visually. For recursion (e.g., a tree traversal function), flowcharts can represent it, but sequence diagrams often make it clearer:
sequenceDiagram
participant Main
participant Func
Main->>Func: traverse(node)
alt node is leaf
Func-->>Main: return
else node has children
Func->>Func: traverse(left child)
Func->>Func: traverse(right child)
Func-->>Main: return
end
How do I show a "do-while" loop (run first, check after)?
In flowcharts, do-while is just a loop where the check comes after the action:
flowchart TD
A([Start]) --> B["Attempt"]
B --> C{Succeeded?}
C -->|No| B
C -->|Yes| D([End])
The action (B) always runs at least once before the check (C).
Can I nest loops more than 2 levels deep?
Technically yes, but it gets hard to read. Beyond 2–3 levels, consider extracting the inner loop into a separate diagram or a sub-process box.
Master loop patterns in the MermaidCreator editor—build a retry workflow, a batch processor, or a cleanup script to see how loops make iteration logic shine.
Related posts
Visualizing algorithms with Mermaid: teaching loops and iterations
Step-by-step flowcharts make algorithms concrete. Learn to diagram loops, recursion, and decision logic so students (and you) understand the flow.
Flowchart documentation best practices for complex systems
Master the art of documenting complex systems with Mermaid flowcharts. Avoid common pitfalls and write flowcharts that teams actually understand.