Microservices break complex systems into small, independent services that talk to each other through APIs and message queues. When you need to trace how a single user request flows across five, ten, or twenty of these services, things get confusing fast. That's where UML sequence diagram code examples become genuinely useful they give you a visual, version-controllable way to map every call, response, and async message between services. Instead of drawing boxes in a GUI tool and losing track of changes, you write the diagram as text, commit it alongside your code, and update it when the architecture shifts.

What does a UML sequence diagram for microservices actually look like in code?

A sequence diagram written as code uses a simple text-based markup to define participants (your services) and the messages they exchange. If you're new to the syntax, our sequence diagram markup syntax reference covers every supported element. Here's a basic example showing an order placement flow across three services:

Customer -> APIGateway: POST /orders
APIGateway -> OrderService: createOrder(payload)
OrderService -> InventoryService: checkStock(items)
InventoryService --> OrderService: stockAvailable: true
OrderService -> PaymentService: processPayment(orderId, amount)
PaymentService --> OrderService: paymentConfirmed
OrderService --> APIGateway: 201 Created
APIGateway --> Customer: 201 Created

The arrows with solid lines represent synchronous requests. The arrows with dashed lines represent responses. Each participant is automatically created the first time it appears. This is the same idea behind tools like PlantUML's sequence diagram syntax, though markup dialects vary.

How do you model asynchronous messaging between microservices?

Most real microservices architectures don't rely only on synchronous HTTP calls. They use message brokers like RabbitMQ, Kafka, or AWS SQS for event-driven communication. You can represent async messages with a different arrow style in your diagram code:

OrderService ->> EventBus: OrderCreated event
EventBus ->> NotificationService: OrderCreated event
EventBus ->> ShippingService: OrderCreated event
NotificationService ->> EmailProvider: sendConfirmation(email)
ShippingService ->> WarehouseService: reserveStock(orderId)

The double-dashed arrow (>) signals that the sender doesn't wait for a response. This distinction matters when you're reviewing architecture with your team it immediately tells everyone which calls are blocking and which are fire-and-forget.

How do you show error handling and retries in microservices sequence diagrams?

Microservices fail. Services go down, networks partition, and databases time out. Your diagrams should reflect that reality rather than showing only the happy path. Here's how to represent a payment failure with a retry loop:

OrderService -> PaymentService: processPayment(orderId, amount)
PaymentService --> OrderService: 503 Service Unavailable
note right of OrderService: retry attempt 1 (backoff 1s)
OrderService -> PaymentService: processPayment(orderId, amount)
PaymentService --> OrderService: 503 Service Unavailable
note right of OrderService: retry attempt 2 (backoff 2s)
OrderService -> PaymentService: processPayment(orderId, amount)
PaymentService --> OrderService: 200 OK

You can also use alt (alternative) fragments to show branching logic one path for success, another for failure. This is especially helpful when documenting circuit breaker patterns common in tools like Istio or Resilience4j.

When should you use loops and fragments in your diagram code?

Sequence diagram fragments like loop, alt, opt, and par let you express conditional and repeated behavior. In microservices, you'll use them often. A loop fragment for batch processing might look like this:

loop for each item in batch
  OrderService -> InventoryService: reserveItem(itemId)
  InventoryService --> OrderService: reserved
end

An alt fragment for success vs. failure branching:

alt payment successful
  PaymentService --> OrderService: 200 OK
  OrderService ->> EventBus: OrderConfirmed
else payment failed
  PaymentService --> OrderService: 402 Payment Required
  OrderService ->> EventBus: OrderFailed
end

For a deeper dive into visualizing API call flows specifically, check out our guide on sequence diagram markup for API call flow visualization.

What's a real-world example of a complete microservices flow?

Here's a more complete scenario: a user signs up, places an order, and receives a notification. This involves an auth service, order service, payment service, inventory service, notification service, and a message broker.

actor User
participant APIGateway
participant AuthService
participant OrderService
participant InventoryService
participant PaymentService
participant EventBus
participant NotificationService

User -> APIGateway: POST /auth/login
APIGateway -> AuthService: authenticate(email, password)
AuthService --> APIGateway: JWT token
APIGateway --> User: 200 OK + token

User -> APIGateway: POST /orders (Bearer token)
APIGateway -> AuthService: validateToken(token)
AuthService --> APIGateway: valid, userId
APIGateway -> OrderService: createOrder(userId, items)
OrderService -> InventoryService: checkStock(items)
InventoryService --> OrderService: all items available
OrderService -> PaymentService: charge(userId, total)
PaymentService --> OrderService: charged
OrderService -> InventoryService: decrementStock(items)
InventoryService --> OrderService: stock updated
OrderService ->> EventBus: OrderPlaced event
OrderService --> APIGateway: 201 Created + orderId
APIGateway --> User: 201 Created
EventBus ->> NotificationService: OrderPlaced event
NotificationService ->> User: email confirmation

This single diagram captures authentication, authorization, synchronous service calls, inventory updates, event publishing, and async notification delivery. You can read more about how these examples fit into the broader markup in our microservices architecture sequence diagram examples collection.

What common mistakes do people make when diagramming microservices?

After working with teams that use sequence diagrams for service documentation, these are the errors that come up most:

  • Showing too many services at once. If your diagram has 15 participants, split it into multiple diagrams by bounded context or use case. One diagram per user story is a good rule of thumb.
  • Leaving out the message broker. If your services communicate through Kafka or RabbitMQ, include the broker as a participant. Skipping it makes async flows look like direct service-to-service calls, which is misleading.
  • Only documenting the happy path. Error flows, timeouts, and retries are where the real complexity lives. Document at least the most common failure scenarios.
  • Not versioning your diagrams. Diagram-as-code solves this naturally just commit the file to your repo. But teams that still use drag-and-drop tools often forget to update diagrams when the architecture changes.
  • Using vague participant names. Use the actual service name as it appears in your service registry or deployment config. "Service A" tells no one anything six months later.

How do you keep sequence diagrams useful as your system grows?

A few practices that help teams actually maintain their diagrams over time:

  • Store diagram source files next to the service code. When a developer changes a service's API contract, the diagram is right there to update.
  • Generate diagrams in your CI pipeline. Most text-based diagram tools have CLI support. Render them to SVG or PNG on every build and publish them to your internal docs site.
  • Use consistent naming. Agree on participant names, arrow styles, and fragment notation across your team. Inconsistent diagrams are worse than no diagrams.
  • Write one diagram per API endpoint or user journey. This keeps each diagram focused and easy to review in a pull request.
  • Review diagrams in code reviews. Treat them like any other documentation change. If the architecture shifts, the diagram should shift with it.

Quick checklist for writing your first microservices sequence diagram

  1. List all services involved in the flow you want to document.
  2. Identify which calls are synchronous (request/response) and which are asynchronous (events/messages).
  3. Write the participant declarations first, using real service names.
  4. Map out the happy path messages in order from left to right.
  5. Add error handling with alt fragments for the two or three most likely failure points.
  6. Include the message broker as a participant if async messaging is involved.
  7. Save the file with a descriptive name like order-placement-flow.puml or user-signup-sequence.sdm and commit it to your repo.
  8. Render the diagram and share it with your team for review before merging.

Start with one flow you've recently debuged or onboarded a new team member on. Those are the sequences where a visual diagram provides the most immediate value.