System Design examples
Fourteen complete examples: seven diagram purposes plus AWS, Azure, Google Cloud, Kubernetes, events, on-premises, and hybrid scenarios.
AAL System Design 0.2 · Dictionary 0.2.0
Use a complete example
Choose an example for the question you want your diagram to answer. Application Integration, Infrastructure, Data Pipeline, Event-Driven System, CI/CD, Security, and Observability offer different starting points. Provider-specific and hybrid examples add detail.
Try an example safely
- Create a separate System Design project. Choose Local to experiment in this browser.
- Copy a complete example below and replace the new project’s starter source. Wait for compilation and check diagnostics.
- Fit the canvas. Inspect a element and a relationship, then try the suggested changes.
- Save explicitly. Export a project file if you want an independent copy.
What to look for
- Compare nested source declarations with the canvas boundaries. Trace each relationship from its source.
- Adjust routes separately from attachments. The hybrid example is deliberately larger; visibility controls and Executive presentation help focus the audience.
- The examples are checked against the System Design compiler.
Choose a System Design example
Connected customer experience
Connect a customer portal, orders, CRM, and payments around one customer journey.
Application Integration · Beginner · Application Integration · Purposeful relationships · Stable resource IDs
aal system-design "0.2"
dictionary "0.2.0"
design Example "Connected customer experience" {
element Customer "Customer" { type generic.customer }
element Portal "Customer portal" { type generic.application }
element Orders "Orders API" { type generic.application }
element CRM "Customer CRM" { type generic.external_system }
element Payments "Payments" { type generic.external_system }
relation Flow1 Customer -> Portal connect "Uses"
relation Flow2 Portal -> Orders request_response "Place order"
relation Flow3 Orders -> CRM write "Update customer"
relation Flow4 Orders -> Payments request_response "Take payment"
}
Try changing…
- Rename Customer while preserving its ID; its relationships remain connected.
- Change the label of Flow1; its semantic direction stays the same.
- Arrange the diagram and export it as SVG; visual changes stay outside AAL.
Web application platform
Place an application and database inside a private network behind an API gateway.
Infrastructure · Beginner · Infrastructure · Purposeful relationships · Stable resource IDs
aal system-design "0.2"
dictionary "0.2.0"
design Example "Web application platform" {
environment "production"
element Customer "Customer" { type generic.customer }
element Gateway "API gateway" { type generic.api_gateway }
element Network "Private network" { type generic.network
element App "Application" { type generic.application_server }
element Data "Orders database" { type generic.database }
}
relation Flow1 Customer -> Gateway request_response "HTTPS"
relation Flow2 Gateway -> App request_response "Route request"
relation Flow3 App -> Data write "Save order"
}
Try changing…
- Rename Customer while preserving its ID; its relationships remain connected.
- Change the label of Flow1; its semantic direction stays the same.
- Arrange the diagram and export it as SVG; visual changes stay outside AAL.
From events to insights
Ingest application data, transform it, and make it available for reporting.
Data Pipeline · Beginner · Data Pipeline · Purposeful relationships · Stable resource IDs
aal system-design "0.2"
dictionary "0.2.0"
design Example "From events to insights" {
element Source "Source database" { type generic.database }
element Ingest "Ingestion" { type generic.pipeline }
element Transform "Transform data" { type generic.batch_job }
element Warehouse "Warehouse" { type generic.data_warehouse }
element Reports "Reporting" { type generic.dashboard }
relation Flow1 Source -> Ingest connect "Change stream"
relation Flow2 Ingest -> Transform invoke "Process batch"
relation Flow3 Transform -> Warehouse write "Load records"
relation Flow4 Reports -> Warehouse read "Query metrics"
}
Try changing…
- Rename Source while preserving its ID; its relationships remain connected.
- Change the label of Flow1; its semantic direction stays the same.
- Arrange the diagram and export it as SVG; visual changes stay outside AAL.
One order, independent consumers
Publish order events and distribute them to billing, inventory, and notifications.
Event-Driven System · Beginner · Event-Driven System · Purposeful relationships · Stable resource IDs
aal system-design "0.2"
dictionary "0.2.0"
design Example "One order, independent consumers" {
element Orders "Orders API" { type generic.application }
element Events "Order events" { type generic.event_bus }
element Billing "Billing" { type generic.subscriber }
element Inventory "Inventory" { type generic.subscriber }
element Notify "Notifications" { type generic.subscriber }
relation Flow1 Orders -> Events publish "OrderSubmitted"
relation Flow2 Events -> Billing deliver "Bill order"
relation Flow3 Events -> Inventory deliver "Reserve stock"
relation Flow4 Events -> Notify deliver "Notify customer"
}
Try changing…
- Rename Orders while preserving its ID; its relationships remain connected.
- Change the label of Flow1; its semantic direction stays the same.
- Arrange the diagram and export it as SVG; visual changes stay outside AAL.
From commit to deployment
Explain the dependencies between source control, build, artifacts, and runtime targets.
CI/CD · Beginner · CI/CD · Purposeful relationships · Stable resource IDs
aal system-design "0.2"
dictionary "0.2.0"
design Example "From commit to deployment" {
element Repo "Source repository" { type generic.repository }
element Build "Build and test" { type generic.pipeline }
element Registry "Artifact registry" { type generic.artifact_registry }
element Release "Release pipeline" { type generic.pipeline }
element Runtime "Application" { type generic.application }
relation Flow1 Repo -> Build invoke "Commit trigger"
relation Flow2 Build -> Registry write "Publish artifact"
relation Flow3 Release -> Registry read "Fetch artifact"
relation Flow4 Release -> Runtime invoke "Deploy release"
}
Try changing…
- Rename Repo while preserving its ID; its relationships remain connected.
- Change the label of Flow1; its semantic direction stays the same.
- Arrange the diagram and export it as SVG; visual changes stay outside AAL.
Protected application access
Show identity, access checks, and protected services without representing secret values.
Security · Beginner · Security · Purposeful relationships · Stable resource IDs
aal system-design "0.2"
dictionary "0.2.0"
design Example "Protected application access" {
element User "User" { type generic.user }
element Identity "Identity provider" { type generic.identity_provider }
element Gateway "API gateway" { type generic.api_gateway }
element Service "Protected API" { type generic.application }
element Data "Private data" { type generic.database }
relation Flow1 User -> Identity request_response "Sign in"
relation Flow2 User -> Gateway request_response "Authenticated request"
relation Flow3 Gateway -> Identity request_response "Validate identity"
relation Flow4 Gateway -> Service request_response "Authorized request"
relation Flow5 Service -> Data read "Read records"
}
Try changing…
- Rename User while preserving its ID; its relationships remain connected.
- Change the label of Flow1; its semantic direction stays the same.
- Arrange the diagram and export it as SVG; visual changes stay outside AAL.
Understand system health
Follow telemetry from services through collection, storage, dashboards, and alerts.
Observability · Beginner · Observability · Purposeful relationships · Stable resource IDs
aal system-design "0.2"
dictionary "0.2.0"
design Example "Understand system health" {
element Service "Application" { type generic.application }
element Collector "Telemetry collector" { type generic.collector }
element Logs "Logs and traces" { type generic.log_group }
element Metrics "Metrics" { type generic.metric }
element Dashboard "Health dashboard" { type generic.dashboard }
element Alert "Service alerts" { type generic.alarm }
relation Flow1 Service -> Collector telemetry "Emit telemetry"
relation Flow2 Collector -> Logs telemetry "Logs and traces"
relation Flow3 Collector -> Metrics telemetry "Metrics"
relation Flow4 Dashboard -> Logs read "Explore"
relation Flow5 Metrics -> Alert telemetry "Threshold crossed"
}
Try changing…
- Rename Service while preserving its ID; its relationships remain connected.
- Change the label of Flow1; its semantic direction stays the same.
- Arrange the diagram and export it as SVG; visual changes stay outside AAL.
AWS request/response application
Follow a request from a customer to an API and its storage. The response is part of the same interaction; it does not require a second semantic relationship.
Infrastructure · Beginner · Resource nesting · Request/response · Storage
aal system-design "0.2"
dictionary "0.2.0"
design CloudApp "Cloud application" {
environment "production"
element Customer "Customer" { type generic.customer }
element Account "Production" { type aws.account
element Region "Singapore" { type aws.region
element Api "Orders API" { type aws.lambda }
element Store "Order receipts" { type aws.s3.bucket }
}
}
relation Request Customer -> Api request_response "Submit order" { protocol "HTTPS" response "Accepted" }
relation Persist Api -> Store write "Store receipt"
}
Try changing…
- Change the Orders API display name to Checkout API; its resource label changes while existing connections keep working.
- Change the response label from Accepted to Order received; the return arrow displays the new label.
Azure web application and database
Model a customer using an Azure application backed by a SQL database. These resources document architectural intent rather than provider configuration.
Infrastructure · Beginner · Provider resource types · Request/response · Data storage
aal system-design "0.2"
dictionary "0.2.0"
design AzureApp "Azure customer portal" {
environment "production"
element Customer "Customer" { type generic.customer }
element Web "Orders web app" { type azure.app_service }
element Data "Orders database" { type azure.sql_database }
relation Request Customer -> Web request_response "Place order" { protocol "HTTPS" response "Order accepted" }
relation Persist Web -> Data write "Save order"
}
Try changing…
- Change the Web display name to "Customer portal"; the diagram label changes without breaking the Request relation.
- Add relation ReadOrders Web -> Data read "Read orders"; a second independent database interaction appears.
Google Cloud application and messaging
Separate an incoming request from asynchronous processing using Cloud Run and Pub/Sub. A delivered event does not imply a synchronous response.
Infrastructure · Intermediate · Managed compute · Publish and deliver · Asynchronous processing
aal system-design "0.2"
dictionary "0.2.0"
design GoogleApp "Google Cloud order processing" {
environment "production"
element Customer "Customer" { type generic.customer }
element Api "Orders API" { type gcp.cloud_run }
element Topic "Order events" { type gcp.pubsub }
element Worker "Order processor" { type gcp.cloud_run }
relation Request Customer -> Api request_response "Submit order" { protocol "HTTPS" response "Queued" }
relation Publish Api -> Topic publish "OrderSubmitted"
relation Deliver Topic -> Worker deliver "Process event"
}
Try changing…
- Add element Audit "Audit consumer" { type gcp.cloud_run } and relation AuditEvent Topic -> Audit deliver "Record event"; the topic now delivers to two consumers.
- Change the Publish label to "PaymentReceived"; the event name changes independently of the request label.
Kubernetes elements and nesting
Nest an API element inside a pod. Any element can contain children; namespace and cluster membership remain optional references.
Infrastructure · Intermediate · Elements and children · Containment · Namespace membership
aal system-design "0.2"
dictionary "0.2.0"
design Platform "Kubernetes platform" {
environment "production"
element Cluster "Orders cluster" { type aws.eks
element Namespace "orders" { type kubernetes.namespace }
element Service "Orders endpoint" { type kubernetes.service }
}
element Worker "Worker node" { type aws.ec2
member_of Cluster
element Pod "orders-api" { type kubernetes.pod
namespace Namespace
element Api "Orders API replica"
}
}
relation Forward Service -> Api request_response "Route request"
}
Try changing…
- Add element ApiTwo "Second replica" inside Pod; the pod now contains two independent elements.
- Set the API element technology to "Go"; the element retains its identity and parent.
Event-driven interactions
Publishing, delivering, invoking, and telemetry have different meanings. A publish line does not imply a synchronous reply. View controls can hide telemetry without deleting it.
Event-Driven System · Intermediate · Publish and deliver · Request/response · Telemetry
aal system-design "0.2"
dictionary "0.2.0"
design Events "Order events" {
environment "production"
element Api "Orders API" { type aws.lambda }
element Bus "Order events" { type aws.eventbridge.bus }
element Workflow "Process order" { type aws.step_functions }
element Handler "Fulfil order" { type aws.lambda }
element Logs "Operations" { type aws.cloudwatch }
relation Publish Api -> Bus publish "OrderSubmitted"
relation Deliver Bus -> Workflow deliver "Matching event"
relation Invoke Workflow -> Handler request_response "Invoke task"
relation Observe Handler -> Logs telemetry "Logs and metrics"
}
Try changing…
- Change the Publish label to "OrderPaid"; the event marker displays the new event name.
- Add relation ObserveApi Api -> Logs telemetry "API logs"; a second telemetry connection appears.
On-premises application and network
Show a site with a firewall, switch, application server, and database. Network connections describe connectivity, while nesting describes physical placement.
Infrastructure · Intermediate · Physical containment · Networking · Workload placement
aal system-design "0.2"
dictionary "0.2.0"
design OnPrem "On-premises orders" {
environment "production"
element Site "Primary data center" { type generic.data_center
element Firewall "Perimeter" { type generic.firewall }
element Switch "Application network" { type generic.switch }
element Host "Application server" { type generic.server
element App "Orders runtime"
}
element Data "Orders database" { type generic.database }
}
relation Entry Firewall -> Switch connect "Private network"
relation Network Switch -> Host connect "Server connection"
relation Persist App -> Data write "Save order"
}
Try changing…
- Change technology "Java" to technology "Go" on Orders; the software definition changes while placement remains intact.
- Add element Backup "Backup database" { type generic.database } inside Site and relation Replicate Data -> Backup write "Back up orders" at deployment scope; the backup appears inside the site with a write connection.
Hybrid infrastructure
A complete worked environment: on-premises entry and gateway, private cloud entry, two Kubernetes replicas, event processing, storage, notifications, and telemetry. Trace one request before exploring the event flow.
Infrastructure · Advanced · Cloud and on-premises · Software placement · Multiple interaction kinds
aal system-design "0.2"
dictionary "0.2.0"
design OrdersProduction "Orders — Production" {
environment "production"
element Customer "Customer" { type generic.customer }
element Phone "Customer phone" { type generic.mobile
element Mobile "Mobile App" { type generic.application }
}
element Akamai "Public API protection" { type akamai.waf }
element Site "Primary data center" { type generic.data_center
element WebVM "Web server" { type generic.vm
element Ihs "Public entry" { type ibm.ihs }
}
element GatewayVM "Gateway server" { type generic.vm
element Gateway "Orders Gateway" { type light.gateway }
}
}
element Aws "Production account" { type aws.account
element Region "Singapore" { type aws.region
element Cluster "Orders EKS" { type aws.eks
element Namespace "orders" { type kubernetes.namespace
element Service "Orders Service" { type kubernetes.service }
}
}
element Entry "Private API entry" { type aws.nlb }
element ZoneA "Availability Zone A" { type aws.availability_zone
element WorkerA "Worker A" { type aws.ec2
member_of Cluster
element PodA "orders-api-a" { type kubernetes.pod
namespace Namespace
element ApiA "Order API A"
}
}
}
element ZoneB "Availability Zone B" { type aws.availability_zone
element WorkerB "Worker B" { type aws.ec2
member_of Cluster
element PodB "orders-api-b" { type kubernetes.pod
namespace Namespace
element ApiB "Order API B"
}
}
}
element Events "Order events" { type aws.eventbridge.bus }
element Workflow "Process order" { type aws.step_functions }
element Subscriber "Order subscriber" { type aws.lambda }
element Receipts "Order receipts" { type aws.s3.bucket }
element Notifications "Order notifications" { type aws.sns.topic }
element Monitoring "Platform telemetry" { type aws.cloudwatch }
}
}
relation Uses Customer -> Mobile connect "Uses"
relation PublicRequest Mobile -> Akamai request_response "Submit order" { protocol "HTTPS" response "Order accepted" }
relation Origin Akamai -> Ihs request_response "Accepted request" { protocol "HTTPS" }
relation Forward Ihs -> Gateway request_response "Forward request"
relation Private Gateway -> Entry request_response "Private network"
relation Route Entry -> Service request_response "Service routing"
relation ReplicaA Service -> ApiA request_response "Route to A"
relation ReplicaB Service -> ApiB request_response "OR route to B"
relation EventA ApiA -> Events publish "OrderSubmitted"
relation EventB ApiB -> Events publish "OrderSubmitted"
relation Start Events -> Workflow deliver "Matching event starts workflow"
relation Process Workflow -> Subscriber request_response "Invoke task"
relation Receipt Subscriber -> Receipts write "Store receipt"
relation Notify Workflow -> Notifications publish "Order completed"
relation Observe Subscriber -> Monitoring telemetry "Logs and metrics"
}
Try changing…
- Change environment "production" to environment "staging"; the model describes a separate environment without provisioning anything.
- Hide telemetry in View, then show it again; those relationships remain in the source throughout.
- Collapse a containing resource; external connections follow the collapsed boundary without changing their source endpoints.