If you've ever stared at a Mermaid sequence diagram and wondered why your arrows don't look right or what each arrow actually means you're not alone. Mermaid uses specific arrow types and notation to represent different kinds of interactions between participants in a sequence diagram. Getting these wrong can confuse anyone reading your diagram, lead to miscommunication in your team, or simply break your rendering. Understanding the arrow syntax is the difference between a diagram that clearly shows a request-response flow and one that leaves people guessing.

What do the different arrow types mean in a Mermaid sequence diagram?

Mermaid sequence diagrams support several arrow types, each one representing a different kind of message or interaction between two participants (called actors or lifelines). The arrow you choose signals whether a message is synchronous, asynchronous, a return, or a self-call.

Here are the core arrow types:

  • Solid arrow with closed head (->) Represents a synchronous message. The sender waits for a response before continuing.
  • Dashed arrow with closed head (-->>) Represents a return or response message. This is what comes back after a synchronous call.
  • Solid arrow with open head (->>) Represents an asynchronous message. The sender does not wait for a response.
  • Dashed arrow with open head (-->>) Can also be used for asynchronous return messages.
  • Open dotted arrow (..> or ..>>) Used for notes or lightweight/optional interactions.

In practice, the most common pairing you'll see is A->>B: Request followed by B-->>A: Response. This follows the standard request-response pattern used in most API workflows.

How do you write arrow notation in Mermaid syntax?

The basic syntax for a message in a Mermaid sequence diagram follows this pattern:

ParticipantA arrowType ParticipantB: Message text

The arrow type is defined by the characters between the two participant names. Here's how the most-used notations break down:

  • -> Solid line with solid arrowhead (synchronous)
  • ->> Solid line with open arrowhead (asynchronous)
  • --> Dashed line with solid arrowhead (return/synchronous response)
  • -->> Dashed line with open arrowhead (return/asynchronous response)
  • -x Solid line ending with a cross (message that should not arrive or is lost)
  • --x Dashed line ending with a cross (lost return message)
  • ->) Solid line with half arrowhead (often used for async in some renderers)

A simple example looks like this:

Alice->>Bob: Hello Bob
Bob-->>Alice: Hi Alice

This tells the renderer to draw a solid open arrow from Alice to Bob labeled "Hello Bob," then a dashed open arrow back from Bob to Alice labeled "Hi Alice."

What's the difference between synchronous and asynchronous arrows?

This is one of the most common points of confusion. In UML sequence diagrams which Mermaid follows the distinction matters because it changes how you interpret the flow:

  • Synchronous messages (solid arrowhead ->) mean the caller blocks and waits for a reply. Think of a function call in code where you call another function and the current thread pauses until it returns.
  • Asynchronous messages (open arrowhead ->>) mean the sender fires off the message and moves on without waiting. Think of sending an event to a message queue or triggering a background job.

If you're documenting a REST API call where the client sends a request and waits for the server to respond, use the synchronous arrow. If you're showing an event being published to a message broker, use the asynchronous arrow. For real examples of how this looks in API documentation, you can check how to write sequence diagram syntax for REST API workflows.

How do you show self-calls and nested activations?

Sometimes a participant needs to send a message to itself like a method calling another method on the same object. In Mermaid, you do this by using the same participant name on both sides:

Alice->>Alice: Think about it

This draws an arrow that loops back to the same lifeline. You can also combine this with activation bars to show when a participant is actively processing. Activation and deactivation bars in Mermaid use activate and deactivate keywords, and they're essential when you need to show nested calls clearly. If you want to understand how lifeline activation bars work alongside arrows, the syntax for UML sequence diagram lifeline activation bars covers that in detail.

Can you use notes and boxes alongside arrows?

Yes. Mermaid lets you add notes attached to specific participants using simple notation:

  • Note over A: Some note Places a note over participant A.
  • Note left of A: Left note Places a note to the left of A.
  • Note right of B: Right note Places a note to the right of B.
  • Note over A,B: Shared note Places a note spanning across two participants.

Notes are not arrows, but they sit alongside your arrow notation to provide extra context. You can also use boxes and loops (loop, alt, opt, par) to group arrows into logical blocks.

What common mistakes break Mermaid sequence diagrams?

Here are the issues that trip people up most often:

  • Using the wrong dash count. A single dash (-) draws a solid line; two dashes (--) draw a dashed line. Mixing these up changes the meaning of your diagram entirely.
  • Forgetting the colon before the message text. Every message label needs a colon: A->>B: message. Without the colon, Mermaid won't parse it correctly.
  • Not matching participant names exactly. Participant names are case-sensitive. alice and Alice are two different lifelines.
  • Confusing ->> with ->. The extra angle bracket changes the arrowhead from solid to open, which changes the meaning from synchronous to asynchronous.
  • Overusing solid arrows for everything. If every message looks the same, your reader can't tell what's a request, what's a response, and what's a fire-and-forget call. Use dashed arrows for returns.

Are there alternative notations to Mermaid for sequence diagrams?

Mermaid is popular because it works in Markdown files, GitHub, and many documentation tools. But it's not the only option. PlantUML, for example, offers a more feature-rich syntax for sequence diagrams and handles some complex scenarios better. If you find Mermaid's arrow syntax limiting for a particular use case, comparing it against the PlantUML sequence diagram syntax reference can help you decide which tool fits your needs.

How do you add loops, alternatives, and parallel blocks with arrows?

Mermaid supports structured blocks that wrap around groups of arrows. These are written as keywords followed by a label:

  • loop Every 5 seconds Repeats the enclosed messages.
  • alt Success / else Failure Shows conditional branching with different arrow flows.
  • opt Optional step Shows an optional interaction.
  • par Parallel task A / and Parallel task B Shows concurrent interactions.

Each block ends with the end keyword. Inside these blocks, your arrows follow the same notation rules. The arrows are what carry the actual message content; the blocks just organize them into logical sections.

Quick reference: arrow notation cheat sheet

  • -> Solid line, solid arrowhead synchronous message
  • ->> Solid line, open arrowhead asynchronous message
  • --> Dashed line, solid arrowhead synchronous return
  • -->> Dashed line, open arrowhead asynchronous return
  • -x Solid line, cross end lost synchronous message
  • --x Dashed line, cross end lost return message
  • ->) Solid line, half arrowhead async (some renderers)

Practical checklist before you publish your diagram

  1. Use ->> (open arrowhead) for requests and -->> (dashed open) for responses this is the most readable convention.
  2. Make sure every message line has a colon before the label text.
  3. Double-check that participant names match exactly everywhere they appear.
  4. Use activate and deactivate to show processing time on a lifeline when flows get complex.
  5. Add notes over participants to clarify anything the arrows alone can't express.
  6. Preview your diagram in a Mermaid live editor before committing it to your documentation.
  7. Keep arrow direction consistent left-to-right for requests, right-to-left for responses so the visual flow is easy to follow.