Database Migrations Without Fear: Patterns That Won't Wake You Up at 3am

Database migrations are where deployments go to die. One bad migration can corrupt data, lock tables for hours, or bring down production entirely. Here’s how to make them boring. The Golden Rules Every migration must be reversible (or explicitly marked as not) Never run migrations during deploy (separate the concerns) Always test against production-scale data (10 rows works, 10 million doesn’t) Assume the migration will fail halfway (design for it) The Expand-Contract Pattern The safest way to change schemas: expand first, contract later. ...

March 12, 2026 Â· 7 min Â· 1289 words Â· Rob Washington

Cloud Cost Optimization: Stop Burning Money on AWS

Your AWS bill is too high. Everyone’s is. The cloud makes it trivially easy to spin up resources and surprisingly hard to know what you’re actually paying for. Here’s how to stop the bleeding. The Low-Hanging Fruit Unused Resources The easiest savings come from things you’re not using. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # Find unattached EBS volumes aws ec2 describe-volumes \ --filters Name=status,Values=available \ --query 'Volumes[*].[VolumeId,Size,CreateTime]' \ --output table # Find unused Elastic IPs aws ec2 describe-addresses \ --query 'Addresses[?AssociationId==`null`].[PublicIp,AllocationId]' \ --output table # Find idle load balancers (no healthy targets) aws elbv2 describe-target-health \ --query 'TargetHealthDescriptions[?TargetHealth.State!=`healthy`]' Run these monthly. You’ll find forgotten resources every time. ...

March 12, 2026 Â· 6 min Â· 1068 words Â· Rob Washington

LLM API Integration Patterns: Building Reliable AI-Powered Features

Integrating LLM APIs into production systems is harder than the tutorials suggest. The API call works in development. Then you hit rate limits, latency spikes, context limits, and costs that scale faster than your revenue. Here’s how to build LLM integrations that actually work. The Basics Nobody Mentions Always Stream Non-streaming API calls block until complete. For a 500-token response, that’s 5-15 seconds of your user staring at nothing. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # Bad: User waits forever response = client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": prompt}] ) print(response.choices[0].message.content) # Good: Tokens appear as generated stream = client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": prompt}], stream=True ) for chunk in stream: if chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end="", flush=True) Streaming also lets you abort early if the response is going off-rails. ...

March 12, 2026 Â· 7 min Â· 1350 words Â· Rob Washington

Home Automation for Developers: Beyond Smart Plugs

You’re a developer. You have smart lights. They turn on when you clap or yell at a cylinder. Congratulations, you’ve automated nothing meaningful. Real home automation is infrastructure. Let’s build it properly. The Stack That Works Home Assistant — The hub. Open source, local-first, integrates with everything. Run it on a Raspberry Pi, a NUC, or a VM. Zigbee/Z-Wave coordinator — Wireless protocols that don’t depend on WiFi or cloud services. Zigbee2MQTT or ZHA for Zigbee, Z-Wave JS for Z-Wave. ...

March 12, 2026 Â· 7 min Â· 1326 words Â· Rob Washington

CI/CD Patterns That Actually Work: Beyond the Tutorial Examples

Every CI/CD tutorial shows you “hello world” pipelines. Then you hit production and realize none of that scales. Here are the patterns that actually work. The Fundamental Truth CI/CD pipelines are software. They need: Version control (they’re in your repo, good start) Testing (who tests the tests?) Refactoring (your 500-line YAML file is technical debt) Observability (why did that deploy take 45 minutes?) Treat them with the same rigor as your application code. ...

March 12, 2026 Â· 6 min Â· 1208 words Â· Rob Washington

AI Coding Assistants: A Practical Guide to Actually Using Them Well

Everyone has access to AI coding assistants now. Most people use them poorly. Here’s how to actually get value from them. The Mental Model Shift Stop thinking of AI assistants as “autocomplete on steroids.” Think of them as a junior developer who: Has read every Stack Overflow answer ever written Types infinitely fast Never gets tired or annoyed Has no memory of what you discussed 5 minutes ago Will confidently produce plausible-looking nonsense That last point is crucial. These tools don’t know things. They predict likely tokens. The output often looks right even when it’s wrong. ...

March 12, 2026 Â· 9 min Â· 1750 words Â· Rob Washington

GitOps Done Right: When Git Becomes Your Control Plane

GitOps sounds simple: Git is the source of truth, automation syncs it to reality. In practice, most teams get it wrong. Here’s how to get it right. The Core Principle GitOps isn’t “we use Git.” It’s a specific operational model: Declarative: You describe what you want, not how to get there Versioned: All changes go through Git (audit trail for free) Automated: Software agents continuously reconcile desired vs actual state Observable: You can always answer “what’s deployed where?” The magic is in reconciliation. Traditional CI/CD pushes changes. GitOps pulls desired state and converges toward it. The system heals itself. ...

March 12, 2026 Â· 8 min Â· 1516 words Â· Rob Washington

Observability Beyond Logs: Building Systems That Tell You What's Wrong

You’ve got logging. Great. Now your system is down and you’re grep’ing through 50GB of text trying to figure out why. Sound familiar? Observability isn’t about collecting more data. It’s about collecting the right data and making it queryable. The goal: any engineer should be able to answer arbitrary questions about system behavior without deploying new code. The Three Pillars (And Why They’re Not Enough) You’ve heard this: logs, metrics, traces. The “three pillars of observability.” It’s a useful framework, but it misses something crucial: correlation. ...

March 12, 2026 Â· 4 min Â· 779 words Â· Rob Washington

SSH Config Mastery: Stop Typing Long Commands

Still typing ssh -i ~/.ssh/my-key.pem -p 2222 user@server.example.com? There’s a better way. The SSH Config File ~/.ssh/config transforms verbose commands into simple ones. # s # s s s B h A h e f f - t p o i e r r r o e ~ d / . s s h / p r o d - k e y . p e m - p 2 2 2 2 d e p l o y @ p r o d . e x a m p l e . c o m Basic Config # H H H o o o ~ s s s / t t t . H U P I H U I H U s p o s o d s o s d d o s s r s e r e t s e e e s e h o t r t n a t r n v t r / d N t g N t N c a d 2 i i a d i a d o m e 2 t n m e t m e n e p 2 y g e p y e v f l 2 F l F e i p o i s o i 1 l g r y l t y l 9 o o e a e 2 p d g . e . ~ i ~ 1 r e / n / 6 x . g . 8 a s . s . m s e s 1 p h x h . l / a / 1 e p m s 0 . r p t 0 c o l a o d e g m - . i k c n e o g y m - . k p e e y m . p e m Now just: ...

March 11, 2026 Â· 15 min Â· 3056 words Â· Rob Washington

Makefiles for Project Automation

Makefiles aren’t just for C projects. They’re a simple, universal way to document and run project tasks. Why Make Every project has tasks: build, test, deploy, clean. Make provides: Documentation — Tasks are visible in the Makefile Consistency — Same commands for everyone Dependencies — Tasks can depend on others Portability — Make is everywhere Basic Syntax 1 2 target: dependencies command Important: Commands must be indented with a tab, not spaces. ...

March 11, 2026 Â· 5 min Â· 965 words Â· Rob Washington