Launch async parallelism
Launch, Async, and Parallelism Deep Dive¶
Overview¶
launch and async are the most used coroutine builders, but misuse creates
silent failures, unnecessary parallelism, or result-handling bugs.
Core Concepts¶
launchfor fire-and-forget side effectsasyncfor concurrent result production (Deferred)- lazy async defers start until needed
- bounded parallelism protects downstream systems
Internal Implementation¶
launch propagates uncaught exceptions immediately to parent/root.
async captures exceptions and rethrows on await(), which changes failure timing.
Lazy deferred jobs are created but not started until start()/await().
Threading Model¶
Builders do not define threads on their own; dispatcher and context do. Parallelism should be explicit and bounded to avoid pool saturation.
Coroutine / Flow Behavior¶
Builder choices often appear inside Flow pipelines and repository orchestration.
Unbounded parallel async usage can amplify pressure on APIs/DB and hurt tail latency.
Code Examples¶
suspend fun loadDashboard(): Dashboard = coroutineScope {
val user = async { api.loadUser() }
val feed = async { api.loadFeed() }
Dashboard(user.await(), feed.await())
}
suspend fun loadConditionally(flag: Boolean): String = coroutineScope {
val deferred = async(start = CoroutineStart.LAZY) { api.loadHeavy() }
if (flag) deferred.await() else "skipped"
}
Common Interview Questions¶
- Q: When is
launchpreferable toasync? A: Answer with correctness first and throughput second: cancellation model, dispatcher choice, bounded parallelism, and contention or latency measurements. - Q: Why can forgotten
await()hide failures? A: Answer with correctness first and throughput second: cancellation model, dispatcher choice, bounded parallelism, and contention or latency measurements. - Q: Is lazy async good by default? A: Answer with correctness first and throughput second: cancellation model, dispatcher choice, bounded parallelism, and contention or latency measurements.
- Q: How do you cap parallel requests safely? A: Lead with correctness then throughput: choose dispatcher by workload type, keep critical sections small, cap parallelism, and monitor tail latency and queue depth.
Production Considerations¶
- always consume
Deferredresults intentionally - cap fan-out with semaphore/limited parallelism
- prefer simple sequential flow unless parallelism is justified
- measure backend impact before increasing concurrency
Performance Insights¶
Parallelism helps throughput only until contention dominates. Beyond that, queueing and context-switch overhead reduce efficiency.
Senior-Level Insights¶
Senior engineers should explain concurrency budgets: how many tasks can run in parallel per feature, and how those limits are enforced and observed.