Flowcharts Beyond the Basics with Mermaid

Go past “boxes and arrows” with Mermaid flowcharts. Learn subgraphs, layout tricks, reusable styling with classDefs, meaningful edge labels, link types, and a real-world deploy + drain example you can reuse in future posts.

Table of Contents

Mermaid flowcharts are perfect when you want diagrams that live next to your code, stay reviewable in git, and can be updated as quickly as your systems change.

This guide skips the “hello world” and focuses on the features that make flowcharts maintainable: subgraphs, reusable styling, clean labels, consistent layout, and patterns you’ll use again and again.


A quick refresher (so the rest makes sense)

Mermaid flowcharts use this basic structure:

  • flowchart LR (or TD) sets the layout direction
  • A --> B connects nodes
  • A[Rectangle], A(Rounded), A{Decision} control shapes
  • A -->|label| B adds edge labels

Example

Source

Rendered

flowchart LR A[Request] --> B{Authorized?} B -->|yes| C[Serve content] B -->|no| D[Redirect to login]


1) Layout control that actually improves readability

Pick a direction intentionally

  • LR (left-to-right) is great for pipelines and request paths.
  • TD (top-down) is great for decision trees and troubleshooting.

Source

Rendered

flowchart TD A[Start] --> B[Step 1] --> C[Step 2] --> D[Done]

Use invisible “spacers” to guide layout

Sometimes you need a little structure without adding meaning.

Source

Rendered

flowchart LR A[Ingress] --> B[Service] B --> C[Pod 1] B --> D[Pod 2] %% Spacer to keep things from collapsing X[ ]:::spacer classDef spacer fill:transparent,stroke:transparent,color:transparent; C --- X D --- X

Tip: Treat spacers like CSS hacks—use sparingly, but don’t fear them when they improve clarity.


2) Subgraphs (the feature that keeps big diagrams sane)

Subgraphs let you group related nodes. They’re the key to drawing “real” systems without turning your diagram into spaghetti.

Basic subgraph

Source

Rendered

flowchart LR subgraph Edge[Edge Layer] CDN[CDN] --> WAF[WAF] WAF --> ALB[Load balancer] end subgraph App[Application Layer] ALB --> API[API service] API --> Q[Queue] API --> DB[(Database)] end

Subgraphs as “swimlanes”

A clean trick is to use subgraphs as swimlanes for responsibility boundaries: client vs platform vs app.

Source

Rendered

flowchart LR subgraph Client U[User] --> B[Browser] end subgraph Platform B --> CDN[CDN] CDN --> ALB[ALB] end subgraph Service ALB --> API[API] API --> DB[(DB)] end


3) Node shapes and labels that age well

Use shapes to convey meaning

A few conventions that readers learn quickly:

  • Rounded A(Run step) for actions
  • Diamond A{Decision?} for branching
  • Cylinder A[(DB)] for data stores
  • Stadium A([Start]) and B([End]) for boundaries

Multi-line labels

You can use <br/> inside labels to make long text readable.

Source

Rendered

flowchart TD A[Deploy request from CI] --> B{Change type?} B -->|config| C[Apply config and reload] B -->|binary| D[Roll service instances]

Tip: Prefer short node text + edge labels over giant paragraphs in a single node.


4) Link types: solid, dotted, thick, and “not really a dependency”

Mermaid supports different link styles that you can use to communicate strength or meaning.

  • --> normal flow
  • -.-> optional / async / “may happen”
  • ==> emphasis / strong coupling

Source

Rendered

flowchart LR A[API] --> B[DB] A -.-> C[Metrics] A ==> D[Payment processor]


5) Styling with classDefs (so diagrams look consistent across your blog)

If you only do one “advanced” thing, do this: define a small style palette and reuse it.

A small, reusable style set

Source

Rendered

flowchart LR classDef edge fill:#eef,stroke:#446,stroke-width:1px; classDef compute fill:#efe,stroke:#464,stroke-width:1px; classDef data fill:#fee,stroke:#644,stroke-width:1px; classDef danger fill:#fdd,stroke:#a33,stroke-width:2px; CDN[CDN]:::edge --> ALB[Load balancer]:::edge ALB --> API[API service]:::compute API --> DB[(Database)]:::data API --> ERR[Error path]:::danger

Apply classes later (cleaner for big diagrams)

When diagrams grow, it’s often clearer to define nodes first, then apply classes.

Source

Rendered

flowchart LR classDef edge fill:#eef,stroke:#446; classDef compute fill:#efe,stroke:#464; classDef data fill:#fee,stroke:#644; CDN[CDN] --> ALB[Load balancer] ALB --> API[API] API --> DB[(DB)] class CDN,ALB edge; class API compute; class DB data;


6) Label edges like you mean it

Edge labels are how you keep nodes short while still conveying meaning.

Source

Rendered

flowchart TD A[Client] -->|HTTPS 443| B[CDN] B -->|cache miss| C[Origin] C -->|SQL| D[(DB)] C -->|timeout| E[Fallback]

Tip: If every edge label is “calls”, remove edge labels entirely. Label only what differentiates the link.


7) Clickable diagrams (turn a diagram into navigation)

If your renderer supports it, Mermaid can attach links to nodes.

Source

Rendered

flowchart LR A[Runbook] --> B[Restart service] A --> C[Scale out] click A "https://example.com/runbook" "Open the runbook" click B "https://example.com/restart" "Restart steps" click C "https://example.com/scaling" "Scaling guide"

Replace the example URLs with your own internal documentation links.


8) A real “beyond basics” example: deploy + drain done cleanly

This example combines subgraphs, edge labels, link types, and a small style palette.

Source

Rendered

flowchart LR classDef user fill:#eef,stroke:#446; classDef edge fill:#eef,stroke:#446; classDef compute fill:#efe,stroke:#464; classDef data fill:#fee,stroke:#644; classDef warn fill:#ffd,stroke:#aa7,stroke-width:2px; subgraph Client U[User]:::user --> CDN[CDN]:::edge end subgraph Platform CDN --> ALB[ALB]:::edge ALB -->|new requests| TG1[Target group]:::edge end subgraph Service TG1 --> S1[App v1]:::compute TG1 --> S2[App v1]:::compute S1 --> DB[(DB)]:::data S2 --> DB end CI[CI deploy]:::compute -.->|start rollout| ASG[ASG update]:::compute ASG -.->|add v2| S3[App v2]:::compute ASG -.->|shift traffic| TG1 ASG -.->|drain v1| D{Deregistration<br/>delay}:::warn D -.->|in-flight completes| S1 D -.->|in-flight completes| S2


9) A checklist for “blog-ready” flowcharts

Before you publish:

  • Can a reader understand it in 10 seconds? If not, split it into two diagrams.
  • Are your labels consistent? (Requests, events, retries, timeouts)
  • Do subgraphs reflect responsibility boundaries? (Client / platform / service)
  • Are you using shapes intentionally? (decisions vs actions vs data)
  • Are edge labels doing real work? Label the why, not the obvious.
  • Do you have a stable style palette? Reuse classDef names across posts.

Where to go next

If you found subgraphs and class-based styling useful, the next Mermaid feature to learn is sequence diagrams—they’re often the best way to explain time (retries, backoffs, and latency) without contorting a flowchart.

Have a project or a problem?

Talk with a senior engineer for practical recommendations—no obligation.

Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts

Categories

Get a free consultation from Reliable Penguin

Submit the form—or for immediate service call 866-649-7984.