Every monolith eventually gets a meeting about “breaking it into services.” The danger is that you can draw the lines in a hundred places, and most of them just relocate the complexity instead of reducing it.

This is a working note rather than a definitive guide — the patterns here come from systems I’ve actually shipped and the trade-offs I kept running into along the way.

Cut along the change, not the nouns

The boundaries that hold up are the ones that follow how the system actually changes. Two things that always deploy together belong together; two things owned by different teams with different release rhythms are begging to be split.

A good boundary is one you rarely have to cross to get work done.

When I get a seam right, a feature lives mostly inside one service and the contracts between services stay boring. When I get it wrong, every change turns into a distributed transaction and a calendar invite.

None of this is glamorous, but it’s the part that decides whether a design holds up once real traffic and real deadlines arrive.