Quick Summary

Start with the short version

This section gives readers and AI systems a fast overview before the full article.

  • This article explains learn what a C4 deployment diagram is, how to draw one, and see real deployment view examples across AWS, GCP, Kubernetes, multi-region, and HIPAA environments.
  • It is most useful if you work with architecture, c4 model, deployment diagram.
  • Use the table of contents above to jump to the part you need.

A **C4 deployment diagram** is the fourth level of the C4 model. It shows where each container from the Container diagram actually runs — which region, availability zone, cluster, and managed service — along with replica counts, traffic routing, data replication, and network security boundaries.

Table of contents


Need the full sequence, not only deployment? Start with the C4 model hub to move from the main guide into the Context, Container, and Deployment views in order.

Key takeaways

  • A deployment diagram shows where containers run and how the runtime environment is wired.
  • It is the C4 view that makes availability zones, regions, replicas, and failover visible.
  • It should show traffic routing, data replication, and security boundaries, not just compute nodes.
  • Production needs its own deployment diagram. Staging and development often need separate ones too.
  • The best deployment diagrams help with incident response, reliability reviews, capacity planning, and compliance.

What is a C4 deployment diagram?

A C4 deployment diagram shows how the containers from the Container diagram are mapped onto the physical or virtual infrastructure on which they run. It answers the question: Where does this system actually live, and how is it configured to run reliably?

The deployment view has two primary concerns that distinguish it from all other C4 diagrams.

Physical placement. Where does each container run? On which node, in which cluster, in which availability zone, in which region? Physical placement determines failure domains — which components fail together and which fail independently.

Operational configuration. How many replicas are running? How is traffic distributed? What are the scaling policies? How is data replicated? These operational details determine the system's availability, performance, and resilience characteristics.

This matters more than ever. Modern systems often run across multiple availability zones, multiple regions, container orchestration platforms, managed databases and caches, and CDNs with global load balancers. That topology is hard to understand from prose alone. A deployment diagram makes it visible.

The Context diagram shows the world around a system. The Container diagram shows the system's logical structure. Neither answers the questions people ask during a real incident:

  • Where is this service actually running?
  • Which infrastructure does it depend on?
  • What breaks if one availability zone fails?
  • How many replicas are live right now?
  • How does traffic enter the system and move between services?

The deployment diagram answers those questions.


Deployment view vs container diagram

The deployment diagram does not replace the Container diagram. It complements it.

Container diagramDeployment diagram
AnswersWhat are the system's building blocks?Where do those building blocks run?
ShowsContainers and their logical relationshipsDeployment nodes, replicas, traffic routing
AudienceAll developers and architectsDevOps, SRE, platform engineers, on-call
Detail levelTechnology and responsibilityInfrastructure, scaling, replication

Every container in the Container diagram should appear in at least one deployment diagram — typically the production one. Conversely, every deployable unit in the deployment diagram should correspond to a container in the Container diagram. That one-to-one connection is what makes the C4 model useful as a hierarchy.

Multiple deployment diagrams for multiple environments

A system usually has more than one environment: production, staging, development, load testing, and disaster recovery. Each environment can have a different topology — production might be multi-region, staging single-region, development running locally in Docker Compose.

Each distinct topology deserves its own deployment diagram. This is not duplication. The diagrams describe different reliability and failure characteristics. Production is the most important and should always be accurate enough for incident response, reliability reviews, security review, and onboarding.


Elements of a deployment diagram

Deployment nodes

A deployment node is a computational infrastructure element on which containers or other deployment nodes can be deployed. Deployment nodes include:

  • Physical servers and virtual machines (EC2, GCE, Azure VM)
  • Container orchestration clusters (Kubernetes, ECS, Nomad)
  • Individual cluster nodes (Kubernetes worker nodes, ECS container instances)
  • Managed cloud services (RDS, Cloud SQL, ElastiCache, Memorystore)
  • Cloud regions and availability zones (us-east-1, eu-west-1, us-east-1a)
  • CDN edge networks (CloudFront, Cloudflare, Akamai)

