Examples

Nine reference architectures — the system-design classics, each one file. Every picture here is rendered by the engine from the source under it; open any of them in the Playground and change it.

URL shortener

the classic warm-up: a write path that mints keys, a read path that must be fast

13 objects · 7 relations · 5 placements · Open in Playground →

ArchCode diagram — 8 objects, 7 relations URL shortener · [system]URL shortener[system] next unique key 302 fast path cache miss new link warm the cache drop expired shorten · redirect · via lb User · [actor]User[actor] Browser · [external]Browser[external] Shortener API · [service] · GoShortener API[service]Go Key generator · [service] · GoKey generator[service]Go Hot links · [cache] · RedisHot links[cache]Redis Links DB · [datastore] · PostgreSQLLinks DB[datastore]PostgreSQL Expiry sweeper · [job] · GoExpiry sweeper[job]Go ArchCode diagram — 8 objects, 7 relations URL shortener · [system]URL shortener[system] next unique key 302 fast path cache miss new link warm the cache drop expired shorten · redirect · via lb User · [actor]User[actor] Browser · [external]Browser[external] Shortener API · [service] · GoShortener API[service]Go Key generator · [service] · GoKey generator[service]Go Hot links · [cache] · RedisHot links[cache]Redis Links DB · [datastore] · PostgreSQLLinks DB[datastore]PostgreSQL Expiry sweeper · [job] · GoExpiry sweeper[job]Go
source · 10-url-shortener.arch
# URL shortener — the classic warm-up: a write path that mints keys, a read path that must be fast
actor    user     "User"
external browser  "Browser"

system shortener "URL shortener" {
  gateway   lb       "Load balancer"     { transit }
  service   api      "Shortener API"     tech Go
  service   keygen   "Key generator"     tech Go
  cache     redis    "Hot links"         tech Redis        owned_by api
  datastore urls     "Links DB"          tech PostgreSQL   owned_by api
  job       cleaner  "Expiry sweeper"    tech Go

  api     calls  keygen  over gRPC   "next unique key"
  api     reads  redis   over RESP   "302 fast path"
  api     reads  urls    over SQL    "cache miss"
  api     writes urls    over SQL    "new link"
  api     writes redis   over RESP   "warm the cache"
  cleaner writes urls    over SQL    "drop expired"
}

user calls shortener.api over HTTPS via shortener.lb "shorten · redirect"

env prod "Production" {
  cluster k8s "Kubernetes" nodes 3 cpu 8 mem 32Gi {
    run shortener.api    replicas 4 cpu 0.5 mem 512Mi
    run shortener.keygen replicas 2 cpu 0.25 mem 256Mi
    run shortener.cleaner replicas 1
  }
  managed cache_svc "Managed Redis"    { run shortener.redis }
  managed pg        "Managed Postgres" { run shortener.urls }
}

Rate limiter

a gateway that says no politely, with counters in a shared cache and rules in a store

11 objects · 5 relations · 4 placements · Open in Playground →

ArchCode diagram — 6 objects, 5 relations API edge · [system]API edge[system] take a token refill limits per client, cached 30s allowed every request · via gw API client · [actor]API client[actor] Rate limiter · [service] · Go token bucket per keyRate limiter[service]Go token bucket per key Counters · [cache] · RedisCounters[cache]Redis Rules · [datastore] · etcdRules[datastore]etcd Protected service · [service] · KotlinProtected service[service]Kotlin ArchCode diagram — 6 objects, 5 relations API edge · [system]API edge[system] take a token refill limits per client, cached 30s allowed every request · via gw API client · [actor]API client[actor] Rate limiter · [service] · Go token bucket per keyRate limiter[service]Go token bucket per key Counters · [cache] · RedisCounters[cache]Redis Rules · [datastore] · etcdRules[datastore]etcd Protected service · [service] · KotlinProtected service[service]Kotlin
source · 11-rate-limiter.arch
# Rate limiter — a gateway that says no politely, with counters in a shared cache and rules in a store
actor    client   "API client"

