Case Study

Serverless Contact Form on AWS (HTTP API + Lambda + DynamoDB TTL + SES)

Production-grade contact channel for petedorc.com using API Gateway (HTTP API) → Lambda (Node.js 20) with input validation and per-IP rate limiting in DynamoDB (TTL), sending mail via Amazon SES. Fronted by CloudFront and S3.

Context

Goal: Own the pipeline and keep ops near-zero. Requirements: fast UX, high deliverability, abuse protection, and no third‑party form service. Constraints: keep bundle small and preserve Web Vitals (LCP ≤ 2.0s, INP ≤ 200ms).

Architecture

  • CloudFront (edge) → API Gateway HTTP APILambda (Node.js 20)
  • DynamoDB table contact_rate_limits with TTL for per‑IP windowing
  • Amazon SES (domain verified, DKIM/SPF aligned) for delivery
  • S3 static site; CloudFront Function injects security headers
CloudFront → HTTP API → Lambda → DynamoDB TTL + SES; S3 hosts static site
Serverless Contact Form — architecture overview.
Request lifecycle: Browser → CloudFront → API Gateway → Lambda → DynamoDB/SES with 429 branch
Request lifecycle with rate-limit branch (429) and happy path.

Decisions & Trade-offs

  • HTTP API vs REST API: chose HTTP API for lower latency/cost; fewer built-ins like usage plans.
  • DynamoDB TTL vs Redis: serverless and durable; slightly higher p99 than in-memory.
  • Direct SES send vs SNS fan‑out: fewer moving parts now; SNS can be added later for archive/Slack.
  • Single region: simpler/cheaper today; multi‑region is future work if the form becomes critical-path.

Results

Latency P95 ~320 ms Delivery >99% Cost/mo <$0.10 Uptime 99.99%

Measured via curl + CloudWatch logs sampling; replace with screenshots as you gather more data.

Cost & Ops

  • API Gateway + Lambda: effectively free at current volume; DynamoDB on‑demand for a single read/write per submission.
  • SES out of sandbox; monitor bounces/complaints. Ensure DMARC policy is aligned.
  • CloudWatch alarms on 5XX rate and p95 latency; structured logs for request IDs and rate‑limit hits.

Improvements

  • Add Cloudflare Turnstile or reCAPTCHA at higher traffic.
  • EventBridge for async fan‑out (archive to S3, Slack/Email multi-destination).
  • Promote to CDK stack bundling API, Lambda, DDB, and CF Function.
  • Optional multi‑region API + Route 53 health checks.