What is the difference between a goroutine and an OS thread?
go-jun-001
Your answer
Answer as you would in a real interview — explain your thinking, not just the conclusion.
Model answer
OS threads are scheduled by the kernel with a fixed stack of 1–8 MB each, making it expensive to spawn thousands. Goroutines are multiplexed onto OS threads by the Go runtime using M:N scheduling. A goroutine starts with a 2 KB growable stack, so you can run millions simultaneously with minimal overhead. The Go scheduler is cooperatively and preemptively scheduled: it switches goroutines at function calls, channel operations, and system calls without OS involvement. When a goroutine blocks on a syscall, the scheduler parks it and runs another goroutine on the same thread — no thread is wasted waiting. This is why Go concurrency is cheap and idiomatic: spawn a goroutine per request, not a thread.
Code example
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
// Spawn 100 goroutines — cheap, ~2KB stack each
for i := 0; i < 100; i++ {
wg.Add(1)
go func(n int) {
defer wg.Done()
fmt.Println("goroutine", n)
}(i)
}
wg.Wait()
}
Follow-up
How does GOMAXPROCS affect goroutine scheduling, and what is its default value in modern Go?