system edge "API edge" {
  gateway   gw        "API gateway"        { transit  tech Envoy }
  service   limiter   "Rate limiter"       tech Go     "token bucket per key"
  cache     counters  "Counters"           tech Redis  owned_by limiter
  datastore rules     "Rules"              tech etcd   owned_by limiter
  service   backend   "Protected service"  tech Kotlin

  limiter reads  counters over RESP  "take a token"
  limiter writes counters over RESP  "refill"
  limiter reads  rules    over gRPC  "limits per client, cached 30s"
}

client calls edge.limiter over HTTPS via edge.gw "every request"
edge.limiter calls edge.backend over HTTP "allowed"

env prod "Production" {
  cluster k8s "Kubernetes" nodes 4 cpu 8 mem 32Gi {
    run edge.limiter replicas 6 cpu 0.5 mem 256Mi
    run edge.backend replicas 3 cpu 1   mem 1Gi
  }
  managed redis_svc "Managed Redis" { run edge.counters }
  node    etcd1 "etcd" count 3 cpu 2 mem 4Gi { run edge.rules }
}

News feed

fan-out on write: a post lands in every follower's feed cache before they ask

12 objects · 10 relations · Open in Playground →

ArchCode diagram — 9 objects, 9 relations News feed · [system]News feed[system] CQL images, video followers of the author push the post id into each follower's list RESP hydrate the ids post.created publish · via gw read the feed · via gw Member · [actor]Member[actor] Post service · [service] · JavaPost service[service]Java Fan-out worker · [service] · JavaFan-out worker[service]Java Social graph · [service] · GoSocial graph[service]Go Feed service · [service] · JavaFeed service[service]Java Feed cache · [cache] · RedisFeed cache[cache]Redis Posts · [datastore] · CassandraPosts[datastore]Cassandra Media · [datastore] · S3Media[datastore]S3 ArchCode diagram — 9 objects, 9 relations News feed · [system]News feed[system] CQL images, video followers of the author push the post id into each follower's list RESP hydrate the ids post.created publish · via gw read the feed · via gw Member · [actor]Member[actor] Post service · [service] · JavaPost service[service]Java Fan-out worker · [service] · JavaFan-out worker[service]Java Social graph · [service] · GoSocial graph[service]Go Feed service · [service] · JavaFeed service[service]Java Feed cache · [cache] · RedisFeed cache[cache]Redis Posts · [datastore] · CassandraPosts[datastore]Cassandra Media · [datastore] · S3Media[datastore]S3
source · 12-news-feed.arch
# News feed — fan-out on write: a post lands in every follower's feed cache before they ask
actor    member   "Member"

system feed "News feed" {
  gateway   gw        "API gateway"      { transit }
  service   posts     "Post service"     tech Java
  service   fanout    "Fan-out worker"   tech Java
  service   social    "Social graph"     tech Go
  service   timeline  "Feed service"     tech Java
  broker    events    "Post events"      { transit  tech Kafka }
  topic     post.created
  cache     feeds     "Feed cache"       tech Redis      owned_by timeline
  datastore post_db   "Posts"            tech Cassandra  owned_by posts
  datastore media     "Media"            tech S3         owned_by posts

  posts    writes     post_db  over CQL
  posts    writes     media    over HTTPS   "images, video"
  posts    publishes  post.created via events
  fanout   subscribes post.created via events
  fanout   calls      social   over gRPC    "followers of the author"
  fanout   writes     feeds    over RESP    "push the post id into each follower's list"
  timeline reads      feeds    over RESP
  timeline reads      post_db  over CQL     "hydrate the ids"
}

member calls feed.posts    over HTTPS via feed.gw "publish"
member calls feed.timeline over HTTPS via feed.gw "read the feed"

Chat

long-lived connections in front, a message log behind, presence on the side

