Agent → Email Service Architecture
High-throughput, async, durable email pipeline. Agent (ECS) enqueues; Email (Lambda) sends via SES; DynamoDB is source of truth; SQS/SNS decouple producers from consumers.
Components
| Component | Role |
|---|---|
| Agent (ECS Fargate, NestJS) | API surface. Accepts single/batch send requests, writes job rows to DynamoDB, publishes to SQS. |
| Email Lambda (plain Node/TS) | SQS-triggered worker. Renders + sends via SES, updates DynamoDB. No DI framework — handler is a plain function for fast cold starts. |
| Event Lambda (plain Node/TS) | SNS-triggered. Updates job status, maintains suppression. |
SQS Standard (email-jobs) |
Main work queue. High throughput, at-least-once. |
SQS DLQ (email-jobs-dlq) |
Catches messages exceeding maxReceiveCount. |
SQS DLQ (event-lambda-dlq) |
Catches SNS deliveries Event Lambda failed to process after retries. |
SNS (ses-events) |
Fan-out for SES bounce/complaint/delivery notifications. |
DynamoDB EmailJobs |
Job state, idempotency, audit trail. |
DynamoDB Suppression |
Bounce/complaint suppression list (checked before send). |
| SES | Actual mail transport. |
High-Level Flow
flowchart LR
Client[Client / Upstream] -->|POST /emails| Agent[Agent ECS Fargate]
Agent -->|PutItem job=PENDING| DDB[(DynamoDB EmailJobs)]
Agent -->|SendMessage| SQS[[SQS email-jobs]]
SQS -->|trigger batch| Lambda[Email Lambda]
Lambda -->|GetItem| DDB
Lambda -->|check| Supp[(DynamoDB Suppression)]
Lambda -->|SendEmail / SendBulkEmail| SES[SES]
Lambda -->|UpdateItem SENT/FAILED| DDB
SES -->|bounce/complaint/delivery| SNS[[SNS ses-events]]
SNS --> EvtLambda[Event Lambda]
EvtLambda -->|UpdateItem| DDB
EvtLambda -->|PutItem| Supp
SQS -. failures .-> DLQ[[SQS DLQ]]
SNS -. failures .-> EDLQ[[Event DLQ]]
DLQ --> Alarm{{CloudWatch Alarm}}
EDLQ --> Alarm