The GMP model (Goroutines, OS threads, Processors) is Go's runtime scheduler that multiplexes goroutines onto OS threads using work-stealing, enabling massive concurrency with minimal overhead.
G (Goroutine): the unit of work with its own stack and state
M (Machine/OS thread): the entity that actually executes code on the CPU
P (Processor): a logical processor with a local run queue, limited by GOMAXPROCS
Each P can run one G at a time on one M — GOMAXPROCS controls parallelism, not concurrency
Global run queue: overflow queue when local P queues are full
Work stealing: idle P steals goroutines from busy P's local queue — automatic load balancing
Preemption: goroutines are preempted at function calls and loop back-edges (Go 1.14+) — no starvation
Blocking syscall: when G blocks on a syscall, P detaches from M and attaches to a new M so other goroutines keep running
Network I/O: Go's netpoller parks goroutines awaiting I/O without blocking an OS thread
If you launch 1000 goroutines that each perform a quick CPU‑bound calculation, how many OS threads do you expect Go to use by default, and why?
What happens if you call runtime.GOMAXPROCS(1) in a program that spawns many goroutines? How does that affect scheduling?
When a goroutine blocks on a channel send, what does the Go scheduler do with its underlying M?
You notice a latency spike in a service that uses a worker pool of goroutines processing requests. How would you investigate whether the GMP scheduler is a bottleneck?
Explain why increasing GOMAXPROCS sometimes doesn't improve throughput in a Go microservice, and what scheduler behavior you would look at.
During a load test, you see many goroutines stuck in 'syscall' state. How does the scheduler handle syscalls, and what changes could you make to mitigate the issue?
Design a high‑throughput pipeline that mixes CPU‑bound and I/O‑bound stages. How would you configure GOMAXPROCS and possibly use runtime.LockOSThread to influence the GMP scheduler for optimal performance?
When migrating a legacy C++ service to Go, you need to preserve its thread‑affinity guarantees. How would you work with the GMP scheduler to ensure certain goroutines stay on specific OS threads?
Explain the trade‑offs of using many short‑lived goroutines versus a fixed pool of workers in a system that must handle millions of concurrent connections, considering the scheduler’s work‑stealing and P‑local runqueues.
At a company‑wide level, you are deciding whether to adopt Go for a new distributed system that requires strict real‑time latency. How would the GMP scheduler influence that decision, and what architectural mitigations would you propose?
Your organization has multiple services written in Go that share a common library which spawns background goroutines. Over time, you observe increased CPU contention. How would you redesign the library or runtime configuration to reduce scheduler contention across services?
If you need to run Go services on a heterogeneous cluster where some nodes have many cores and others have few, how would you design a deployment strategy that adapts GOMAXPROCS and leverages the scheduler to maintain consistent performance?