What is the fundamental difference between a goroutine and an OS thread?
This tests your grasp of Go's M:N scheduler. A strong answer notes that goroutines are runtime-managed, multiplexed onto OS threads, and use far less memory per unit, enabling thousands of concurrent tasks.
WHAT THIS TESTS: Whether you understand that goroutines are not simply wrappers around OS threads but a distinct concurrency primitive managed by the Go runtime. Interviewers want to see that you know the M:N multiplexing model, where many goroutines are scheduled onto a smaller number of OS threads, and that you can articulate why this matters for memory usage and scalability.
A GOOD ANSWER COVERS: First, the ownership model: OS threads are kernel-managed and scheduled by the operating system, while goroutines are user-space entities managed by the Go runtime scheduler. Second, the resource footprint: goroutines begin with small stacks that grow and shrink as needed, whereas OS threads typically reserve a large fixed stack region, so spawning thousands of threads quickly exhausts virtual memory. Third, context switching cost: the Go runtime switches goroutines in user space without trapping into kernel mode, which is faster than the full kernel context switch required for OS threads. Fourth, the practical impact: because goroutines are cheap to create and schedule, Go programs can spawn tens or hundreds of thousands of concurrent goroutines, but only a handful of OS threads, keeping CPU and memory overhead low.
COMMON WRONG ANSWERS: Claiming that goroutines are just green threads with no OS involvement at all; the runtime still uses OS threads as execution vehicles. Saying that goroutines always run in parallel on separate cores; concurrency is not parallelism, and the runtime multiplexes goroutines onto threads. Asserting that goroutines share nothing; they share memory in the same address space, and the programmer must synchronize access or use channels. Giving vague hand-waving about goroutines being faster without explaining the scheduler, stack model, or context switch differences.
LIKELY FOLLOW-UPS: How does the Go scheduler handle blocking syscalls? What happens when a goroutine blocks on I/O? How do channels interact with the scheduler? When would you still use sync.Mutex instead of channels? How does GOMAXPROCS affect goroutine execution?
ONE CONCRETE EXAMPLE: Imagine a web server handling ten thousand open connections. With OS threads, each connection might consume megabytes of reserved stack space, causing the process to use tens of gigabytes of virtual memory and forcing the kernel to thrash scheduling thousands of threads. With goroutines, the same server spawns one goroutine per connection; the runtime maps them onto perhaps as many OS threads as CPU cores, each goroutine using only a few kilobytes of stack initially. The result is that the server scales to tens of thousands of concurrent connections within a few hundred megabytes of memory.
Read the original → go.dev
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.