Kotlin Coroutines Roadmap

Asynchronous programming and concurrency in Android (modern best practices)

Kotlin Coroutines: Effortless async programming

Master coroutines for clean, efficient concurrency without callbacks or threads.


Coming Soon!

We're building this Kotlin Coroutines course - full modules with code, videos, and projects launching soon. If interested, rate us below to prioritize updates! ⭐⭐⭐⭐⭐

play_arrow
Getting Started with Coroutines (Absolute Basics)

Zero-prereq intro: mental model, first coroutine, basic suspend, and core terms.

3 days


  • play_circleWhat Are Coroutines? (not threads) - the mental model
  • play_circleHello Coroutine: runBlocking + launch + delay (console demo)
  • play_circlesuspend Functions 101: writing & calling your first suspending API
  • articleCheat Sheet: coroutine • job • scope • builder - quick definitions
  • articleProject Setup (JVM & Android): coroutines-core/android + test libs
  • assignmentPractice: two coroutines printing → refactor into a suspending function
build
Suspending & Builders - Foundations

Clear separation of concepts: suspension vs blocking, builders, scope boundaries, and a first taste of structured concurrency.

5 days


  • play_circleSuspension vs Blocking: delay() vs Thread.sleep()
  • play_circleSuspension Points in Practice: delay, I/O with withContext(Dispatchers.IO), Flow collect/emit
  • play_circleCooperative Cancellation: isActive, ensureActive, yield (keep work responsive)
  • play_circleBuilders Deep Dive: launch vs async/await (returning results)
  • play_circlecoroutineScope vs supervisorScope: structure & child-failure behavior
  • play_circleStructured Concurrency 101 (overview): parents, children, Job trees
  • play_circlerunBlocking - when it's OK (tests/main) and when it's not (Android/UI)
  • articleCheat Sheet: choosing a builder & scope (quick reference)
  • assignmentPractice: Parallel API calls with async + cancellation propagation
account_tree
Structured Concurrency - Deep Dive

Principles, job hierarchies, failure propagation, supervision, and real-world scope design.

5 days


  • play_circleStructured Concurrency Principles (the key invariants)
  • play_circleJob Hierarchies & Cancellation Trees (visual walkthrough)
  • play_circleFailure Propagation: launch vs async (who cancels whom?)
  • play_circleSupervisorJob vs supervisorScope: boundaries & use-cases
  • play_circleStructured Parallelism: async + awaitAll + cancellation on first failure
  • play_circleMultiple Failures, finally, and NonCancellable (cleanup patterns)
  • play_circleAnti-patterns & Leaks: GlobalScope, orphan Jobs, ad-hoc scopes
  • articleScope Design Guide (UI, repo, use-case): who owns the scope?
  • assignmentPractice: Cancellation propagation lab (normal vs supervisor)
  • assignmentPractice: Parallel fan-out with fail-fast & proper cleanup
tune
Context & Dispatchers - Mastery

Understand CoroutineContext deeply: elements, inheritance, dispatchers (Main/IO/Default/Unconfined), thread switching with withContext, limited parallelism, and thread-local propagation.

5 days


  • play_circleCoroutineContext 101: elements, + combination, inheritance & overriding
  • play_circleDispatchers: Main, IO, Default - when to use each (and why Unconfined is risky)
  • articleAndroid specifics: Dispatchers.Main.immediate & main-safety notes
  • play_circlewithContext correctly: switching threads without nesting traps; cancellation semantics
  • play_circleTuning concurrency: Dispatchers.IO.limitedParallelism(n) and when to use it
  • articleCustom dispatchers: Executor.asCoroutineDispatcher vs newSingleThreadContext (trade-offs & cleanup)
  • play_circleNaming & diagnostics: CoroutineName + structured logging
  • play_circleThread context propagation: ThreadLocal.asContextElement / ThreadContextElement (MDC, request IDs)
  • articleQuick note: CoroutineExceptionHandler is a context element (limitations for async)
  • assignmentPractice: Reduce context hops, add CoroutineName, wire MDC, and cap IO parallelism
fast_forward
CoroutineStart Modes - Practical Control

DEFAULT, LAZY, ATOMIC, UNDISPATCHED: how they start, when to use them, and common pitfalls.

3 days


  • play_circleThe start parameter on launch/async - what it controls
  • play_circleDEFAULT vs LAZY - triggering start (start/join/await) & pitfalls in structured concurrency
  • play_circleUNDISPATCHED - run on caller thread until first suspension (safer than Unconfined)
  • articleATOMIC (Delicate) - guaranteed start before cancellation: use-cases & warnings
  • assignmentPractice: Compare modes - warm-up jobs, lazy pipelines, and observing thread hops
