Member-only story
Race, Queue, or Cancel: Choosing the Right flatMap for Your Kotlin Flow
Not a Medium Member? “Read For Free”
Every Android codebase that uses Flow eventually grows a flatMap something. A map viewport triggers a trail query, a photo grid triggers thumbnail loads, a sync queue triggers uploads. The three flattening operators look interchangeable in a code review, and they are not. Swapping one for another changes what runs in parallel, what gets thrown away, what order the UI sees, and which bug you will be paged for.
This post puts flatMapMerge, flatMapConcat and flatMapLatest through the same input, shows exactly where the timelines diverge, and then walks through the failure modes that tend to survive code review. Examples come from a fictional hiking app called Trailhead.
The short version, as three mental models:
flatMapMergeraces. Every item starts work right away, and results are emitted in the order they finish, not the order they arrived.flatMapConcatqueues. One inner flow runs at a time, in arrival order. Everything behind it waits, including the upstream producer.flatMapLatestcancels. A new item kills the running inner flow. Only the freshest work gets to finish.










