Blog
Thoughts on engineering, design, and building great products.
Observability: Lambda Powertools and X-Ray Tracing
Start operating like production by being able to see inside. Wire in Lambda Powertools for structured JSON logs and pushed metrics, enable X-Ray to trace which services a request passes through. Read a real trace showing the resolver calling DynamoDB and EventBridge as subsegments, and a log line carrying a trace id to link logs to traces.
Step Functions: Orchestrating Multi-Step Workflows and the Saga Pattern
When a process has many steps, branches, and error handling, cramming it all into one Lambda gets messy and hard to read. Step Functions pulls the orchestration logic out into a declarative state machine. Build a link-moderation workflow (safety scan, then activate or reject), with Retry, Catch, and a direct DynamoDB call without Lambda. Covers Standard vs Express, and the saga pattern for undoing a mid-process failure.
WebSocket API: Pushing Click Counts to a Realtime Dashboard
Build the realtime part of the dashboard. Stand up an API Gateway WebSocket API with $connect and $disconnect routes, store each connection in DynamoDB tied to the link it watches, then have the aggregator push the new click count down to exactly the open connections each time it finishes counting. Open a real connection, click the link, and watch the number jump to the browser with no reload.
Counting Clicks Safely: Idempotency, DLQ, and Partial Batch Failure
Turn the logging consumer from the previous article into a real aggregator. Insert SQS between EventBridge and Lambda for batching, retry, and a dead-letter queue, count clicks into DynamoDB with a transaction that both increments counters and prevents double-counting in one atomic operation, and report failures per message so only the broken one is retried. Real tests: a duplicate event counts once, a failing event lands in the DLQ.
EventBridge: Decoupling Click Recording from the Redirect Path
Opening the event-driven part. Instead of counting clicks right inside the redirect handler, every link open publishes an event onto a custom EventBridge event bus, and a separate consumer handles it. Build the bus, have resolve publish the event, attach a consumer via an event pattern, then open a real link to watch the event flow through the bus to the consumer.
Multi-Tenant: Each User Their Own Data Slice, and Blocking IDOR
Turn the URL shortener into a true multi-tenant system. Add a list-links route scoped to the identity in the token, and a delete-link route that checks ownership inside the write operation so one user can't delete another's link even if they guess the code right. Tested with two real users to see the boundary hold.
Cognito and JWT Authorizer: Only Logged-In Users Can Create Links
Add real users with Amazon Cognito. Stand up a user pool that issues JWTs, attach the HTTP API's JWT authorizer to protect the create-link route while the open-link route stays public, and have the handler read the user identity from a claim in the token instead of hard-coding it. Create a real user, get a real token, call the API with and without a token to see the boundary.