Choosing a database: relational unless you have a reason
Relational databases handle the overwhelming majority of business workloads well. Alternatives should be chosen for specific reasons.
Microservices solve organisational scaling problems and introduce distributed systems problems. Most teams should start with a well-structured monolith.
Independent deployment by independent teams, and independent scaling of components with very different load profiles. Both are real problems at a certain organisational size.
They are not a solution to messy code. A poorly structured monolith becomes a poorly structured distributed system with network calls between the mess.
One deployable unit with strict internal module boundaries: modules communicate through defined interfaces, own their data, and do not reach into each other's tables.
This gives most of the structural benefit — clear ownership, testable boundaries, the ability to reason about a part — without distributed systems overhead. It also makes later extraction straightforward, because the seams already exist.
Good reasons: a component with a genuinely different scaling profile, a team that needs to deploy independently, a part with different compliance requirements.
Extract that piece and leave the rest. A gradual, evidence-led split ends up in a better place than a big-bang decomposition designed before the pressures were known.
A modular monolith only delivers its benefit if the boundaries hold, and in a single codebase nothing physically prevents one module reaching into another.
Enforce it in the build: package or namespace rules, dependency linting, or architecture tests that fail when a module imports another's internals. Without enforcement, boundaries erode within months under deadline pressure.
Give each module its own data ownership too. Shared tables are the most common way a modular design quietly becomes a monolith in the pejorative sense.
When you have more services than teams, coordination cost usually exceeds the benefit. Services without a clear owner drift.
Yes, and some organisations do. Consolidating services that always deploy together is a legitimate simplification.
The same reasoning applies. Many small functions with no clear boundaries produce the same coordination problems with additional cold-start considerations.
Keep reading
Relational databases handle the overwhelming majority of business workloads well. Alternatives should be chosen for specific reasons.
Complete rewrites fail at a high rate. Incremental strangulation delivers value earlier and carries far less risk.
Events decouple producers from consumers and make the overall flow harder to see. Both effects are real and need managing.