Your team is debating whether to pull a chunk of functionality out of the monolith into its own service. How do you decide where a service boundary should go, and when splitting is the wrong move?
technical-conceptual · Mid level · software-engineering
What the interviewer is really asking
Assesses whether the candidate draws boundaries around business capability and data ownership and weighs the operational cost of a network boundary — rather than splitting by technical layer or chasing microservices for their own sake.
What to say
- Anchor the boundary on a business capability and the data it owns: a good service has its own bounded context and its own data store, so it can change and deploy independently — splitting along a domain seam, not a technical layer like 'all the controllers' or 'the database service.'
- Use coupling and change-frequency as the test: code that changes together and shares data should stay together; a chunk that has a clean interface, changes on its own cadence, or needs to scale independently is a strong candidate to extract.
- Name the cost a network boundary adds: what was an in-process call becomes a network hop with partial failure, you trade a single transaction for eventual consistency, and you take on deployment, monitoring, and versioning overhead — so don't split when the parts are chatty, share a transaction, or the team is too small to operate the extra service.
What to avoid
- Splitting by technical tier (a 'controller service', a 'database service') instead of by business capability, which creates services that can't change independently and chat constantly.
- Treating more services as automatically better architecture, ignoring that each one adds a network boundary, partial-failure modes, and operational load.
- Carving a boundary right through tightly-coupled data that needed one transaction, turning a simple local commit into a distributed-consistency problem you didn't have before.
Example answers
Strong: I'd draw the boundary around a business capability that owns its own data — say 'payments' or 'notifications' — so it can deploy and scale on its own cadence. My test is coupling: things that change together and share a transaction stay together; a chunk with a clean interface that changes independently or has a very different scaling profile is worth extracting. I'd push back on splitting by technical layer, and I'd keep it in the monolith if the pieces are chatty or share a transaction, because then I'm just trading an in-process call for a network hop and turning one commit into an eventual-consistency problem.
Weak: Monoliths are hard to scale, so generally splitting into microservices is the right call — it's the modern architecture and lets each piece scale. I'd probably break it up by layer so we have a service for the API, a service for the business logic, and a service for the database. More services means more flexibility.