Thinking
Technical articles on AI, development tools, cloud architecture, and software engineering.
Your agent doesn't need the whole internet: egress control and permissions on AWS
How to limit what an AI agent can reach and do on AWS: Network Firewall domain allowlists, why DNS filtering alone fails, one IAM role per agent with session policies, approval gates and a kill switch.
Fargate vs App Runner cost: the same app, priced both ways
Fargate vs App Runner cost, calculated for the same Next.js app: list prices, ALB, public IPv4 and NAT included, and the break-even point where Fargate wins.
How we build cloud and DevOps: three accounts, one CDK codebase, and no cluster
We operate AWS for our own products and for a client platform with real users and real money flowing through it.
Infrastructure as code does not mean Terraform. CDK, Pulumi, and the question that actually decides it
Somewhere around 2019, "infrastructure as code" became a synonym for Terraform in most conversations, the way "search" means Google. It is a reasonable default.
Queues without Kafka: SQS, EventBridge, and the one place we actually needed a stream
Every platform reaches the moment where a request does too much. The checkout handler sends an email, updates the search index, notifies the warehouse, records…
Rate limiting: at the edge, in the gateway, or in the app? Three layers, three jobs
"Add rate limiting" is a one-line ticket that hides three different problems.
Health checks that lie: six ways your service says "ready" when it isn't
A health check is a contract between your application and the thing that routes traffic to it.
Backups you've never restored aren't backups. A restore drill, timed.
Every AWS data store has backups turned on by default or by a checkbox. Aurora keeps automated backups. DynamoDB has point-in-time recovery. S3 has versioning.
An incident runbook for a team without on-call
Big companies have on-call rotations, incident commanders, severity matrices and a tooling budget to match.
Rotating the database password without downtime: the thing you've been putting off
Everyone agrees the database password should rotate. Almost nobody's does, and the reason isn't laziness.
WAF for a Next.js app: the managed rules that block legitimate traffic, and what we did about them
Turning on AWS WAF in front of a web application is one CDK construct and a checkbox's worth of managed rule groups.
Secrets in CDK: Secrets Manager, Parameter Store, and never anything in the template
A CloudFormation template is a text file. It's stored by CloudFormation, it's in cdk.out on every developer's disk, it's in the CI logs from the last synth…
Reserved, Savings Plans, or nothing: when a one-year commitment is actually worth it at small scale
AWS will give you up to 72 % off compute if you promise to keep paying for it for three years. The number is real and it's in every cost-optimisation checklist.
AWS NAT Gateway cost: the most expensive line you don't see
How much does an AWS NAT Gateway cost per month? $32.85 per gateway before any traffic, plus $0.045/GB. Worked examples, our $102 bill and five ways to cut it.
Zero-downtime deploys aren't a platform feature. They're a schema-migration discipline.
Every container platform will tell you it does zero-downtime deployments.
Dev, staging and prod from day one: why a team of three shouldn't wait
"We'll separate environments later, when we have users." We've heard that sentence from every small team we've worked with, and we've said it ourselves.
You don't need Kubernetes. You need a good Dockerfile and a place to run it.
Every few months a team of three to five engineers asks us whether they should move to Kubernetes.
What managed observability really costs at 100 GB a day: Datadog, Grafana Cloud, self-hosted
The observability bill is the one that surprises people twice. The first time is when it arrives and it's a third of the compute bill.
Alerts that don't know which cloud they run in
Every cloud sells you alarms. CloudWatch Alarms, Azure Monitor alert rules, Cloud Monitoring alerting policies: each one is preconfigured, each one is a few…
Your traces shouldn't know which cloud they run in either
We made the case that application logs shouldn't be owned by the cloud: the app emits, an agent stamps the cloud onto it, a neutral backend stores it.
Same tag, no deploy: why cdk deploy with an unchanged image does nothing, and the 300-line script we wrote around it
Two stories about the same deploy pipeline, told together because the second exists because of the first.
CloudWatch data protection policies: masking PII before it lands in your logs
A support engineer asked for a debug log on one API route, "just for a week", to chase a bug in address validation. The log line was the whole request body.
Aurora Serverless v2 after six months: the 0.5 ACU floor and the auto-pause myth
Aurora Serverless v2 is sold with one sentence: pay for the database capacity you use, scaled in fractions of a second.
The CloudFormation 500-resource limit, and how we split a stack without losing data
Hit the CloudFormation 500-resource limit? How we split a CDK stack without losing data: moving stateless resources, importing stateful ones, and the traps.