12 objects · 9 relations · Open in Playground →

ArchCode diagram — 9 objects, 8 relations Chat · [system]Chat[system] CQL heartbeats with a TTL deliver now or queue message.sent send · receive · via ws heartbeat · via ws HTTPS HTTPS Person · [actor]Person[actor] Message service · [service] · ElixirMessage service[service]Elixir Presence · [service] · ElixirPresence[service]Elixir Push relay · [service] · GoPush relay[service]Go Message log · [datastore] · ScyllaDBMessage log[datastore]ScyllaDB Who is online · [cache] · RedisWho is online[cache]Redis Apple Push · [external]Apple Push[external] Google Push · [external]Google Push[external] ArchCode diagram — 9 objects, 8 relations Chat · [system]Chat[system] CQL heartbeats with a TTL deliver now or queue message.sent send · receive · via ws heartbeat · via ws HTTPS HTTPS Person · [actor]Person[actor] Message service · [service] · ElixirMessage service[service]Elixir Presence · [service] · ElixirPresence[service]Elixir Push relay · [service] · GoPush relay[service]Go Message log · [datastore] · ScyllaDBMessage log[datastore]ScyllaDB Who is online · [cache] · RedisWho is online[cache]Redis Apple Push · [external]Apple Push[external] Google Push · [external]Google Push[external]
source · 13-chat.arch
# Chat — long-lived connections in front, a message log behind, presence on the side
actor    person   "Person"

system chat "Chat" {
  gateway   ws        "WebSocket gateway"  { transit  tech Go }
  service   messages  "Message service"    tech Elixir
  service   presence  "Presence"           tech Elixir
  service   push      "Push relay"         tech Go
  broker    bus       "Message bus"        { transit  tech NATS }
  topic     message.sent
  datastore log       "Message log"        tech ScyllaDB  owned_by messages
  cache     online    "Who is online"      tech Redis     owned_by presence

  messages  writes     log      over CQL
  messages  publishes  message.sent via bus
  push      subscribes message.sent via bus   "recipient offline → notify"
  presence  writes     online   over RESP     "heartbeats with a TTL"
  messages  reads      online   over RESP     "deliver now or queue"
}

external apns "Apple Push"   { stage live }
external fcm  "Google Push"  { stage live }

person       calls chat.messages over WSS via chat.ws "send · receive"
person       calls chat.presence over WSS via chat.ws "heartbeat"
chat.push    calls apns over HTTPS
chat.push    calls fcm  over HTTPS

Notification system

one API in, three channels out, every provider behind a worker of its own

16 objects · 15 relations · Open in Playground →

