Skip to content
tezvyn:

What is a CoroutineDispatcher and when to use IO vs Default?

Source: kotlinlang.orgMediumHow cards are made

What is a CoroutineDispatcher and when to use IO vs Default?

Tests your grasp of thread pool strategy for CPU vs. I/O-bound tasks. A good answer defines Dispatchers, contrasts the fixed-size Default pool (for CPU work) with the larger IO pool (for blocking I/O), and gives clear examples.

What's really being asked

This question tests your understanding of thread pool strategy. The interviewer wants to see if you can correctly map workload types (CPU-bound vs. I/O-bound) to the appropriate thread pool to maximize application performance and avoid thread starvation. It's a test of resource management, not just API knowledge.

The full answer

First, define a CoroutineDispatcher as a ContinuationInterceptor that determines the execution thread or thread pool for a coroutine. Second, briefly describe the three main dispatchers: Main for the UI thread, Default for CPU-intensive work, and IO for blocking I/O operations. Third, focus on the critical difference between Default and IO. Default uses a thread pool whose size is limited to the number of CPU cores, making it efficient for computational tasks that keep the CPU busy. Fourth, explain that Dispatchers.IO uses a larger, on-demand pool of threads (defaults to 64 or the number of cores, whichever is larger). This is designed for tasks that block a thread while waiting for external operations (like network or disk), allowing other tasks to proceed without exhausting the CPU-bound pool.

The mistakes people make

The biggest red flag is treating Dispatchers.IO as the default for all background work. This shows a misunderstanding of CPU-bound vs. I/O-bound tasks. Another common mistake is failing to explain the why behind the different pools, i.e., the difference in their size and purpose. Simply stating "Default is for CPU, IO is for I/O" is a junior-level answer. Stating that running a blocking call on Dispatchers.Default is fine is incorrect; it can starve the limited pool, blocking other computations. Finally, recommending Dispatchers.Unconfined for general use is a red flag, as official documentation advises against it.

What usually comes next

"What happens if you run a long-running blocking call on Dispatchers.Default?" (Answer: You tie up a valuable, CPU-optimized thread, potentially delaying other computations and degrading performance.) "How would you create a dispatcher for a service that should only ever have 10 concurrent network requests?" (Answer: Dispatchers.IO.limitedParallelism(10).) "When might you create your own thread pool instead of using Default or IO?" (Answer: For isolating a critical, long-running, or resource-intensive set of tasks from the shared pools to guarantee its resources and prevent it from impacting the rest of the app.)

A concrete example

Imagine you need to process a large bitmap image (e.g., apply a complex filter) and then upload it to a server. The filter application is CPU-bound: it's pure computation. This should run on Dispatchers.Default. The upload is I/O-bound: the thread will spend most of its time blocked, waiting for network packets. This should run on Dispatchers.IO. Using withContext(Dispatchers.Default) for the filter and withContext(Dispatchers.IO) for the upload is the correct, performant pattern.

Interview question

When applying a complex image filter and then uploading the image, which CoroutineDispatchers are best for each task?

  • a.Filter on Dispatchers.Default, upload on Dispatchers.IOCorrect
  • b.Filter on Dispatchers.IO, upload on Dispatchers.Default
  • c.Both filter and upload on Dispatchers.Default
  • d.Both filter and upload on Dispatchers.IO
Why?

Applying a complex filter is CPU-bound and best suited for Dispatchers.Default, which uses a core-limited thread pool. Uploading is I/O-bound and should use Dispatchers.IO, designed for blocking operations with a larger, on-demand thread pool. Using Dispatchers.IO for CPU-bound tasks is inefficient and doesn't leverage the CPU-optimized Default pool.

Just read this? Test yourself on what you have been reading.

Read the original → kotlinlang.org

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on coroutines — each one lists the topics its interview covers.

See open roles