Real examples of Graphviz


This week we wanted to highlight graphviz.

Grpahviz diagram

What are main reasons to use Graphviz/DOT:

  1. diagrams as code:
    • easy to review in pull requests.
    • can be embed in your documentation. Supported by sphinx and many others.
    • track the history of changes
    • very simple and intuitive DSL to create by hands
  2. very easy to create programmatically:
    • helper libraries in most of the programming languages (python, javascript, ruby, java you name it)
    • DSL is so easy, so you don't even need a library to create it in your script.

In this article I will show several use cases I personally use Graphviz for.

  1. business flow diagram
  2. microservices interaction
  3. software architecture diagram
  4. workflow diagram
  5. entity relationship diagram

Business Process Diagram

Business process diagram (or BPMN) is a diagram describing business process.

If you are working with DDD (domain driven design) or work with enterprise software you probably read or even write them.


digraph BPMN {
  node[shape=rectanble style="rounded,filled" color="lightgoldenrodyellow" ]
  start[shape=circle color=palegreen1]
  end[shape=doublecircle color=orangered]
  join, join2[shape=diamond label="" style="filled" fillcolor=orange]
  wait, delay[shape=circle color="lightgoldenrod1"]
  start -> announce
  announce -> delay
  announce -> moderate
  moderate -> join2
  delay -> email
  announce -> check_cal
  check_cal -> conf_call
  conf_call -> wait[label=yes]
  moderate_conf[label="moderate \nconference call"]
  wait -> moderate_conf
  moderate_conf -> join
  conf_call -> join[label=no]


(you can play with business process example here)

Microservices Interaction

When you operate in a microservice environment sometimes you need to visualize what's going on.

There are some sub-types of the interactions you care about.

  1. general picture of the service dependencies. With thousands of service running in production sometimes it's hard to understand the dependencies between them. Visual picture is great for that.
  2. you can overlay number of requests on top of #1 above, so you see fanout and how traffic is distributed to microservices.
  3. visualizing specific request aka trace. If you use distributed tracing then you might have some built-in solution for this. If you can create your own and visualize it.
  4. add latencies on top of a single trace or p50/p90/p99 on top of aggregate graph.

Here is an example graph with latencies displayed:

digraph ServiceInteraction {
    apiGateway -> usersService[color=green label="34ms" fontcolor="green"]
    apiGateway -> organizationService[color=red label="552ms" fontcolor="red"]
    organizationService->organizationSearch[color=red label="540ms" fontcolor="red"]
    apiGateway -> repoService[color=orange label="220ms" fontcolor="orange"]
    repoService -> starGazerCache[color=orange label="200ms" fontcolor="orange"]
    repoService -> watchersCache[color=green label="15ms" fontcolor="green"]


(you can play with Microservice Interaction example here)

Software Architecture Diagram

You are probably using LucidChart, Vizio, Google Docs shapes or similar when creating your design documents or RFCs.

Why it's better to use Graphviz?

  1. have diagrams in your code review / pull request.
  2. check in and modify designs during implementation phase to keep design close to implemnentation.
  3. collaborate on design with your colleagues.

Example architecture diagram:

digraph MessageArchitecture {
  messageClient -> messageBackend[label=sendMessage]
  messageBackend -> userService
  userService -> userDB
  messageBackend -> messageDB
  messageDB -> messageQueue[label="change data captrure"]
  messageQueue -> messageNotifier
  messageNotifier -> pushNotifications


(you can play with Architecture Diagram example here)

workflow diagram

There are multiple workflow systems availabe (Amazon SWF, Amazon Step functions, Netflix conductor, Uber Cadence, Camunda etc).

Some of them come with their own visualization tools and some don't.

Many reasons why you might want to build Graphviz representation for your Workflow Diagrams:

  1. check-in with your documentation.
  2. sketch it before implementing at design phase
  3. regenerate it from your workflow code; then this can be peer-reviewed at pull request. sometimes it isn't obvious what's changed in your workflow until you see it visually.
  4. visualize particular workflow execution or aggregate across all instance of a workflow.

Example workflow graph:

digraph BookingWorkflow {
  successful_payment[shape=diamond label="success?"]
  start -> lock_booking
  lock_booking -> process_payment
  process_payment -> successful_payment
  successful_payment -> release_booking[label=NO]
  successful_payment -> reserve_booking[label=Yes]
  reserve_booking -> send_email
  send_email -> end
  release_booking -> end


(you can play with Workflow Diagram example here)

entity relationship diagram

Where do you need ERD?

  • During design phase to show your entities and relationships between them
  • Visually see existing entities (from your DB tables)

Visually see the entities and relationships between them can be invaluable especially in your documentation or designs.

Representing it as code (graphviz/dot) is great because:

  1. it can be checked into your documentation, code reviewed.
  2. auto-generated from your DB or RPC schema.

There are some open source projects already that help you to build ERD diagrams from protobuf. Most of the DB clients allow you to build visual ERD from DB schema.

Example ERD represented in graphviz:

digraph GitHub {
    graph [
        rankdir = "LR"
    node[shape = record];     
    organization[label="Organization | { url | string } | {id | int} "]
    user[label="User | {avatar|string} | {email|string}"]
    repository[label="Repository | {name|string} | {stargazers_count|int}"]
    repository -> user[label=stargazers taillabel=1 headlabel=N dir=both]
    organization -> repository[label=repos taillabel=1 headlabel=N]
    organization -> user[label=members taillabel=1 headlabel=N]


(you can play with ERD example here)

This article was originally published in DevToolsDaily blog