ArchCode diagram — 12 objects, 12 relations Notifications · [system]Notifications[system] opt-outs, quiet hours SQL HTTP HTTP HTTP send.email send.sms send.push send(user, template, data) HTTPS HTTPS HTTPS Notification API · [service] · PythonNotification API[service]Python Email worker · [service] · PythonEmail worker[service]Python SMS worker · [service] · PythonSMS worker[service]Python Push worker · [service] · PythonPush worker[service]Python Templates · [datastore] · PostgreSQLTemplates[datastore]PostgreSQL User preferences · [datastore] · PostgreSQLUser preferences[datastore]PostgreSQL Delivery log · [datastore] · ClickHouseDelivery log[datastore]ClickHouse Orders service · [external]Orders service[external] Email provider · [external]Email provider[external] SMS gateway · [external]SMS gateway[external] Push service · [external]Push service[external] ArchCode diagram — 12 objects, 12 relations Notifications · [system]Notifications[system] opt-outs, quiet hours SQL HTTP HTTP HTTP send.email send.sms send.push send(user, template, data) HTTPS HTTPS HTTPS Notification API · [service] · PythonNotification API[service]Python Email worker · [service] · PythonEmail worker[service]Python SMS worker · [service] · PythonSMS worker[service]Python Push worker · [service] · PythonPush worker[service]Python Templates · [datastore] · PostgreSQLTemplates[datastore]PostgreSQL User preferences · [datastore] · PostgreSQLUser preferences[datastore]PostgreSQL Delivery log · [datastore] · ClickHouseDelivery log[datastore]ClickHouse Orders service · [external]Orders service[external] Email provider · [external]Email provider[external] SMS gateway · [external]SMS gateway[external] Push service · [external]Push service[external]
source · 14-notifications.arch
# Notification system — one API in, three channels out, every provider behind a worker of its own
system notify "Notifications" {
  service   api        "Notification API"   tech Python
  broker    queue      "Channel queues"     { transit  tech RabbitMQ }
  topic     send.email
  topic     send.sms
  topic     send.push
  service   email_wrk  "Email worker"       tech Python
  service   sms_wrk    "SMS worker"         tech Python
  service   push_wrk   "Push worker"        tech Python
  datastore templates  "Templates"          tech PostgreSQL  owned_by api
  datastore prefs      "User preferences"   tech PostgreSQL  owned_by api
  datastore sent       "Delivery log"       tech ClickHouse

  api       reads      prefs      over SQL   "opt-outs, quiet hours"
  api       reads      templates  over SQL
  api       publishes  send.email via queue
  api       publishes  send.sms   via queue
  api       publishes  send.push  via queue
  email_wrk subscribes send.email via queue
  sms_wrk   subscribes send.sms   via queue
  push_wrk  subscribes send.push  via queue
  email_wrk writes sent over HTTP
  sms_wrk   writes sent over HTTP
  push_wrk  writes sent over HTTP
}

external orders   "Orders service"   description "an internal caller"
external mailer   "Email provider"
external smsgw    "SMS gateway"
external pushgw   "Push service"

orders           calls notify.api over HTTPS "send(user, template, data)"
notify.email_wrk calls mailer over HTTPS
notify.sms_wrk   calls smsgw  over HTTPS
notify.push_wrk  calls pushgw over HTTPS

Video upload & playback

upload once, transcode into renditions, serve from a CDN

14 objects · 11 relations · 3 placements · Open in Playground →

ArchCode diagram — 10 objects, 10 relations Video platform · [system]Video platform[system] multipart, resumable HTTPS 1080p · 720p · 480p · HLS ready SQL video.uploaded upload browse · play segments origin pull Creator · [actor]Creator[actor] Viewer · [actor]Viewer[actor] CDN · [external]CDN[external] Upload service · [service] · GoUpload service[service]Go Transcoder · [job] · C++ · ffmpegTranscoder[job]C++ · ffmpeg Catalog API · [service] · GoCatalog API[service]Go Raw uploads · [datastore] · S3Raw uploads[datastore]S3 Renditions · [datastore] · S3Renditions[datastore]S3 Video metadata · [datastore] · PostgreSQLVideo metadata[datastore]PostgreSQL ArchCode diagram — 10 objects, 10 relations Video platform · [system]Video platform[system] multipart, resumable HTTPS 1080p · 720p · 480p · HLS ready SQL video.uploaded upload browse · play segments origin pull Creator · [actor]Creator[actor] Viewer · [actor]Viewer[actor] CDN · [external]CDN[external] Upload service · [service] · GoUpload service[service]Go Transcoder · [job] · C++ · ffmpegTranscoder[job]C++ · ffmpeg Catalog API · [service] · GoCatalog API[service]Go Raw uploads · [datastore] · S3Raw uploads[datastore]S3 Renditions · [datastore] · S3Renditions[datastore]S3 Video metadata · [datastore] · PostgreSQLVideo metadata[datastore]PostgreSQL
source · 15-video-upload.arch
# Video upload & playback — upload once, transcode into renditions, serve from a CDN
actor    creator  "Creator"
actor    viewer   "Viewer"
external cdn      "CDN"

