Modular monolith or microservices: choosing on team shape
Microservices solve organisational scaling problems and introduce distributed systems problems. Most teams should start with a well-structured monolith.
Most integration problems are variations on a few known patterns. Choosing deliberately avoids inventing a worse version.
Direct connections between two systems are simple and appropriate for a small number of integrations. The difficulty is combinatorial: each new system multiplies the connections, and eventually nobody can describe the estate.
The threshold is usually reached sooner than expected, and the resulting tangle is expensive to unpick.
Any integration will be unavailable at some point. Every boundary needs timeouts, bounded retries with backoff, and defined behaviour when the other side is down.
Circuit breakers prevent a slow dependency exhausting your own resources, which is how one system's problem becomes everyone's outage.
Define one system of record per entity. Where data is duplicated for performance, be explicit about which copy is authoritative and how discrepancies are resolved.
Build reconciliation reporting from the start. Discrepancies between systems are inevitable, and finding them through a customer complaint is the expensive route.
Integrations fail silently more often than loudly. A queue consumer stops, a scheduled transfer does not run, a webhook endpoint returns errors nobody sees, and the discovery is a business user asking why data is missing.
Monitor throughput and lag on every integration, alert on absence as well as on error — a feed that normally delivers hourly and delivers nothing is a failure — and reconcile record counts between systems regularly.
Absence monitoring is the part most often missing, and it catches the failure mode that causes the most business disruption.
At a certain number of integrations, centralised tooling for routing, transformation and monitoring pays for itself. Below that it is overhead.
Rarely, and mainly as a transitional step during modernisation. It couples systems so tightly that neither can change its schema independently.
Transform at the boundary rather than spreading knowledge of another system's format through your codebase. One place to change when the other side changes.
Keep reading
Microservices solve organisational scaling problems and introduce distributed systems problems. Most teams should start with a well-structured monolith.
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.