Mình từng deploy một Lambda qua SQS, tưởng đơn giản, ai ngờ message bị mất giữa đường vì batch size sai. SQS không phải cứ throw message vào là xong – nó cần pattern đúng để không mất data, không backpressure, không timeout.

Pattern 1: SQS – Lambda Batch

handler.addEventSource(
  new SqsEventSource(queue, {
    batchSize: 100,
    maxBatchingWindow: cdk.Duration.seconds(30),
    reportBatchItemFailures: true,
    maxConcurrency: 10,
  })
);

Mình dùng SQS Lambda batch cho order processing, lưu ý maxBatchingWindow không nên quá 30s nếu muốn latency thấp.

Pattern 2: EventBridge – Step Functions

new events.Rule(this, "OrderCreated", {
  eventPattern: { source: ["com.myapp.order"], detailType: ["OrderCreated"] },
  targets: [new targets.SfnStateMachine(orderWorkflow)],
});

Pattern 3: WebSocket API (real-time)

const wsApi = new apigatewayv2.WebSocketApi(this, "Realtime");
wsApi.addRoute("$connect", {
  integration: new WebSocketLambdaIntegration("Connect", connectHandler),
});
wsApi.addRoute("sendmessage", {
  integration: new WebSocketLambdaIntegration("Send", messageHandler),
});

Pattern 4: SNS Fan-out – Multiple SQS

const topic = new sns.Topic(this, "OrderTopic");
topic.addSubscription(
  new subs.SqsSubscription(emailQueue, {
    filterPolicy: {
      priority: sns.SubscriptionFilter.stringFilter({ allowlist: ["high"] }),
    },
  })
);
topic.addSubscription(new subs.SqsSubscription(inventoryQueue));

Bốn pattern này cover hầu hết use case event-driven trên AWS. Pattern nào cũng có trade-off – quan trọng là biết khi nào pattern A gãy thì chuyển sang pattern B.

PatternUse Case
SQS → Lambda batchAsync processing, retry, backpressure
EventBridge → Step FunctionsComplex multi-step workflow
WebSocket APIReal-time: chat, live dashboard, game
SNS → multiple SQSOne event → many independent consumers

Bài sau: Bonus 1: Amazon Bedrock & GenAI cho developer