Deployment nodes are nested. A Kubernetes cluster contains worker nodes, which contain pods, which contain containers. A cloud region contains availability zones, which contain clusters. This nesting reflects the real-world infrastructure hierarchy and is where the availability and failure domain information lives.

Infrastructure nodes

An infrastructure node is a supporting element that is not a container but is relevant to the deployment architecture. Infrastructure nodes do not host containers — they provide supporting services.

Examples include load balancers (ALB, GCLB, Azure Application Gateway), DNS (Route 53, Cloud DNS), firewalls and security groups, API gateways as managed services, VPNs and private connectivity (Direct Connect, ExpressRoute), and certificate managers (ACM, Let's Encrypt).

Container instances

Containers from the Container diagram appear inside deployment nodes to show where they are running. In the deployment diagram, a container is shown as a concrete instance on specific infrastructure — not a logical concept.

Container instances should be annotated with replica count or autoscaling configuration, resource configuration (memory, CPU, instance type), and health check configuration where relevant.

Relationships

Relationships in the deployment diagram describe physical connectivity — network connections, traffic routing, data replication. They should be labelled with network protocol, port numbers where operationally relevant, traffic routing rules (canary weights, round-robin), and replication configuration (synchronous vs asynchronous, lag).


How to build a deployment diagram

Step 1: choose the environment

Start with production. Label the diagram clearly — a reader picking it up must immediately know which environment they are looking at.

Step 2: identify the infrastructure topology

Document: which cloud provider and regions, which availability zones, which orchestration platform, which managed services, which load balancers, which VPCs and subnets.

Step 3: map containers to infrastructure

For each container in the Container diagram: where it runs, how many replicas, how it scales, what resource configuration, what health checks.

Step 4: document the traffic flow

Trace how traffic enters the system: where DNS resolves, which CDN or load balancer receives requests, how requests route to container instances, how requests route between containers.

Step 5: document data replication

For every data store: primary-replica setup, synchronous vs asynchronous replication, replicas across AZs or regions, RPO implied by replication lag.

Step 6: annotate failure domains

Ask: If this availability zone goes down, what breaks? Group components by availability zone, show which services span multiple AZs, show which data stores fail over automatically, mark single points of failure clearly.


Example 1: e-commerce platform AWS production deployment {#example-1-e-commerce-platform-aws}

Infrastructure overview

The e-commerce platform runs on AWS in us-east-1, distributed across three availability zones. It uses EKS for container orchestration, RDS for managed PostgreSQL, ElastiCache for Redis, MSK for Kafka, and CloudFront for CDN.

Deployment node hierarchy

AWS Region: us-east-1
├── CloudFront Distribution (CDN)
│   └── Web Application (React SPA) — static assets cached at edge
│
├── Availability Zone: us-east-1a
│   ├── Public Subnet
│   │   └── Application Load Balancer (ALB) — HTTPS port 443
│   └── Private Subnet
│       ├── EKS Worker Node (m5.2xlarge)
│       │   ├── API Gateway Pod (Kong) — 2 replicas
│       │   ├── Order Service Pod — 2 replicas
│       │   └── Payment Service Pod — 2 replicas
│       └── RDS Primary Instance (db.r6g.2xlarge, PostgreSQL 16)
│           ├── Orders Database (primary)
│           ├── Customer Database (primary)
│           └── Payment Database (primary)
│
├── Availability Zone: us-east-1b
│   └── Private Subnet
│       ├── EKS Worker Node (m5.2xlarge)
│       │   ├── API Gateway Pod — 2 replicas
│       │   ├── Order Service Pod — 2 replicas
│       │   ├── Product Catalog Service Pod — 2 replicas
│       │   └── Customer Service Pod — 2 replicas
│       ├── RDS Read Replica (db.r6g.xlarge)
│       │   └── Asynchronous replication from primary in us-east-1a
│       └── ElastiCache Node (cache.r6g.large)
│           └── Session Cache (Redis 7)
│
├── Availability Zone: us-east-1c
│   └── Private Subnet
│       ├── EKS Worker Node (m5.2xlarge)
│       │   ├── Notification Service Pod — 2 replicas
│       │   ├── Product Catalog Service Pod — 2 replicas
│       │   └── Customer Service Pod — 2 replicas
│       └── ElastiCache Node (cache.r6g.large)
│           └── Session Cache (Redis 7) replica of us-east-1b node
│
├── MSK Cluster (Multi-AZ, 3 brokers — one per AZ)
│   └── Message Broker (Apache Kafka)
│
└── Elasticsearch Service (3-node cluster, one node per AZ)
    └── Search Index

Traffic flow

User's browser
    │ HTTPS (port 443)
    ▼
CloudFront Distribution
    │ Serves static assets from edge cache
    │ Forwards dynamic API requests to ALB
    ▼ HTTPS (port 443)
Application Load Balancer
    │ SSL termination
    │ Routes /api/* to API Gateway target group
    │ Health check: GET /health, 30s interval
    ▼ HTTP (port 8000), round-robin across 6 API Gateway pods
API Gateway (Kong)
    │ JWT validation, rate limiting
    │ Routes to backend services by path prefix
    ▼ HTTP (internal)
Order Service / Customer Service / Product Catalog Service
    ▼ SQL (port 5432)
RDS Primary Instance

Failure domain analysis

Single AZ failure (e.g., us-east-1a goes down): ALB routes traffic to pods in remaining AZs. EKS reschedules evicted pods. RDS fails over to standby in us-east-1b or us-east-1c (~60 seconds automatic Multi-AZ failover). MSK continues with 2 of 3 brokers. ElastiCache fails over to replica (~30 seconds). User impact: increased latency during failover (30–90 seconds), no data loss for committed transactions.

What this deployment view reveals: Multi-AZ redundancy is explicit. The public/private subnet boundary is visible. The CloudFront CDN layer shows that static assets are served from edge, not origin. The read replica signals analytics query offloading from the primary.


Example 2: banking app multi-region production deployment {#example-2-banking-app-multi-region}

Infrastructure overview

The banking mobile application is deployed across two AWS regions for high availability and DR: us-east-1 (primary) and us-west-2 (secondary). This multi-region architecture is driven by regulatory requirements and an RTO of less than 15 minutes.

Primary region: us-east-1

AWS Region: us-east-1 (Primary)
├── Route 53 (DNS with health-check-based failover)
│   ├── mobile-api.bank.com → ALB in us-east-1 (primary)
│   └── mobile-api.bank.com → ALB in us-west-2 (failover on health check failure)
│
├── AWS WAF + Shield Advanced
│   └── DDoS protection, SQL injection prevention, rate limiting
│
├── Availability Zone: us-east-1a
│   ├── ALB
│   └── Private Subnet
│       ├── EKS Worker Node (r5.2xlarge)
│       │   ├── Mobile API (BFF) Pod — 3 replicas
│       │   ├── Authentication Service Pod — 2 replicas
│       │   └── Transaction Service Pod — 3 replicas
│       └── RDS Primary (db.r6g.4xlarge, PostgreSQL 16, encrypted at rest)
│           └── Transaction Database — Multi-AZ, synchronous standby in us-east-1b
│
├── Availability Zone: us-east-1b
│   └── Private Subnet
│       ├── EKS Worker Node
│       │   ├── Mobile API (BFF) Pod — 3 replicas
│       │   ├── Account Service Pod — 2 replicas
│       │   └── Card Service Pod — 2 replicas
│       ├── RDS Standby (synchronous replication from us-east-1a primary)
│       └── ElastiCache Primary Node (r6g.xlarge, Redis 7, TLS + auth enabled)
│
├── Availability Zone: us-east-1c
│   └── Private Subnet
│       ├── EKS Worker Node
│       │   ├── Notification Service Pod — 2 replicas
│       │   └── Account Service Pod — 2 replicas
│       └── ElastiCache Replica Node
│
├── Amazon MSK (Multi-AZ, 3 brokers)
│
└── AWS PrivateLink Endpoints
    ├── → Core Banking System (on-premises via AWS Direct Connect)
    └── → Fraud Detection System (separate AWS account, VPC peering)

Secondary region: us-west-2 (warm standby DR)

AWS Region: us-west-2 (DR warm standby)
├── ALB (inactive — only receives traffic during failover)
├── EKS Cluster (scaled to 0 pods — scaled up during failover in <10 minutes)
│   └── All pods: Mobile API, Authentication, Transaction, Account, Card, Notification
├── RDS Read Replica (asynchronous replication from us-east-1 — ~5 second lag)
│   └── Promoted to primary during failover
└── ElastiCache (empty Session Store — rebuilt from RDS on startup)

What this deployment view reveals: The DR topology is explicitly warm standby — infrastructure exists but pods are scaled to zero. The ~5 second RDS replication lag is an explicit RPO signal: in a worst-case failover, up to 5 seconds of transaction data could be lost. Direct Connect for Core Banking means PHI traffic never traverses the public internet. The three-layer security group configuration (ALB → EKS → RDS) shows defense-in-depth.


Example 3: SaaS platform Kubernetes production deployment (GKE) {#example-3-saas-platform-kubernetes}

Infrastructure overview

The SaaS platform runs on GCP using GKE in us-central1, with Google Cloud Load Balancing and Cloud CDN for global traffic routing, Cloud SQL for PostgreSQL, and Cloud Memorystore for Redis.

Kubernetes cluster architecture

GCP Project: prod-saas-platform
├── Google Cloud Load Balancing (global anycast IP)
│   ├── Cloud CDN — serves React SPA static assets from edge
│   └── HTTPS Load Balancer → GKE Ingress Controller
│
├── GCP Region: us-central1
│   ├── GKE Cluster: prod-cluster (regional, 3 AZs)
│   │   ├── Node Pool: api-pool (n2-standard-8, autoscaling 3–12 nodes)
│   │   │   └── Namespace: production
│   │   │       ├── API Server (6 pods, 2 per AZ)
│   │   │       │   ├── Liveness probe: GET /healthz, 10s interval
│   │   │       │   ├── Readiness probe: GET /ready, 5s interval
│   │   │       │   ├── Resources: 2 CPU / 4 GB RAM per pod
│   │   │       │   └── HPA: min 6, max 30, target CPU 60%
│   │   │       ├── Authentication Service (3 pods, HPA min 3, max 15)
│   │   │       ├── Billing Service (2 pods)
│   │   │       ├── Search Service (3 pods)
│   │   │       └── File Service (2 pods)
│   │   │
│   │   ├── Node Pool: worker-pool (n2-standard-4, autoscaling 2–8 nodes)
│   │   │   └── Namespace: production
│   │   │       ├── Notification Service (3 pods)
│   │   │       └── Integration Service (3 pods)
│   │   │
│   │   └── Node Pool: system-pool (n2-standard-2, 3 nodes, fixed)
│   │       └── Ingress controller, Cert Manager, Prometheus, Grafana, Jaeger
│   │
│   ├── Cloud SQL (db-custom-16-65536, PostgreSQL 16)
│   │   ├── Primary: prod-primary (us-central1-a)
│   │   └── Read Replica: prod-replica-1 (us-central1-b) — reporting queries
│   │
│   ├── Cloud Memorystore (Redis 7, Standard Tier)
│   │   ├── Primary: prod-redis-primary (us-central1-a, 16 GB)
│   │   │   ├── Job Queue (Bull)
│   │   │   └── Real-Time Cache
│   │   └── Replica: prod-redis-replica (us-central1-b, auto-failover ~30s)
│   │
│   └── Google Cloud Pub/Sub
│       └── Analytics Event Stream → BigQuery export
│
└── Global Resources
    ├── Cloud Storage: prod-attachments (multi-region US, versioning enabled)
    ├── Elasticsearch Service (Elastic Cloud, 3-node cluster)
    └── Secret Manager (database credentials, API keys)

Namespace and resource isolation

Kubernetes Namespaces:
├── production     Live customer workloads
├── staging        Pre-production validation
├── monitoring     Prometheus, Grafana, Jaeger, AlertManager
├── ingress        Nginx ingress controller
└── cert-manager   Certificate lifecycle management

Resource Quotas (production namespace):
├── CPU limit:     80 cores
├── Memory limit:  160 GB
└── Pod limit:     200

Network Policies (production namespace):
├── Default: deny all ingress and egress
├── Allow: ingress from ingress namespace (HTTP)
├── Allow: egress to Cloud SQL (port 5432)
├── Allow: egress to Cloud Memorystore (port 6379)
└── Allow: egress to Google APIs (HTTPS port 443)

What this deployment view reveals: Three node pools with distinct purposes prevent a traffic spike on api-pool from starving system components or workers. HPA configuration communicates specific availability commitments: minimum 6 pods always available, scales to 30 at peak. The Cloud SQL Auth Proxy sidecar explains why database connections go to localhost rather than a hostname. Network policies show a zero-trust default-deny posture.


Example 4: ride-sharing active-active multi-region deployment {#example-4-ride-sharing-active-active}

Infrastructure overview

The ride-sharing platform uses an active-active multi-region deployment across three AWS regions. A complete regional failure does not interrupt service for riders and drivers in unaffected geographies.

Multi-region architecture

Global Traffic Management
├── AWS Route 53 (GeoDNS + latency-based routing)
│   ├── api.rideshare.com → us-east-1 (US East traffic)
│   ├── api.rideshare.com → eu-west-1 (European traffic)
│   └── api.rideshare.com → ap-southeast-1 (APAC traffic)
└── AWS Global Accelerator (anycast IP, TCP/UDP acceleration)

Region: us-east-1 (US Primary — active)
├── Availability Zone: us-east-1a
│   ├── EKS Worker Nodes (c5.4xlarge)
│   │   ├── Passenger API Pod — 5 replicas
│   │   ├── Driver API Pod — 5 replicas
│   │   ├── Matching Service Pod — 3 replicas (Go, high CPU)
│   │   └── Trip Service Pod — 3 replicas
│   └── ElastiCache Node (Location Store primary, r6g.2xlarge)
│
├── Availability Zone: us-east-1b
│   ├── EKS Worker Nodes
│   │   ├── Passenger API Pod — 5 replicas
│   │   ├── Driver API Pod — 5 replicas
│   │   ├── Routing Service Pod — 3 replicas (Google Maps integration)
│   │   └── Payment Service Pod — 3 replicas
│   └── ElastiCache Node (Location Store replica — async from us-east-1a)
│
├── Availability Zone: us-east-1c
│   └── EKS Worker Nodes
│       ├── Matching Service Pod — 3 replicas
│       ├── Pricing Service Pod — 3 replicas
│       └── Communication Service Pod — 2 replicas
│
├── MSK Cluster (3 brokers, replication factor 3)
│   └── Topics: TripEvents, PaymentEvents, DriverLocationUpdates
│
└── Aurora PostgreSQL (Multi-AZ)
    ├── Writer: us-east-1a (db.r6g.4xlarge)
    ├── Reader 1: us-east-1b
    └── Reader 2: us-east-1c

Region: eu-west-1 (European Region — active, serves EU traffic)
├── [Same structure as us-east-1, scaled to EU traffic]
├── Aurora Global Database secondary cluster
│   └── Asynchronous replication — < 1 second lag
└── Data residency: EU PII stored only in eu-west-1 (GDPR)
    └── EU data does not replicate to non-EU regions

Location service architecture

Location Service Deployment (special case — extreme performance requirements)
├── Redis Cluster (ElastiCache, cluster mode)
│   ├── 6 shards × 2 replicas = 18 nodes per region
│   ├── Geospatial index: GEOADD / GEORADIUS
│   ├── Key TTL: 30 seconds (stale drivers auto-expire)
│   └── Peak throughput: ~50,000 writes/second
│
├── Location Service Pods (Go, 10 replicas per AZ)
│   ├── Write target: <5 ms per location update
│   └── Proximity query target: <10 ms
│
└── Firebase Realtime Database
    └── Driver apps write here — Location Service subscribes for events

What this deployment view reveals: Active-active is explicitly distinguished from the banking example's active-passive DR. GDPR data residency is documented as an infrastructure constraint — Aurora Global Database replication is configured to exclude PII fields for EU data. Aurora Global Database's < 1 second replication lag is a named operational commitment. The Location Service's Redis Cluster detail justifies the infrastructure investment with explicit throughput targets.


Example 5: healthcare HIPAA-compliant AWS deployment {#example-5-healthcare-hipaa}

Infrastructure overview

The healthcare portal operates in a HIPAA-compliant AWS environment. HIPAA imposes specific infrastructure requirements: encryption in transit and at rest everywhere, comprehensive audit logging, network isolation, backup and recovery procedures, and Business Associate Agreements with all cloud providers.

HIPAA-compliant architecture

AWS Region: us-east-1 (HIPAA-compliant, BAA signed with AWS)
│
├── Dedicated AWS Account for PHI workloads (account-level isolation)
│
├── VPC: 10.0.0.0/16 (HIPAA VPC — no shared resources)
│   ├── Public Subnets (10.0.1–3.0/24, one per AZ)
│   │   ├── AWS WAF (HIPAA-required: prevents injection attacks on PHI)
│   │   └── ALB (HTTPS only, TLS 1.2 minimum)
│   │
│   ├── Application Subnets (10.0.11–13.0/24)
│   │   └── EKS Worker Nodes (m5.2xlarge, HIPAA-hardened AMI)
│   │       ├── Patient Web Portal Pod — 6 total (2 per AZ)
│   │       ├── Patient API Pod — 9 total (3 per AZ)
│   │       ├── Clinical API Pod — 6 total
│   │       ├── Epic Integration Service Pod — 6 total
│   │       ├── Appointment Service Pod — 6 total
│   │       ├── Prescription Service Pod — 6 total
│   │       ├── Secure Messaging Service Pod — 6 total
│   │       ├── FHIR API Service Pod — 6 total
│   │       └── Notification Service Pod — 6 total
│   │
│   ├── Data Subnets (10.0.21–23.0/24) — no internet gateway
│   │   ├── RDS Aurora PostgreSQL (encrypted at rest, AES-256)
│   │   │   ├── Writer: us-east-1a (db.r6g.2xlarge)
│   │   │   │   ├── Patient Database (PHI — contains PII)
│   │   │   │   └── Message Store (PHI — field-level encrypted content)
│   │   │   ├── Reader: us-east-1b (reporting queries)
│   │   │   └── Automated backups: 35-day retention, encrypted, PITR enabled
│   │   │
│   │   └── ElastiCache Redis (TLS + AUTH, encrypted in transit + at rest)
│   │       ├── Primary: us-east-1a
│   │       └── Replica: us-east-1b
│   │           └── Patient Data Cache (TTL: 15 minutes)
│   │
│   ├── AWS PrivateLink Endpoints (traffic never leaves AWS network)
│   │   ├── → S3
│   │   ├── → SQS
│   │   ├── → Secrets Manager
│   │   └── → CloudWatch Logs
│   │
│   └── Transit Gateway → Hospital On-Premises Network (AWS Direct Connect)
│       └── Epic EHR System (HL7 FHIR over private connection)
│
├── AWS S3 (PHI Bucket)
│   ├── Bucket policy: deny HTTP (HTTPS only)
│   ├── Versioning: enabled (HIPAA requires version history)
│   ├── MFA delete: enabled
│   ├── Server-side encryption: AES-256
│   └── Access logging: all access logged to audit bucket
│
├── AWS CloudWatch Logs (Audit Log)
│   ├── /hipaa/phi-access — immutable resource policy, prevents deletion
│   ├── /hipaa/api-access — all API access to PHI endpoints
│   └── Retention: 7 years (HIPAA minimum), daily export to S3
│
├── AWS SQS + SNS (PHI-safe event stream)
│   ├── All queues: server-side encryption with KMS key
│   └── Message payloads: event metadata only — no PHI in message bodies
│       └── Consumers retrieve PHI via API using IDs in event payloads
│
└── AWS KMS (Customer-Managed Key: hipaa-phi-key, annual rotation)
    ├── Encrypts: RDS, ElastiCache, S3, SQS, CloudWatch Logs, EBS volumes
    └── Key usage logged: all encrypt/decrypt operations audited

What this deployment view reveals: HIPAA compliance controls are implemented as infrastructure — the deployment diagram is the compliance evidence document. The KMS key appears as a central element encrypting every data store. PHI-free message payloads are an explicit design decision that reduces PHI surface area. Direct Connect for Epic means HL7 FHIR messages containing PHI never traverse the public internet. Immutable audit logs with 7-year retention are annotated explicitly, not described generically.


Common mistakes

The flat deployment diagram. Showing all containers as flat boxes without nesting them inside deployment nodes fails to communicate physical topology. The nesting is where the availability and failure domain information lives.

Omitting replica counts. A deployment diagram that shows a container without indicating replica count omits one of the most important pieces of operational information. A single instance is a single point of failure; ten replicas is highly available. The diagram cannot answer the question without replica annotations.

Ignoring the data layer. Deployment diagrams that show where application services run but not where databases and caches run omit the most failure-sensitive components. Database placement — which AZ, with what replication, with what backup policy — is often the most critical reliability information in the diagram.

Conflating Container and Deployment diagrams. The Container diagram shows what runs. The Deployment diagram shows where it runs. Mixing the two levels — showing Kubernetes nodes in the Container diagram, or internal service code structure in the Deployment diagram — destroys the hierarchy's usefulness.

Single-environment diagrams presented as production. Every deployment diagram must be explicitly labelled with the environment it describes. Readers making decisions based on a staging diagram assuming it reflects production will make incorrect decisions.

Omitting security and network topology. Deployment diagrams that omit load balancers, security groups, network boundaries, and VPC topology miss most of the security architecture. For regulated systems, these elements are required for the diagram to serve as compliance evidence.


Deployment diagrams as compliance evidence

For regulated systems, the deployment diagram has two jobs: it helps operators understand the runtime environment, and it helps auditors see how controls are implemented. This is common in healthcare (HIPAA), financial services (PCI-DSS), and government environments.

Auditors typically ask for diagrams showing network segmentation and data isolation, encryption in transit and at rest, access controls and authentication, audit logging configuration, and backup and recovery procedures. A well-maintained deployment diagram can answer those questions directly.

For compliance-focused diagrams, be explicit. Use "Encrypted in transit (TLS 1.2+)" and "Encrypted at rest (AES-256)" rather than just "encrypted". Use "7-year retention, immutable" for audit logs rather than "audit logging enabled". Use "No PHI in message payloads" for message queues rather than "uses SQS". This specificity is what makes the diagram useful to an auditor.


Tooling

Structurizr DSL

Structurizr supports deployment diagrams natively. The deployment node hierarchy, container instance placement, and infrastructure nodes can all be expressed as code and kept in version control alongside the system they describe.

deploymentEnvironment "Production" {
    deploymentNode "AWS us-east-1" {
        deploymentNode "us-east-1a" {
            deploymentNode "EKS Worker Node" {
                containerInstance apiGateway {
                    properties { "replicas" "2" }
                }
                containerInstance orderService {
                    properties { "replicas" "2" }
                }
            }
            deploymentNode "RDS Primary" {
                containerInstance ordersDb
            }
        }
    }
}

AWS and GCP diagramming tools

AWS provides official icons for draw.io and Lucidchart. Combining AWS infrastructure icons with C4-style container and relationship notation gives you a diagram that is both cloud-specific and readable as a C4 deployment view.

Terraform and IaC as ground truth

For teams using infrastructure-as-code (Terraform, Pulumi, CloudFormation), the IaC is the authoritative source of truth. Tools like Inframap and Pluralith can generate topology diagrams from Terraform state, giving an automatic view of deployed infrastructure.

These generated diagrams are useful but not a full replacement for a maintained C4 deployment diagram — they typically miss narrative clarity, audience-focused labelling, explicit failure-domain reasoning, and operational annotations. The best pattern: IaC as source of truth, C4 deployment diagram as the human-friendly explanation.

uxxu.io

uxxu.io supports C4 deployment diagrams natively, maintaining the link between Container and Deployment views so changes to a container propagate consistently across levels.


Frequently asked questions

What is a C4 deployment diagram?

A C4 deployment diagram is the fourth level of the C4 model. It shows how the containers from the Container diagram map onto the physical or virtual infrastructure on which they run — which region, availability zone, cluster, and managed service each container is deployed to, along with replica counts, traffic routing, and replication configuration.

What is a deployment view in software architecture?

A deployment view is an architectural view that describes the physical or virtual infrastructure on which a software system runs. In the C4 model, the deployment view is the Deployment diagram — it shows where each container runs, how many replicas exist, how traffic is routed, and how data is replicated. Other architectural frameworks use similar terms: the C4 deployment view corresponds roughly to the physical view in the 4+1 architectural view model.

What is the difference between a Container diagram and a Deployment diagram?

The Container diagram shows the logical building blocks of a system — what containers exist, what each one does, and how they communicate. The Deployment diagram shows where those containers run in production — which infrastructure, how many replicas, how traffic routes between them, and how data replicates. A Container diagram exists independently of any specific infrastructure; a Deployment diagram is specific to an environment (production, staging, etc.).

What should a deployment diagram include?

A complete deployment diagram should include: deployment nodes (regions, AZs, clusters, managed services) with nesting that reflects the physical hierarchy; container instances inside deployment nodes with replica counts; infrastructure nodes (load balancers, DNS, security groups); relationships with protocol and port labels; replication configuration for all data stores; and explicit failure domain grouping by availability zone.

Do I need a separate deployment diagram for each environment?

Yes, if the environments have different topologies. Production and staging typically have different topologies — production is often multi-AZ or multi-region, staging is often single-AZ. Each distinct topology deserves its own deployment diagram, clearly labelled. If staging is topologically identical to production (rare), one diagram with environment labels can suffice.

What is a sample C4 deployment diagram?

A sample C4 deployment diagram for a web application might show: a cloud region (e.g., AWS us-east-1) containing two availability zones; each AZ containing an EKS worker node with 2 application service pods; a load balancer in a public subnet routing HTTPS traffic to the pods; an RDS primary database in AZ-a with a synchronous standby in AZ-b; and an ElastiCache Redis instance with a replica across AZs. The five examples in this guide (e-commerce, banking, SaaS, ride-sharing, healthcare) provide complete real-world sample deployment diagrams.

How often should deployment diagrams be updated?

Deployment diagrams should be updated whenever the infrastructure topology changes: new services added, scaling configurations changed, database instances resized, network topology modified, new availability zones added, or DR configuration changed. In teams using infrastructure-as-code, the deployment diagram update should be part of the same pull request as the IaC change. A stale deployment diagram is often worse than none — it creates false confidence in on-call engineers and auditors.


Conclusion

The deployment diagram is the most operational C4 view. It turns the Container diagram into a view of the real runtime environment and answers the questions that matter in production: where things run, how many instances exist, what redundancy is in place, which failure domains matter, what network controls are active, and which compliance controls are implemented.

The five examples in this guide illustrate how deployment diagrams serve different purposes in different contexts — multi-AZ redundancy, DR topology, Kubernetes resource segregation, active-active multi-region, and HIPAA compliance as infrastructure.

The key principles remain the same across all of them: show the nesting hierarchy, annotate replica counts, document replication configuration, show traffic routing, make failure domains explicit, include security topology, label the environment prominently, and keep it current.

If a system matters in production, its deployment view deserves to exist and stay accurate.

Start diagramming your deployment view in uxxu.io →


Related Articles