system video "Video platform" {
  service   upload     "Upload service"    tech Go
  job       transcode  "Transcoder"        tech "C++ · ffmpeg"
  service   catalog    "Catalog API"       tech Go
  broker    jobs       "Transcode jobs"    { transit  tech SQS }
  topic     video.uploaded
  datastore raw        "Raw uploads"       tech S3   owned_by upload
  datastore renditions "Renditions"        tech S3   owned_by transcode
  datastore meta       "Video metadata"    tech PostgreSQL  owned_by catalog

  upload    writes     raw        over HTTPS   "multipart, resumable"
  upload    publishes  video.uploaded via jobs
  transcode subscribes video.uploaded via jobs
  transcode reads      raw        over HTTPS
  transcode writes     renditions over HTTPS   "1080p · 720p · 480p · HLS"
  transcode writes     meta       over SQL     "ready"
  catalog   reads      meta       over SQL
}

creator calls video.upload  over HTTPS "upload"
viewer  calls video.catalog over HTTPS "browse · play"
viewer  calls cdn           over HTTPS "segments"
cdn     reads video.renditions over HTTPS "origin pull"

env prod "Production" {
  cluster k8s "Kubernetes" nodes 6 cpu 16 mem 64Gi {
    run video.upload    replicas 3 cpu 1 mem 2Gi
    run video.catalog   replicas 3 cpu 0.5 mem 1Gi
    run video.transcode replicas 8 cpu 4 mem 8Gi
  }
}

Ticket shop

sizing: the figures live beside the services, the resources table is computed from

19 objects · 12 relations · 18 placements · Open in Playground →

ArchCode diagram — 11 objects, 12 relations Ticket shop · [system]Ticket shop[system] browse · via gw hold a seat · via gw pay · via gw SQL SQL hold for 10 min SQL confirm the seat RESP SQL HTTPS authorise Buyer · [actor]Buyer[actor] Payment provider · [external] · RESTPayment provider[external]REST Web shop · [webapp] · Next.jsWeb shop[webapp]Next.js Catalog · [service] · Go · 0.5 cpu · 512MiCatalog[service]Go0.5 cpu · 512Mi Booking · [service] · Go · 1 cpu · 1Gi · rps 800 · p99 150msBooking[service]Go1 cpu · 1Gi · rps 800 · p99 150ms Payments · [service] · Kotlin · 1 cpu · 1GiPayments[service]Kotlin1 cpu · 1Gi Seat release · [job] · GoSeat release[job]Go Seat holds · [cache] · RedisSeat holds[cache]Redis Events & seats · [datastore] · PostgreSQL 16 · size 120Gi · growth 6Gi/moEvents & seats[datastore]PostgreSQL 16size 120Gi · growth 6Gi/mo Orders · [datastore] · PostgreSQL 16 · size 80Gi · growth 9Gi/moOrders[datastore]PostgreSQL 16size 80Gi · growth 9Gi/mo ArchCode diagram — 11 objects, 12 relations Ticket shop · [system]Ticket shop[system] browse · via gw hold a seat · via gw pay · via gw SQL SQL hold for 10 min SQL confirm the seat RESP SQL HTTPS authorise Buyer · [actor]Buyer[actor] Payment provider · [external] · RESTPayment provider[external]REST Web shop · [webapp] · Next.jsWeb shop[webapp]Next.js Catalog · [service] · Go · 0.5 cpu · 512MiCatalog[service]Go0.5 cpu · 512Mi Booking · [service] · Go · 1 cpu · 1Gi · rps 800 · p99 150msBooking[service]Go1 cpu · 1Gi · rps 800 · p99 150ms Payments · [service] · Kotlin · 1 cpu · 1GiPayments[service]Kotlin1 cpu · 1Gi Seat release · [job] · GoSeat release[job]Go Seat holds · [cache] · RedisSeat holds[cache]Redis Events & seats · [datastore] · PostgreSQL 16 · size 120Gi · growth 6Gi/moEvents & seats[datastore]PostgreSQL 16size 120Gi · growth 6Gi/mo Orders · [datastore] · PostgreSQL 16 · size 80Gi · growth 9Gi/moOrders[datastore]PostgreSQL 16size 80Gi · growth 9Gi/mo
source · 16-ticket-shop-sizing.arch
# Ticket shop — sizing: the figures live beside the services, the resources table is computed from
# them per environment and per moment (`at 2027-06 …`), and a store's growth is projected.
# Open the Resources tab; then change a replica count and watch the totals move.

