How does coroutine cancellation work internally?

Tests your grasp of cooperative cancellation. A good answer explains that cancel() sets a flag, suspend functions check it and throw CancellationException, and non-suspending loops need manual isActive checks.
What's really being asked
This question assesses your understanding that coroutine cancellation is cooperative, not preemptive. The interviewer wants to see if you know the internal mechanics: the role of the Job state, suspension points, and CancellationException. It separates candidates who just use the API from those who understand the underlying concurrency model, which is critical for writing robust, resource-efficient code.
The full answer
A strong answer explains the process in four steps. First, calling job.cancel() doesn't stop anything immediately. It atomically moves the Job to a 'Cancelling' state and sets an internal flag. Second, the coroutine continues executing until it hits a suspension point. Third, all suspend functions in kotlinx.coroutines (like delay, yield, withContext) are cooperative. Before resuming, they check the job's status. If cancelled, they throw a CancellationException instead of resuming. Fourth, for a long-running, non-suspending computation (like a tight while loop), the coroutine must be made cooperative manually by periodically checking the coroutineContext.isActive boolean property and exiting if it's false.
The mistakes people make
The biggest red flag is stating that cancel() immediately stops the coroutine or kills the underlying thread. This shows a fundamental misunderstanding of the cooperative model. Another common mistake is forgetting to mention CancellationException, which is the core mechanism for unwinding the call stack. A candidate who can't explain how to make a CPU-bound loop cancellable (using isActive) is not demonstrating senior-level knowledge. Finally, suggesting you should catch CancellationException without re-throwing it is a major error, as it breaks structured concurrency.
What usually comes next
Expect questions like: "What is the difference between checking isActive and calling ensureActive()?" (ensureActive() throws the exception for you). Or, "When would you use a NonCancellable context?" (For essential cleanup code in a finally block that must run even if cancelled, like closing a file or releasing a lock). Or, "What happens if you swallow a CancellationException?" (The coroutine will appear to complete successfully, and cancellation will not propagate to its parent).
A concrete example
Imagine a coroutine processing a list of 1,000,000 images. A non-cooperative for loop would continue processing all 1M images even if the user navigates away and job.cancel() is called after the 10th image. This wastes CPU and memory. A cooperative version would use while (i < list.size && isActive) or check isActive inside the loop. When cancel() is called, isActive becomes false, and the loop terminates gracefully after finishing its current iteration, preventing hundreds of thousands of unnecessary operations.
Interview question
A coroutine executes a CPU-intensive `while` loop without any suspend function calls. If its job is cancelled, what is required for the coroutine to actually stop?
- a.The loop must periodically check the `isActive` property of the coroutine context and manually exit.Correct
- b.Nothing; the `cancel()` call interrupts the underlying thread, which immediately terminates the loop's execution.
- c.The coroutine will stop automatically once it finishes the current iteration of the `while` loop.
- d.A `CancellationException` will be thrown automatically on the next loop iteration, unwinding the stack.
Why? this is the answer
Coroutine cancellation is cooperative, not preemptive. For code without suspension points, like a tight loop, the coroutine must manually check its `isActive` state to participate in cancellation.
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.
We are hiring for this. Open roles that interview on kotlin — each one lists the topics its interview covers.
See open roles