What Is a Coroutine? Functions That Pause and Resume
A coroutine is a function that can pause partway through, hand control back to its caller, and later resume exactly where it left off, keeping its local state.
Ordinary functions run to completion once called. A coroutine can suspend in the middle, yield control, and be resumed later with its variables intact. This cooperative model is the basis for lightweight concurrency in languages like Go, Kotlin, and Python, letting one thread juggle thousands of coroutines far more cheaply than thousands of OS threads.
How coroutines differ from functions
A normal function has one entry and one exit. A coroutine has multiple suspension points: it can yield, preserving its stack and locals, and be resumed later. Control passes cooperatively rather than being preempted by the OS scheduler.
Coroutines vs threads
Threads are scheduled preemptively by the OS and are relatively heavy. Coroutines are scheduled cooperatively in user space and are extremely light, so you can run huge numbers of them. The trade-off: a coroutine that never yields can starve the others.
What coroutines enable
- Massive concurrency, like a goroutine per connection.
- Async I/O written in a clean, sequential style.
- Generators that produce values lazily, one at a time.
- Cooperative multitasking without the cost of OS threads.
Cooperative scheduling
Because coroutines yield voluntarily, they only switch at defined points (like an await or a channel operation). That makes reasoning about shared state easier than with preemptive threads, but a coroutine that blocks without yielding can stall everything on its scheduler.
A quick example
In Go, starting go handle(conn) launches a goroutine, a coroutine the runtime multiplexes onto a small pool of OS threads, so thousands of connections cost very little.
Coroutines in CI
Coroutine-based test code can hang if a coroutine awaits something that never completes, stalling the suite until timeout. Latchkey enforces job timeouts so a stuck coroutine does not burn minutes indefinitely, and retries only failures that appear genuinely transient.
Key takeaways
- A coroutine can suspend and resume, keeping its local state across the pause.
- Coroutines are lightweight and cooperatively scheduled, unlike preemptive OS threads.
- They enable massive cheap concurrency but can stall a scheduler if they never yield.