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

This tests thread pool selection and the CPU versus IO distinction. A strong answer maps CoroutineDispatcher to the thread pool, Default to CPU work, IO to blocking IO, and Main to the UI thread.
What's really being asked
This question probes whether you understand that a CoroutineDispatcher is not just an abstract concept but the concrete thread pool where coroutine code actually executes. Interviewers want to see that you grasp the distinction between CPU-bound work and blocking IO work, because choosing the wrong dispatcher starves the shared thread pool and destroys app performance.
The full answer
First, define CoroutineDispatcher as the base class that determines which thread or thread pool runs a coroutine. Second, explain Dispatchers.Default as the shared background pool used when no dispatcher is specified; it is backed by a fixed pool of worker threads equal to the CPU core count and is meant for compute-intensive tasks like sorting large lists or running algorithms. Third, explain Dispatchers.IO as a dispatcher that shares threads with Default under the hood but can create additional on-demand threads as needed; it is designed specifically for offloading blocking IO operations such as file reads, database transactions, or blocking network calls. Fourth, explain Dispatchers.Main as the UI thread dispatcher on Android where View updates must happen. Fifth, mention that Dispatchers.Unconfined exists but should not normally be used in production code.
The mistakes people make
A major red flag is saying that Dispatchers.Default is for any background work including blocking IO. Because Default has a limited thread pool, blocking it causes all coroutines on that dispatcher to stall. Another red flag is describing Dispatchers.IO as a separate unlimited pool; in reality it shares worker threads with Default and only spins up extra threads when blocking operations are detected. A third red flag is claiming that coroutines automatically move work off the main thread without specifying a dispatcher; beginners often think launch alone implies a background thread, but it inherits the caller context and can run on Main if launched there.
What usually comes next
The interviewer may ask what happens if you run blocking IO on Dispatchers.Default. They may also ask how Dispatchers.IO and Dispatchers.Default relate to each other under the hood, or when to use withContext versus launching on a different dispatcher. Another common follow-up is how to create a custom dispatcher with limitedParallelism or newFixedThreadPoolContext, and why you might prefer limitedParallelism on IO instead of creating a raw thread pool.
A concrete example
Imagine an Android ViewModel that loads a large JSON file from disk and then parses it. You should wrap the file read in withContext(Dispatchers.IO) because FileInputStream.read is a blocking call. Once the bytes are in memory, you switch to withContext(Dispatchers.Default) to parse and map the JSON into data classes because that transformation is CPU-intensive. Returning to Dispatchers.Main happens automatically when the result is posted to the UI layer via LiveData or StateFlow.
Interview question
An Android ViewModel reads a large file from disk and parses the bytes into objects. Which dispatcher strategy is correct?
- a.Perform both operations on Dispatchers.Default to avoid thread switching
- b.Perform the read on Dispatchers.IO and the parsing on Dispatchers.DefaultCorrect
- c.Perform both operations on Dispatchers.IO because it creates extra threads on demand
- d.Perform the read on Dispatchers.IO and the parsing on Dispatchers.Main since the data is already in memory
Why? this is the answer
Blocking file reads should use Dispatchers.IO, while CPU-intensive parsing belongs on Dispatchers.Default. Using Default for the read starves its limited thread pool, and using IO for parsing misuses the on-demand thread expansion designed for blocking operations.
Just read this? Test yourself on what you have been reading.
Read the original → kotlinlang.org
- #kotlin
- #coroutines
- #android
- #concurrency
- #dispatchers
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.
We are hiring for this. Open roles that interview on kotlin — each one lists the topics its interview covers.
See open roles