Architecture pattern library

AWS field guide

Keep the synchronous path intentionally small

Keep synchronous APIs focused on authorization, validation, and fast domain work. Move uncertain or long tasks behind a queue.

Use this pattern when

Requests are bursty, stateless, and benefit from independent scaling with minimal idle cost.

Reference architecture

Responsibilities and controls, not a deployment template.

Synchronous Asynchronous

Client

Authenticated request

Amazon API Gateway

Authorize and validate

AWS Lambda

Short domain operation

Amazon DynamoDB

Conditional state write

Amazon SQS

Long work continues here

AWS service marks use the official Q3 2026 AWS Architecture Icons. Abstract nodes represent application responsibilities rather than AWS services.

Decisions that shape the pattern

  • Define a strict latency budget.
  • Reuse connections outside the handler.
  • Return an operation ID for asynchronous work.

Security boundaries

  • Authorize at the edge and inside the workload.
  • Validate request size and shape.
  • Use separate roles for synchronous and background paths.

Reliability posture

  • Cap downstream concurrency.
  • Use conditional writes for state transitions.
  • Design client-safe retries.

Starter implementation

Start from deployable infrastructure

Review every permission, limit, Region, and cost assumption before production.

Download ADR template
serverless-api.stack.ts
import { Duration, Stack, StackProps } from 'aws-cdk-lib';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as athena from 'aws-cdk-lib/aws-athena';
import * as bedrock from 'aws-cdk-lib/aws-bedrock';
import * as budgets from 'aws-cdk-lib/aws-budgets';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
import * as cloudtrail from 'aws-cdk-lib/aws-cloudtrail';
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as patterns from 'aws-cdk-lib/aws-ecs-patterns';
import * as events from 'aws-cdk-lib/aws-events';
import * as targets from 'aws-cdk-lib/aws-events-targets';
import * as glue from 'aws-cdk-lib/aws-glue';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as kms from 'aws-cdk-lib/aws-kms';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as sources from 'aws-cdk-lib/aws-lambda-event-sources';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
import * as sqs from 'aws-cdk-lib/aws-sqs';
import { Construct } from 'constructs';

export class PatternStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const table = new dynamodb.Table(this, 'State', {
      partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
      billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
    });
    const jobs = new sqs.Queue(this, 'Jobs');
    const handler = new lambda.Function(this, 'ApiHandler', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset('api'),
      environment: { TABLE_NAME: table.tableName, QUEUE_URL: jobs.queueUrl },
    });
    table.grantReadWriteData(handler);
    jobs.grantSendMessages(handler);
    new apigateway.LambdaRestApi(this, 'Api', { handler });
  }
}

Before production

Adoption checklist

  1. 01Set request and integration timeouts.
  2. 02Add structured error responses.
  3. 03Protect downstream connection pools.
  4. 04Test burst traffic.
  5. 05Trace one request across async work.

From the journal

Selected from service names and architecture signals used by this pattern.

Was this playbook useful?

One click helps prioritize deeper examples and updates.