actor    buyer "Buyer"
external psp   "Payment provider" tech REST

system tickets "Ticket shop" owner @team-tickets availability 24x7 {
  webapp    web       "Web shop"       tech Next.js
  gateway   gw        "API gateway"    tech Envoy { transit }
  service   catalog   "Catalog"        tech Go     cpu 0.5 mem 512Mi
  service   booking   "Booking"        tech Go     cpu 1   mem 1Gi   { capacity rps 800 p99 150ms }
  service   payments  "Payments"       tech Kotlin cpu 1   mem 1Gi
  job       release   "Seat release"   tech Go     description "frees seats held longer than 10 minutes"
  cache     holds     "Seat holds"     tech Redis
  datastore events_db "Events & seats" tech "PostgreSQL 16" owned_by booking  { capacity size 120Gi growth 6Gi/mo }
  datastore orders_db "Orders"         tech "PostgreSQL 16" owned_by payments { capacity size 80Gi  growth 9Gi/mo }
}

buyer            calls  tickets.web       over HTTPS
tickets.web      calls  tickets.catalog   over HTTPS via tickets.gw "browse"
tickets.web      calls  tickets.booking   over HTTPS via tickets.gw "hold a seat"
tickets.web      calls  tickets.payments  over HTTPS via tickets.gw "pay"
tickets.catalog  reads  tickets.events_db over SQL
tickets.booking  writes tickets.events_db over SQL
tickets.booking  writes tickets.holds     over RESP "hold for 10 min"
tickets.payments calls  psp               over HTTPS "authorise"
tickets.payments writes tickets.orders_db over SQL
tickets.payments calls  tickets.booking   over gRPC "confirm the seat"
tickets.release  reads  tickets.holds     over RESP
tickets.release  writes tickets.events_db over SQL

env prod "Production" {
  cluster k8s "Kubernetes" nodes 4 cpu 8 mem 32Gi disk 100Gi {
    run tickets.web      replicas 2 cpu 0.3/1   mem 256Mi/512Mi
    run tickets.gw       replicas 2 cpu 0.5/1   mem 256Mi/512Mi
    run tickets.catalog  replicas 2 cpu 0.5/1   mem 512Mi/1Gi
    run tickets.booking  replicas 3 cpu 1/2     mem 1Gi/2Gi      at 2027-06 replicas 6
    run tickets.payments replicas 2 cpu 1/2     mem 1Gi/2Gi
    run tickets.release  replicas 1 cpu 0.2/0.5 mem 128Mi/256Mi
    agent fluent_bit, node_exporter
  }
  node cache "Redis VMs" count 2 cpu 4 mem 8Gi disk 40Gi {
    run tickets.holds
    agent node_exporter, keepalived
    at 2027-06 count 3
  }
  managed pg "Managed Postgres" {
    run tickets.events_db disk 500Gi
    run tickets.orders_db disk 300Gi
  }
}

env stage "Staging" {
  cluster k8s "Kubernetes" nodes 2 cpu 4 mem 16Gi disk 50Gi {
    run tickets.web, tickets.gw, tickets.catalog, tickets.booking, tickets.payments, tickets.release
    agent fluent_bit
  }
  node one "One VM" cpu 4 mem 8Gi disk 100Gi { run tickets.holds, tickets.events_db, tickets.orders_db  agent node_exporter }
}