stop
Cancellation & Timeouts - Real-World Patterns

Cooperative cancellation model, robust cleanup, timeouts that don't bite you, and writing cancel-safe suspend APIs.

5 days


  • play_circleCancellation Model: Job.cancel, CancellationException, parent→child rules
  • play_circleCooperative Cancellation in Practice: isActive, ensureActive, yield (CPU loops)
  • play_circleCleanup Patterns: try/finally, withContext(NonCancellable), closing resources/channels
  • play_circleTimeouts Deep Dive: withTimeout vs withTimeoutOrNull, propagation & common pitfalls
  • play_circleDesigning Cancel-Safe suspend APIs with suspendCancellableCoroutine
  • articleHooking Cancellation: invokeOnCancellation, listener removal, idempotent cleanup
  • play_circleCanceling Blocking Work: IO with withContext(Dispatchers.IO), interruptible ops, library caveats
  • play_circlePolicy & Patterns: cancel vs retry, supervisor boundaries, time-budget design
  • assignmentPractice: Build a cancel-safe repository (network + cache) with timeouts & retries
error
Exception Handling & Supervision - Mastery

Understand how failures propagate, where exceptions surface, how supervision isolates errors, and how to build resilient retry logic.

5 days


  • play_circleException Model: child→parent propagation & who cancels whom
  • play_circlelaunch vs async: where exceptions surface (handler vs await)
  • play_circleCoroutineExceptionHandler: root-only behavior & limitations with async/supervision
  • articleSupervisorJob vs supervisorScope: isolation boundaries & use-cases
  • play_circleMultiple Failures & Cancellation: suppressed exceptions, failures during cleanup
  • play_circleCancellation vs Failure: handling CancellationException vs real errors (rethrow patterns)
  • play_circleRetries & Backoff (no Flow): exponential backoff, jitter, cancellation-aware delays
  • assignmentPractice: Fail-fast vs supervised trees + resilient use-case with retries
lock
Shared Mutable State & Synchronization - Practical Patterns

Avoid races with confinement, locks, semaphores, or actors. Keep critical sections tiny and responsive.

5 days


  • play_circleStrategies Overview: immutability, confinement, message passing
  • play_circleMutex.withLock: critical sections, tryLock, and “no blocking inside the lock”
  • play_circleSemaphore.withPermit: limiting parallel work & rate limiting (vs limitedParallelism)
  • articleSingle-threaded serialization: custom dispatcher/executor & cleanup duties
  • play_circleActors for Single-Owner State: when an actor beats locks; mailbox/backpressure basics
  • articleChoosing the Right Tool: decision guide + fairness/starvation notes
  • assignmentPractice: Controlled parallel downloads + shared progress counter (lock-free → mutex)
trending_up
Flow Fundamentals

Cold streams, terminal ops, cancellation transparency, and where work runs.

1 week


  • play_circleCold vs Hot - mental model & lifecycle (preview of StateFlow/SharedFlow)
  • play_circleflow{} builder & terminal ops: collect, first/firstOrNull, single, toList
  • play_circleContext & execution: flowOn vs withContext (upstream-only) + exception transparency
  • articleSide-effects & structure: onStart, onEach, onCompletion, emitAll
  • play_circleWrapping callbacks with callbackFlow: awaitClose, cancellation-safe cleanup
  • play_circlechannelFlow vs callbackFlow - when to choose which
  • assignmentPractice: Debounced search pipeline (cold Flow)
transform
Flow Operators & Backpressure

Transform, combine, and control rate like a pro (with correct error semantics).

5 days


  • play_circleTransform basics: map, transform, transformLatest (when latest cancels prior work)
  • play_circleFlatMap family: flatMapConcat / flatMapMerge / flatMapLatest - trade-offs & patterns
  • play_circleCombining streams: zip vs combine (+ combineTransform) - ordering & timing
  • play_circleRate control: buffer(capacity, onBufferOverflow), conflate, collectLatest, debounce, sample
  • articleStateful ops: distinctUntilChanged/By, scan, runningFold
  • play_circleError handling: catch placement (upstream/downstream), onCompletion, retry/retryWhen
  • assignmentPractice: Performance-tuned pipeline (debounce + flatMapLatest + buffer)
hot_tub
Hot Flows: StateFlow & SharedFlow

UI state, one-shot events, and sharing strategies done right.

4 days


  • play_circleStateFlow for UI State: replay=1, conflation, update()
  • play_circleSharedFlow for Events: replay, extraBufferCapacity, onBufferOverflow (sticky vs non-sticky)
  • articleTurning Cold → Hot: stateIn & shareIn with SharingStarted (Eagerly/Lazily/WhileSubscribed)
  • play_circleScopes & Performance: where work runs with flowOn + stateIn/shareIn; avoid per-collector hot flows
  • assignmentPractice: ViewModel exposing StateFlow (UI state) + SharedFlow (one-shot events)
