All posts
MermaidFlowchartsWorkflow DesignAdvanced

Mermaid subgraphs and swimlanes for complex workflow diagrams

5 min readThe MermaidCreator team

When a flowchart grows beyond ten nodes, it can become a hairball—arrows crossing everywhere, related logic scattered across the canvas. Subgraphs and swimlanes are Mermaid's answer: they partition a diagram by team, responsibility, or domain, turning chaos into readable zones.

What are subgraphs and swimlanes?

A subgraph is a logical grouping within a single diagram. You wrap related nodes in a subgraph block, and Mermaid renders them in a bounded box.

A swimlane is the same concept, but we usually reserve the term for horizontal or vertical bands where each lane represents an actor (e.g., "Customer", "Payment Service", "Warehouse"). Subgraphs automatically create these lanes when you nest them.

Compare a flat flowchart:

flowchart TD
    A[Customer visits site]
    B[Browse products]
    C{Item in stock?}
    D[Checkout]
    E[Process payment]
    F[Payment approved]
    G[Warehouse picks item]
    H[Ship to customer]
    I[Order complete]
    
    A --> B --> C
    C -->|Yes| D --> E --> F
    F --> G --> H --> I
    C -->|No| J[Notify out of stock]
    J --> K[End]

...to the same flow with swimlanes:

flowchart TD
    subgraph Customer ["🛍️ Customer"]
        A[Browse products]
        D[Checkout]
    end
    
    subgraph Payment ["💳 Payment Service"]
        E[Process payment]
        F[Payment approved]
    end
    
    subgraph Warehouse ["📦 Warehouse"]
        G[Pick item]
        H[Pack & ship]
    end
    
    A --> D --> E --> F
    F --> G --> H

The second version immediately shows who does what and where handoffs happen. That's swimlanes at work.

Swimlane syntax

Start with a top-level subgraph that labels your swimlane, then nest nodes inside:

flowchart TD
    subgraph User["👤 User"]
        A[Open app]
        B[Enter credentials]
    end
    
    subgraph Backend["🔧 Backend"]
        C[Hash password]
        D{Credentials match?}
        E[Generate token]
    end
    
    subgraph Database["📊 Database"]
        F[(User table)]
    end
    
    A --> B --> C
    C --> F
    F --> D
    D -->|Yes| E
    D -->|No| G[Show error]

The syntax is:

  • subgraph <id>["<label>"] — Open a swimlane; <id> is internal, <label> is displayed (emoji optional).
  • Add nodes inside the block.
  • end — Close the swimlane.

You can nest subgraphs, though readability suffers after two levels:

flowchart LR
    subgraph Company["Company"]
        subgraph Team1["Frontend Team"]
            A[Component A]
            B[Component B]
        end
        subgraph Team2["Backend Team"]
            C[API Layer]
            D[Database Layer]
        end
    end
    
    A --> C
    B --> C
    C --> D

A realistic multi-stage order workflow

Here's a full e-commerce order flow with swimlanes for each actor:

flowchart TD
    subgraph Customer["👤 Customer"]
        A[Browse catalog]
        B[Add to cart]
        C[Proceed to checkout]
        D{Confirm order?}
    end
    
    subgraph PaymentService["💳 Payment Gateway"]
        E[Validate card]
        F{Payment approved?}
        G[Issue receipt]
    end
    
    subgraph Fulfillment["📦 Fulfillment Center"]
        H[Check inventory]
        I{Item available?}
        J[Pick & pack]
        K[Generate shipping label]
    end
    
    subgraph Shipping["🚚 Shipping Partner"]
        L[Receive package]
        M[In transit]
        N[Delivered]
    end
    
    A --> B --> C --> D
    D -->|Yes| E --> F
    F -->|No| O[Retry payment]
    O --> E
    F -->|Yes| G --> H
    H --> I
    I -->|Yes| J --> K --> L
    I -->|No| P[Notify customer]
    L --> M --> N

The swimlanes make it instantly clear that payment is independent of fulfillment — they can run in parallel after the customer confirms. Without swimlanes, you'd have to trace arrows to figure that out.

Tips for swimlane success

One responsibility per swimlane. A swimlane should map to a person, system, or team. If you find yourself adding logic that spans multiple swimlanes in a tangled way, you've hit your diagram's natural size limit — break it into two diagrams.

Label clearly. Use emoji sparingly (one per label max), and include the system/role name: "💳 Stripe Payments" not just "💳 Payments". Your teammates can't reverse-engineer a system from emoji alone.

Avoid long horizontal runs. Mermaid's auto-layout tries its best, but wide swimlanes can push nodes far apart. If a swimlane lane becomes unreadable, split the flow into separate diagrams for each major phase.

Collapse detail with subgraph nesting. If a swimlane contains a repeating sub-process (e.g., "Retry payment"), nest a subgraph:

flowchart TD
    A[Start]
    
    subgraph Attempt["💳 Payment Attempt Loop"]
        B[Charge card]
        C{Approved?}
    end
    
    A --> B
    B --> C
    C -->|No, retry| B
    C -->|Yes| D[Success]

Use subgraph direction hints. By default, flowchart TD stacks swimlanes top-to-bottom. Use LR for side-by-side swimlanes if you're showing a sequential handoff:

flowchart LR
    subgraph Customer["Customer"]
        A[Order]
    end
    
    subgraph Warehouse["Warehouse"]
        B[Pack]
    end
    
    subgraph Shipping["Shipping"]
        C[Deliver]
    end
    
    A --> B --> C

When subgraphs aren't enough

If you have more than 4–5 swimlanes or the diagram grows beyond ~40 nodes, consider:

  1. Breaking into multiple diagrams — One for the happy path, one for error handling.
  2. Sequence diagrams — Better for multi-actor interactions with parallel messaging (see "How to document REST APIs with Mermaid sequence diagrams").
  3. State diagrams — Superior if you're modeling a single entity's lifecycle (orders moving from pending → processing → shipped → delivered).

FAQ

Q: Can I color swimlanes differently? A: Mermaid doesn't natively support per-swimlane styling in flowcharts (yet), but you can use shape styling on key nodes to highlight lanes visually.

Q: How do I show parallel flows within a swimlane? A: Draw multiple branches from a node. Swimlanes don't force sequential flow—a node can fan out to many downstream nodes, and they'll all render inside the swimlane.

Q: What's the difference between a subgraph and a comment node? A: A subgraph is a layout primitive that bounds and labels a region. A comment node is just a text node. Subgraphs keep the diagram structure legible at scale; comments are fine for small diagrams but don't scale.


Ready to build clearer workflows? Try the MermaidCreator editor and sketch your first swimlane diagram.

Related posts