AWS Diagram Guide

AWS serverless architecture diagrams: draw the invocation, not just the wire

By the engineer who builds Datadef, from client work on data platforms · Reviewed August 21, 2026

Serverless architectures are mostly arrows. Every box is a managed service, so what distinguishes a good serverless diagram from a useless one is whether the arrows say anything. A synchronous API call, an asynchronous event, and a poll-based event source mapping look identical when drawn as plain lines, and they behave nothing alike when something fails.

7 min readFor teams documenting a Lambda, API Gateway, and EventBridge workload

See it as a diagram

Everything below, as a diagram you can edit. Describe yours and see it in seconds.

213/20003 credits left
Try:

No account needed · Editable canvas, not a picture

Drop the network chrome you do not have

API Gateway, Lambda, EventBridge, SQS, SNS, DynamoDB, and S3 are regional and fully managed. None of them sits in your subnets unless you put it there. Drawing an empty VPC container around a serverless workload adds a boundary that does not constrain anything and suggests network controls that are not in play.

The exception is worth drawing precisely because it is the exception. A Lambda attached to a VPC to reach an RDS instance, an ElastiCache cluster, or an interface endpoint really does have elastic network interfaces in your subnets, and that changes cold start behaviour, egress path, and security group rules. Draw the VPC only around the functions that are actually in it.

Label the invocation type on every arrow

There are three ways a Lambda gets called, and each carries a different retry and failure story. Synchronous invocation from API Gateway, an ALB, or a direct call means the caller waits and errors surface to the caller. Asynchronous invocation from S3 events, EventBridge rules, or SNS means AWS holds the event on an internal queue and retries it, and when the attempts run out the invocation record goes to the on-failure destination or the dead letter queue carrying condition RetriesExhausted and approximateInvokeCount, which is how you tell a poison event from a timeout. The retry count is per function, set with aws lambda update-function-event-invoke-config. Event source mappings for SQS, Kinesis, DynamoDB Streams, and MSK mean Lambda polls, batches, and blocks the shard or the batch when a record keeps failing.

Put that word on the arrow: sync, async, or poll, with the batch size where it matters. An on-call engineer reading the diagram at three in the morning needs to know whether a failed message is lost, retried, parked in a dead letter queue, or blocking a shard, and the arrow label is where that question gets answered.

Resources:
  CheckoutApi:
    Type: AWS::Serverless::Function
    Properties:
      Events:
        Http:                      # synchronous, caller waits
          Type: Api
          Properties: { Path: /checkout, Method: post }

  OrderWorker:
    Type: AWS::Serverless::Function
    Properties:
      Events:
        Queue:                     # event source mapping, poll based
          Type: SQS
          Properties: { Queue: !GetAtt OrderQueue.Arn, BatchSize: 10 }
      EventInvokeConfig:           # async failures land here
        DestinationConfig:
          OnFailure: { Type: SQS, Destination: !GetAtt OrderDlq.Arn }

Draw the parts on-call needs

Dead letter queues and on-failure destinations belong on the canvas, not in an appendix. They are where messages go when the system is unhappy, and they are the first place anyone looks during an incident. The same goes for the EventBridge bus itself: draw it as a lane with the rules attached, because the routing rules are the coupling, and a diagram that shows producers and consumers without the bus hides where the matching happens.

Step Functions state machines read best as a single node with the workflow described in the accompanying document. Exploding fifteen states onto an architecture canvas buries the surrounding services, and the state machine definition is already a better diagram of itself.

One more thing serverless diagrams routinely omit: the datastore each function actually owns. Ownership is the architectural claim. Two functions writing the same DynamoDB table is a design decision worth seeing.

Two behaviours deserve an annotation rather than a node. Setting reserved concurrency to zero on an asynchronously invoked function stops retries entirely and sends new events straight to the dead letter queue, which is both the standard way to stop a runaway consumer and a reason a queue fills during an incident. And an SNS destination has a 256 KB message limit, so a function whose payload approaches 1 MB can fail to deliver its own failure record and report DestinationDeliveryFailures instead. Both are documented on the Lambda developer guide page on capturing records of asynchronous invocations, which also recommends SQS or S3 destinations for large payloads.

Grouping once there are forty functions

Per-function nodes stop working somewhere around fifteen. Past that, group by bounded context, one zone per domain, and draw the events that cross domain boundaries as the only inter-zone arrows. That produces a diagram that answers the question people usually have, which is which domain owns this behaviour, rather than a wall of identical Lambda icons. The edge discipline matters as much as the grouping: no more edges than nodes, and a fan of eight identical arrows from one bus to eight consumers replaced by one labelled flow into the zone.

Datadef draws exactly that shape from a description: zones per domain, real AWS icons, labelled edges. If the functions are defined in Terraform, the parse gives every aws_lambda_function its own node carrying runtime, memory_size, and timeout, because those are the three attributes the catalog picks for that type. Queues and topics are weighted lower, so four aws_sqs_queue resources in one module arrive as one node reading "SQS queues ×4: orders, orders dlq, exports, exports dlq" rather than four boxes competing with the functions. Export to PNG or JPEG for the deck, or embed the live image in the service README so the diagram follows the code.

FAQ

Do serverless diagrams need a VPC boundary?

Only for the functions that are actually VPC-attached. API Gateway, Lambda by default, EventBridge, SQS, and DynamoDB are regional managed services outside your subnets, so an empty VPC box around them implies network controls that do not exist.

How do I show the difference between sync and async invocation?

Label the arrow. Synchronous means the caller waits and sees errors. Asynchronous means AWS queues the event internally, retries, and then routes the failure record to a dead letter queue or an on-failure destination with condition RetriesExhausted. Event source mappings mean Lambda polls and batches, and a poison record can block a batch or a shard.

Should dead letter queues be in the diagram?

Yes. They are where messages land when processing fails, which makes them the first thing an on-call engineer looks for. A serverless diagram without its dead letter queues describes only the happy path.

How should Step Functions appear?

As one node on the architecture diagram, with the states documented separately. The state machine definition already renders as its own workflow diagram, and expanding it inline crowds out the services around it.

What is the right grouping for a large serverless system?

By bounded context, one zone per domain, with cross-domain events as the only arrows between zones. Individual function nodes stay readable up to roughly fifteen functions, after which the domain grouping is what keeps the picture usable.