A while back I was building a Customer 360 Process API for a financial-services client. The mobile app team wanted one clean endpoint — GET /customers/{cif}/360 — that would return a customer's profile, their accounts from the core-banking system, their investment holdings from a wealth platform, their mortgage from the loan-origination system, and quietly drop an audit record into the logging pipeline on every call. One request in, one assembled view out. Simple from the app's perspective, four backend systems behind the curtain.

The naive way to build that is to cram everything into a single flow. I've inherited those flows from other people and they are miserable: a 600-line XML file nobody dares touch, the same customer-ID validation copy-pasted across four endpoints, and an audit-format change that means editing eight places. Worse, you can't test one branch without deploying the whole application.

Mule 4 hands you three building blocks to avoid exactly this, and confusingly they all read like "flows": the public <flow>, the <sub-flow>, and the private flow (which is just a <flow> with no source). They are not interchangeable. The differences come down to two questions — does it share my context, and does it own its own error handling — and once you internalize those two axes, the right choice is usually obvious.