A customer upgrades, then immediately downgrades a minute later because they picked the wrong plan. Your app emits subscription.updated twice — plan: pro at version 6, then plan: starter at version 7. Both events fan out to your billing destination. The pro delivery times out, gets retried, and lands a few seconds late. The starter delivery succeeds on the first try.
Now your destination has the events in the wrong order. The last write wins, and the last write was pro. The customer is on starter, paying for pro, and the support ticket is already open.
Nothing failed here. Every event was delivered. The retry worked exactly as designed. And the data is still wrong — because "delivered" and "delivered in order" are two completely different guarantees, and almost no fan-out system offers the second one.
Why fan-out can't deliver in order
This is not a Meshes limitation or a bug to be patched. It is a property of the architecture, and the same property holds for message brokers, event buses, and any system that delivers events to more than one place at scale.
Fan-out means one event in, many deliveries out, each on its own independent path. The moment you deliver in parallel, you have given up a single serialization point — and a single serialization point is the only thing that can enforce a global order. You can have high-throughput parallel delivery, or you can have a guaranteed total order. You cannot have both.
Retries make it concrete. Reliable delivery is at-least-once: a failed event is retried with exponential backoff and jitter until it succeeds or exhausts its attempts. That backoff is the whole point — it keeps a struggling destination from being hammered. But it also means a retried event can arrive after events that succeeded on the first try. The mechanism that makes delivery reliable is the same one that can reorder it — the two are not separable.
So events can arrive out of order, especially under retries. The honest move is to design for that, not to pretend it won't happen.
The gap nobody lists
We once broke event delivery down into five gaps that most hand-rolled integration code gets wrong: no retry strategy, no idempotency, no dead letter handling, no per-destination isolation, and no delivery visibility. Close all five and you have a genuinely reliable pipeline.
Ordering is not on that list. That is deliberate. It belongs to a different layer.
The other five gaps are about getting the event there — reliably, exactly once in effect, observably, without one bad destination taking down the others. Ordering is about what your code does with the event . You cannot close it on the delivery side, because the delivery side has already given up global order to fan out in parallel. It can only be closed on the receiver.