Parcel tracking

the infrastructure layer: a gateway in front, a broker between, both `transit`.

15 objects · 13 relations · Open in Playground →

ArchCode diagram — 11 objects, 11 relations Parcel tracking · [system]Parcel tracking[system] where is my parcel · via gw scan · via gw SQL RESP SQL RESP parcel.scanned parcel.delivered HTTPS HTTPS delivered Customer · [actor]Customer[actor] Courier · [actor]Courier[actor] SMS provider · [external] · RESTSMS provider[external]REST Tracking site · [webapp] · ReactTracking site[webapp]React Courier app · [webapp] · React NativeCourier app[webapp]React Native Parcels · [service] · GoParcels[service]Go Scan intake · [service] · GoScan intake[service]Go Notifications · [service] · PythonNotifications[service]Python Parcels · [datastore] · PostgreSQL 16Parcels[datastore]PostgreSQL 16 ETA cache · [cache] · RedisETA cache[cache]Redis ArchCode diagram — 11 objects, 11 relations Parcel tracking · [system]Parcel tracking[system] where is my parcel · via gw scan · via gw SQL RESP SQL RESP parcel.scanned parcel.delivered HTTPS HTTPS delivered Customer · [actor]Customer[actor] Courier · [actor]Courier[actor] SMS provider · [external] · RESTSMS provider[external]REST Tracking site · [webapp] · ReactTracking site[webapp]React Courier app · [webapp] · React NativeCourier app[webapp]React Native Parcels · [service] · GoParcels[service]Go Scan intake · [service] · GoScan intake[service]Go Notifications · [service] · PythonNotifications[service]Python Parcels · [datastore] · PostgreSQL 16Parcels[datastore]PostgreSQL 16 ETA cache · [cache] · RedisETA cache[cache]Redis
source · 17-api-edge-infrastructure.arch
# Parcel tracking — the infrastructure layer: a gateway in front, a broker between, both `transit`.
# The logical picture folds them into the arrows ("via gw", "via bus"); the Infrastructure lens
# opens them as cards with every hop. Same file, one switch, nothing redeclared.

actor    customer "Customer"
actor    courier  "Courier"           description "scans parcels from the app"
external sms      "SMS provider"      tech REST

system track "Parcel tracking" owner @team-track {
  webapp    site     "Tracking site"    tech React
  webapp    app      "Courier app"      tech "React Native"
  gateway   gw       "Edge gateway"     tech Kong    { transit }
  service   parcels  "Parcels"          tech Go
  service   scans    "Scan intake"      tech Go
  service   notify   "Notifications"    tech Python
  broker    bus      "Event bus"        tech Kafka   { transit }
  datastore parcels_db "Parcels"        tech "PostgreSQL 16" owned_by parcels
  cache     eta      "ETA cache"        tech Redis
  topic     parcel.scanned
  topic     parcel.delivered
}

customer      calls      track.site     over HTTPS
courier       calls      track.app      over HTTPS
track.site    calls      track.parcels  over HTTPS via track.gw "where is my parcel"
track.app     calls      track.scans    over HTTPS via track.gw "scan"
track.parcels reads      track.parcels_db over SQL
track.parcels reads      track.eta      over RESP
track.scans   writes     track.parcels_db over SQL
track.scans   publishes  parcel.scanned   via track.bus
track.scans   publishes  parcel.delivered via track.bus
track.parcels subscribes parcel.scanned   via track.bus "recompute the ETA"
track.parcels writes     track.eta      over RESP
track.notify  subscribes parcel.delivered via track.bus
track.notify  calls      sms            over HTTPS "delivered"

Inside one service

C3: a container opened to its components. `payments` is a card on the

17 objects · 13 relations · Open in Playground →