sync_lock
Lifecycle-Aware Collection (Android)

Compose & View patterns that are safe, leak-free, and production-ready.

4 days


  • play_circleLaunching in Android: viewModelScope & lifecycleScope (ownership, boundaries, pitfalls)
  • play_circleCompose: collectAsStateWithLifecycle (vs collectAsState), LaunchedEffect, rememberCoroutineScope, snapshotFlow
  • play_circleViews: repeatOnLifecycle (and why launchWhenX is discouraged)
  • articleAvoiding Leaks & Duplicates: single source of truth, shareIn/stateIn, where to collect
  • assignmentPractice: Build a lifecycle-safe screen (Compose + View example)
call_merge
Channels - Pipelines & Point-to-Point

Build producer–consumer pipelines with Channels and know when SharedFlow is the better fit.

4 days


  • play_circleChannel Types & Capacity: RENDEZVOUS / BUFFERED / CONFLATED / UNLIMITED
  • play_circleSending & Receiving: send/receive, trySend/tryReceive, receiveCatching
  • play_circleLifecycle: close vs cancel, iteration with for-loop, backpressure semantics
  • articlePatterns: fan-in, fan-out, pipelines, fairness trade-offs
  • play_circleChannel vs SharedFlow: decision guide (point-to-point vs broadcast)
  • assignmentPractice: Multi-stage channel pipeline with multiple producers/consumers
integration_instructions
Integration: Networking, Storage, Background

End-to-end Android patterns with coroutines: suspend networking, offline-first storage, paging, and background work.

1 week


  • play_circleRetrofit suspend APIs + serialization (Moshi / Kotlinx) & OkHttp interceptors/timeouts
  • play_circleNetwork patterns: withContext(Dispatchers.IO), retries/backoff, error mapping (HTTP→Domain)
  • play_circleRoom DAO with Flow: queries, transactions, and DTO → Entity → Domain mapping
  • articleSingle Source of Truth: cache-then-network, invalidation, and sync strategies
  • play_circlePaging 3 in practice: Pager, PagingSource, RemoteMediator, load states, cachedIn(viewModelScope)
  • play_circleBackground work: WorkManager CoroutineWorker (cancellation, progress, constraints) vs Foreground service
  • assignmentPractice: Offline-first repository (Retrofit + Room + Paging RemoteMediator) with retry & background sync
bug_report
Testing Coroutines & Flows - From Zero to Flake-Free

Deterministic, fast, and reliable tests with kotlinx-coroutines-test and Turbine.

5 days


  • play_circleTest Dispatchers 101: StandardTestDispatcher vs UnconfinedTestDispatcher
  • play_circlerunTest & Virtual Time: scheduler, advanceTimeBy, runCurrent, advanceUntilIdle
  • articleMainDispatcherRule (JUnit4/JUnit5) & swapping Dispatchers.Main safely
  • play_circleTesting suspend functions: success, exceptions, cancellation
  • play_circleTesting Cold Flows: terminal ops, flowOn, catch placement
  • play_circleTesting Hot Flows (StateFlow/SharedFlow): backgroundScope, replay, buffer, timing
  • play_circleTurbine Patterns: awaitItem, skipItems, expectNoEvents, timeouts, cancelAndIgnoreRemainingEvents
  • play_circleTime-based Operators: debounce, sample, retry/backoff with virtual time
  • articleChannels & select in tests: send/receive, closing, and race scenarios
  • play_circleFlake-proofing: deterministic scheduling, avoid real delays, leak checks with TestScope
  • assignmentPractice: Repo Flow tests (retry + timeout) + StateFlow UI state with Turbine
rocket_launch
Performance, Patterns & Capstones - Ship It

Make it fast and resilient, then apply everything in real projects.

1 week


  • play_circleMinimize context hops & avoid needless withContext (throughput & readability)
  • play_circleTuning parallelism: Dispatchers.IO.limitedParallelism(n) vs Semaphore.withPermit
  • play_circleBackpressure in hot streams: StateFlow/SharedFlow buffer, overflow, replay sizing
  • play_circleDetecting cancellation leaks & logging coroutine trees (diagnostics playbook)
  • articlePattern catalog: retries/backoff, time budgets, circuit breaker & hedging
  • play_circleCapstone A: Offline-First Search (Flow + Room + retries)
  • play_circleCapstone B: Downloader (callbackFlow + StateFlow, pause/resume/cancel)
  • assignmentPractice: Implement one capstone end-to-end (repo, tests, perf checks)

Post a Comment

Previous Post Next Post