Engineering Principles
These are the principles I return to when a systems architecture decision gets hard. They are not rules. They are defaults I trust until a specific problem gives me a reason not to.
Design the data schema first, the code second
Most system failures are data modeling failures in disguise. If the PostgreSQL constraints or Kafka schemas are wrong, no amount of application logic will fix the service. Spend the first hour on data shapes, not code.
State lives at the source of truth
Database state belongs in the database. Cached state belongs in Redis. Event streams hold historical facts. Avoid local microservice memory states that diverge from the clusters.
Keep network boundaries explicit
Every cross-service hop is a potential timeout, connection failure, or query latency spike. Treat network boundaries as untrusted and wrap them in circuit breakers.
Boring tools are a feature
Default to boring databases (PostgreSQL, Redis) and robust runtimes (Node.js, NestJS). Save your novelty budget for the specific product flows that genuinely demand custom engines.
Event boundaries over HTTP hooks
Instead of coupling services with direct HTTP calls, declare facts: 'Order submitted,' decoding downstream actions asynchronously through Kafka event partitions. Decoupled services scale independently.
Performance is an architectural choice
The fastest endpoint is the one that was designed to read index scans or hit cached memory. Most performance bottlenecks are database design choices made before a single query was written.
Automate build and container integrity
If a container check is manual, it is a vulnerability. Secure schemas, Docker configurations, and lint rules inside continuous integration (CI) runners, failing builds early.
Write code for the team after you
The reader of systems code is almost never the author. Optimize for legibility, predictability, and explicit variables. Document why an infrastructure pattern was chosen, not just what it does.
Ship the smallest event that proves the concept
Monolithic deployments fail by inches across dozens of vectors. Event-driven deployments fail visibly in one handler, which is exactly how you isolate bugs.
Treat the infrastructure as code
If you configure an AWS bucket or Cloudflare Tunnel manually in a console dashboard, it does not exist. Declare all infrastructure resources securely so they are reproducible.