ArchCode diagram — 15 objects, 12 relations Web shop · [system]Web shop[system] Payments · [service] · KotlinPayments[service] checkout SQL authorise · capture SQL payment.captured HTTPS HTTPS post the invoice Customer · [actor]Customer[actor] Payment provider · [external] · RESTPayment provider[external]REST General ledger · [external] · SAPGeneral ledger[external]SAP Storefront · [webapp] · Next.jsStorefront[webapp]Next.js Orders · [service] · GoOrders[service]Go Payments API · [component] · Spring WebPayments API[component]Spring Web Payment flow · [component] · SpringPayment flow[component]Spring PSP client · [component] · WebClientPSP client[component]WebClient Outbox · [component] · Spring DataOutbox[component]Spring Data Payments repository · [component] · Spring Data JDBCPayments repository[component]Spring Data JDBC Invoicing · [service] · PythonInvoicing[service]Python Payments · [datastore] · PostgreSQL 16Payments[datastore]PostgreSQL 16 Orders · [datastore] · PostgreSQL 16Orders[datastore]PostgreSQL 16 ArchCode diagram — 15 objects, 12 relations Web shop · [system]Web shop[system] Payments · [service] · KotlinPayments[service] checkout SQL authorise · capture SQL payment.captured HTTPS HTTPS post the invoice Customer · [actor]Customer[actor] Payment provider · [external] · RESTPayment provider[external]REST General ledger · [external] · SAPGeneral ledger[external]SAP Storefront · [webapp] · Next.jsStorefront[webapp]Next.js Orders · [service] · GoOrders[service]Go Payments API · [component] · Spring WebPayments API[component]Spring Web Payment flow · [component] · SpringPayment flow[component]Spring PSP client · [component] · WebClientPSP client[component]WebClient Outbox · [component] · Spring DataOutbox[component]Spring Data Payments repository · [component] · Spring Data JDBCPayments repository[component]Spring Data JDBC Invoicing · [service] · PythonInvoicing[service]Python Payments · [datastore] · PostgreSQL 16Payments[datastore]PostgreSQL 16 Orders · [datastore] · PostgreSQL 16Orders[datastore]PostgreSQL 16
source · 18-service-components.arch
# Inside one service — C3: a container opened to its components. `payments` is a card on the
# system picture; expand it and the components appear inside, fold it and they go back.
# Everything around it stays exactly where it was.

actor    customer "Customer"
external psp      "Payment provider" tech REST
external ledger   "General ledger"   tech SAP

system shop "Web shop" owner @team-shop {
  webapp    web      "Storefront"   tech Next.js
  service   orders   "Orders"       tech Go
  service   payments "Payments"     tech Kotlin {
    component api       "Payments API"        tech "Spring Web"     description "REST controllers"
    component flow      "Payment flow"        tech "Spring"         description "authorise · capture · refund"
    component psp_client "PSP client"         tech "WebClient"
    component outbox    "Outbox"              tech "Spring Data"    description "events written with the transaction"
    component repo      "Payments repository" tech "Spring Data JDBC"
    api        calls  flow
    flow       calls  psp_client
    flow       calls  repo
    flow       calls  outbox
  }
  service   invoicing "Invoicing"    tech Python
  broker    bus       "Event bus"    tech Kafka { transit }
  datastore payments_db "Payments"   tech "PostgreSQL 16" owned_by payments
  datastore orders_db   "Orders"     tech "PostgreSQL 16" owned_by orders
  topic     payment.captured
}

customer         calls      shop.web           over HTTPS
shop.web         calls      shop.orders        over HTTPS "checkout"
shop.orders      writes     shop.orders_db     over SQL
shop.orders      calls      shop.payments.api  over gRPC "authorise · capture"
shop.payments.psp_client calls psp             over HTTPS
shop.payments.repo writes  shop.payments_db    over SQL
shop.payments.outbox publishes payment.captured via shop.bus
shop.invoicing   subscribes payment.captured   via shop.bus
shop.invoicing   calls      ledger             over HTTPS "post the invoice"