Where service boundaries actually crack

Three failure patterns we see when teams draw boxes around modules without naming the data that crosses them.

Laptop and notes during a systems discussion

Most architecture diagrams look tidy until you ask which service is allowed to write a given field. In reviews we run for Content Leafcore clients, the cracks rarely start at the network edge. They start at shared tables, dual-write habits, and “temporary” callbacks that never left.

Shared mutable state

Two services reading the same row is survivable. Two services writing the same row without a single owner is where retries invent ghost states. Name one writer. If you cannot, you do not yet have two services — you have a distributed argument.

The helpful callback

Service A calls B, and B calls A “just for enrichment.” That loop is polite in happy path and vicious when latency spikes. Prefer pushing the enrichment data on the original command, or materializing a read model owned by the consumer.

Error shapes that lie

If every failure returns 500 with a free-text body, clients invent their own recovery folklore. Align error codes with whether the caller should retry, fix input, or escalate. Your future on-call will thank the present you.

When we document these in a backend architecture review, we rank them against the decision the team named — launch date, regulatory deadline, or hire plan — not against an abstract purity score.

← All field notes