What are goroutines and how do they differ from OS threads?
Understand what goroutines are, how Go's M:N scheduler makes them cheaper than OS threads, and why Go scales to thousands of concurrent tasks.
Expected Interview Answer
A goroutine is a lightweight, independently executing function managed by the Go runtime rather than the operating system, letting you run thousands of concurrent tasks cheaply by simply prefixing a call with the go keyword.
Unlike an OS thread, which typically reserves around a megabyte of stack and is scheduled by the kernel, a goroutine starts with a tiny stack (a few kilobytes) that grows and shrinks on demand. The Go runtime multiplexes many goroutines onto a small pool of OS threads using its own M:N scheduler, so context switches are cheap and you can have hundreds of thousands of goroutines where OS threads would exhaust memory.
- Extremely cheap to create — a few kilobytes each
- Scheduled in user space by the Go runtime, not the kernel
- Scale to hundreds of thousands of concurrent tasks
- Stacks grow and shrink dynamically
- Simple syntax: just the go keyword
- Work well with channels for safe communication
AI Mentor Explanation
OS threads are like fielders each needing a full stadium slot, so you can only field eleven. Goroutines are like assigning quick roles to a huge squad, where a manager rotates many players through the same few positions on demand. The Go runtime is that manager, cycling thousands of light tasks through a handful of real fielding spots.
Step-by-Step Explanation
Step 1
Start a goroutine
Prefix any function call with the go keyword; it runs concurrently and returns immediately to the caller.
Step 2
Tiny stacks
Each goroutine begins with a small stack (a few KB) that grows and shrinks automatically, unlike a thread's large fixed stack.
Step 3
M:N scheduling
The runtime maps many goroutines (M) onto a small number of OS threads (N) using logical processors set by GOMAXPROCS.
Step 4
User-space switching
The Go scheduler switches goroutines in user space at safe points, avoiding costly kernel context switches.
Step 5
Coordinate work
Use channels or sync primitives (WaitGroup, Mutex) to communicate and wait for goroutines to finish.
What Interviewer Expects
- Defining a goroutine as a runtime-managed lightweight task
- Contrasting stack size and cost with OS threads
- Explaining the M:N scheduler and GOMAXPROCS
- Knowing goroutines are scheduled in user space
- Mentioning channels or WaitGroups for coordination
Common Mistakes
- Saying a goroutine is the same as an OS thread
- Claiming each goroutine gets its own OS thread
- Forgetting the main goroutine can exit before others finish
- Ignoring GOMAXPROCS and the runtime scheduler
- Assuming goroutines run truly in parallel regardless of CPU cores
Best Answer (HR Friendly)
“A goroutine is Go's way of running a task in the background, and it is far cheaper than a traditional operating-system thread. Go can run hundreds of thousands of them at once because its own scheduler shares them across a few real threads, which is why Go handles heavy concurrent workloads so well.”
Code Example
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Println("goroutine", id)
}(i)
}
wg.Wait()
}Follow-up Questions
- What does GOMAXPROCS control?
- How do you wait for goroutines to finish?
- What is a goroutine leak and how do you avoid it?
- How does Go's scheduler decide when to switch goroutines?
- What is the difference between concurrency and parallelism in Go?
MCQ Practice
1. Roughly how much stack does a new goroutine start with?
Goroutines start with a small stack of a few KB that grows on demand, unlike threads which reserve about 1 MB.
2. Who schedules goroutines onto OS threads?
The Go runtime uses an M:N scheduler to multiplex many goroutines onto a few OS threads in user space.
3. Which keyword starts a goroutine?
Prefixing a function call with the go keyword runs it as a goroutine.
Flash Cards
What is a goroutine? — A lightweight function scheduled by the Go runtime, started with the go keyword.
Goroutine vs OS thread stack size? — Goroutine: a few KB that grows dynamically. OS thread: ~1 MB fixed.
What scheduling model does Go use? — M:N — many goroutines multiplexed onto a few OS threads in user space.
How do you wait for goroutines? — Use sync.WaitGroup or channels to coordinate completion.