DevPrep
  • Interview Prep
  • Projects
  • Resources
  • Pricing
  • About Us
Submit Question
DevPrep
  • Pricing
  • About Us
Submit Question

Practice

  • JavaScript
  • DSA
  • Machine Coding
  • System Design

Resources

  • Learning Tracks
  • Articles
  • Roadmaps
  • Compare Concepts
  • Glossary
  • Developer Tools
  • All Questions

Company

  • About
  • Pricing

Legal

  • Privacy Policy
  • Terms of Service
DevPrep

© 2026 DevPrep. All rights reserved.

← Back to Questions
HardTheory

Explain the Go Scheduler: G, M, P Model

28 views

Problem Statement

In a Principal Engineer interview at Google, you're asked: "Explain how Go can run millions of goroutines on a few OS threads. What is the GMP model and how does work stealing improve performance?"

The GMP Model

  • G (Goroutine): User-space thread, starts at 2KB stack, grows dynamically
  • M (Machine): OS thread, executes goroutines
  • P (Processor): Logical processor, holds the run queue

Visual Representation


┌─────────────────────────────────────────────────────────┐
│                     Go Runtime                          │
├─────────────────────────────────────────────────────────┤
│                                                         │
│   ┌─────┐  ┌─────┐  ┌─────┐  ┌─────┐                  │
│   │  G  │  │  G  │  │  G  │  │  G  │  Global Run Q    │
│   └──┬──┘  └──┬──┘  └──┬──┘  └──┬──┘                  │
│      │       │       │       │                         │
│   ┌──▼───────▼───────▼───────▼──┐                      │
│   │         P (Processor)        │                      │
│   │  ┌───┐ ┌───┐ ┌───┐ ┌───┐   │  Local Run Queue    │
│   │  │ G │ │ G │ │ G │ │ G │   │                      │
│   │  └───┘ └───┘ └───┘ └───┘   │                      │
│   └──────────────┬──────────────┘                      │
│                  │                                      │
│   ┌──────────────▼──────────────┐                      │
│   │       M (OS Thread)          │                      │
│   │    Executing Goroutine       │                      │
│   └─────────────────────────────┘                      │
│                                                         │
└─────────────────────────────────────────────────────────┘

Key Scheduler Events

EventWhat Happens
Goroutine blocks (I/O, channel)M releases P, P picks another G
Goroutine syscallM blocks with G, new M takes P
P run queue emptyWork stealing from other Ps
Goroutine runs too long (>10ms)Preempted, put back in queue

Debugging with GODEBUG

# See scheduler decisions in real-time
GODEBUG=schedtrace=1000 ./myapp

# Output every 1000ms:
# SCHED 1000ms: gomaxprocs=8 idleprocs=6 threads=10 
#               spinningthreads=1 idlethreads=3 runqueue=0 [0 0 0 0 0 0 0 0]

Work Stealing Algorithm

// Simplified pseudocode of work stealing
func findRunnable() *g {
    // 1. Check local run queue
    if g := runqget(_p_); g != nil {
        return g
    }
    
    // 2. Check global run queue
    if g := globrunqget(_p_); g != nil {
        return g
    }
    
    // 3. Steal from other Ps (random selection)
    for i := 0; i < 4; i++ {
        victim := randomP()
        if g := runqsteal(_p_, victim); g != nil {
            return g
        }
    }
    
    return nil // No work found
}

GOMAXPROCS

import "runtime"

func main() {
    // Set number of Ps (defaults to NumCPU)
    runtime.GOMAXPROCS(4)
    
    // Check current value
    fmt.Println("GOMAXPROCS:", runtime.GOMAXPROCS(0))
    fmt.Println("NumCPU:", runtime.NumCPU())
    fmt.Println("NumGoroutine:", runtime.NumGoroutine())
}

Follow-up Questions

  1. What happens when a goroutine makes a blocking syscall?
  2. How does Go 1.14+ achieve asynchronous preemption?
  3. Why doesn't increasing GOMAXPROCS beyond NumCPU help CPU-bound work?

Sample Test Cases

Case 1
Input
GOMAXPROCS=4, goroutines=100
Expected Output
100 Gs distributed across 4 Ps
Case 2
Input
goroutine blocks on syscall
Expected Output
M detaches from P, new M created

No solutions yet

Be the first to share a solution for this question.

Comments (0)

Sign in to leave a comment.

No comments yet. Be the first to comment.

Stats

Views
28
Likes
0
Solutions
0
Comments
0

Category

Backend Engineering