The diagram is not the architecture
Everyone can draw boxes and arrows. The real test comes later: the night a service goes down, the month the team doubles, the year the product pivots. A good architecture is one that makes those three moments boring.
We build and operate booking platforms, enterprise platforms serving seven languages, and multi-tenant SaaS products. What follows is not theory. It is what survived.
Layers, not spaghetti
Every system we ship follows the same data flow, from the client down to storage:
- Frontend: the interface, as thin as possible. It displays, it validates at the surface, it decides nothing.
- Backend and APIs: all business logic lives here, testable, versioned, documented.
- Data: one source of truth per domain. Copies are acknowledged caches, never competing truths.
- Cloud and operations: infrastructure described as code, automated deployments, secrets out of the codebase.
This separation sounds obvious. It is not. Most systems we audit mix business logic into the interface, or let three databases contradict each other. Every leaking layer costs weeks later.
Microservices or monolith: the wrong question
The question is not how many services, but how many teams and how many deployment rhythms. A well-modularized monolith beats a badly-partitioned constellation of microservices, every single time.
We move to microservices when two conditions meet: business domains that evolve at different speeds, and a team able to operate the extra complexity. On an enterprise platform we operate, .NET microservices on Azure earn their keep: billing, booking and reporting change at different rhythms and deploy independently. On a young SaaS, a Next.js monolith with PostgreSQL ships faster and refactors painlessly.
The data flow is the product
An architect who cannot draw the exact path of a piece of data, from user input to storage to reporting, does not know their system. We document that path for every critical feature: who writes, who reads, who transforms, who archives.
That is what makes integrations safe. When a real-estate website has to move from one CRM to another, the migration succeeds because the flow is explicit: listings have a source, media has a pipeline, leads have a routing. You reconnect the source, and the rest follows.
Infrastructure is code, or it does not exist
An environment that cannot be recreated from a Git repository is debt. Terraform, Bicep or the cloud's native tooling, the tool matters less than the property: production is reproducible, staging is identical, and a new environment stands up in hours, not weeks.
Same bar for delivery: every commit passes unit tests, end-to-end tests and an automated deployment. Cypress on the critical journeys has prevented more incidents for us than any code review.
Observability before the first incident
Structured logs, metrics and alerts go in on day one, not after the first three-in-the-morning wake-up. Our rule: every meaningful business event produces a usable trace, and every alert must be actionable. An alert ignored twice is an alert to delete or to fix.
Choose boring
PostgreSQL over the fashionable database. Proven message queues over the latest event framework. Readable code over brilliant code. Boring technology has a magical property: it is still maintained, documented and hireable five years from now.
We save innovation for where it pays: AI integrated into business workflows, operations automation, user experience. The foundation stays boring. That is why it holds.
What this changes for you
If you are having a system built, demand three things: a data-flow diagram you understand, infrastructure reproducible from a repository, and automated tests on the journeys that make your revenue. Everything else is negotiable. Not those three.
