Goroutines

Understand Go's lightweight runtime-scheduled tasks, M:N scheduling, and their relationship to OS threads.

In this article

A goroutine is a lightweight task managed by the Go runtime. Go's HTTP server can start one goroutine per request because a goroutine uses a small, growing stack instead of a full OS thread stack.

Fig 1Many goroutines share execution capacity
STUDY MODEL
Inspect one part at a timeGoroutines
  1. Goroutines

    G1, G2, G3, and G4 are lightweight scheduled work.

  2. Scheduler

    The Go scheduler assigns runnable goroutines to available execution capacity.

  3. OS threads

    Thread 1 and Thread 2 illustrate shared execution resources, not a universal thread count.

  4. Channels

    Channels coordinate communication. They are not an automatic cure for all shared-state races.

Goroutines are scheduled by the Go runtime; one goroutine is not one OS thread.

How to read this model

A task magazine feeding two scheduler carriages. The object is a teaching analogy. Inspecting a part highlights its role; it does not execute or simulate the software. Cabinet trays are records, workpieces are data, and latches are checks. Unless an explanation states a quantity, compartments and sample workpieces do not denote data counts. Part dimensions are not a quantitative scale.

## Follow the M:N scheduler

Go schedules many goroutines, called G, onto a smaller set of OS threads, called M. Logical processors, called P, determine how many goroutines can execute Go code in parallel. GOMAXPROCS controls that count. The runtime may create additional OS threads when a thread blocks in a system call or cgo.

many goroutines (G) -> logical processors (P) -> OS threads (M)

When one goroutine waits on I/O, the runtime can pause it and run another goroutine on the available thread. A runtime switch avoids much of the kernel work required for an OS context switch. With multiple logical processors, goroutines also run in parallel.

Compare the models

Model Managed by Per-task cost Parallelism
OS thread Kernel High stack and context-switch cost Yes, across cores
Event loop Runtime on one thread Very low No, unless workers are added
Goroutine Go runtime Very low, growing stack Yes, across cores

Goroutines combine synchronous-looking code with cheap runtime scheduling. That does not remove the need for cancellation, bounded work, or synchronization. A goroutine leak still consumes memory, and shared mutable state can still race.

Java virtual threads use the same broad idea: lightweight runtime-scheduled threads mapped onto a smaller set of OS threads. The exact scheduling and blocking behavior remains runtime-specific.

Read race conditions before sharing state between goroutines.

Keep track of your reading.

Your reading progress stays in this browser.