Design
5 areasThe architectural decisions that cost the most to change later. Where I focus before any line of code is written.
Event-driven architectures
Asynchronous systems with explicit contracts, ordering and recovery strategies.
API design and service contracts
Designing the seams between services so they can evolve without breaking each other.
Distributed systems
When a monolith is the right call, when microservices are not, sync vs async tradeoffs made explicit.
Domain modeling and tradeoff-driven choices
Technology decisions backed by the constraints they solve, not by hype.
Performance and scalability as design requirements
Treated as constraints from day one, not as fixes bolted on after the fact.
Verify
6 areasMaking sure the system actually works: under load, under attack, over time. Without this, automation just makes failures faster.
Observability
Traces, metrics and logs you can correlate. SLOs, burn-rate alerts, signal that matters.
End-to-end functional testing
Tests that exercise the system the way users do, deterministic enough to run in CI.
Performance testing
Load profiles tied to real traffic, regressions caught before users do.
Authentication and authorization
Identity and permissions designed once, enforced everywhere, including service-to-service.
Security analysis
Static and dynamic analysis, dependency scanning, threat modeling on the path that matters.
Architectural consistency over time
Guardrails so the system you designed is still the system you have a year later.
Automate
4 areasOnly after designing and verifying. Automation amplifies everything sitting above it, mistakes included.
CI/CD
Pipelines that fail loudly on the right things, ship safely on the others.
Container orchestration
Kubernetes when it earns its keep, with the platform abstractions to keep developers productive.
Infrastructure as Code
Reviewable, reproducible infrastructure, including the recovery path.
GitOps
Git as the source of truth for deployment state, drift caught automatically.