Go runtime internals
Goroutines, the M:P:G scheduler, channels, the memory model, the garbage collector, escape analysis, interfaces, generics, the runtime package, the network poller. Ten mechanisms that decide how Go programs actually behave at runtime. Each sub-page below works through one of them at the level of "what's the data structure, what's the algorithm, and what does it mean for the code you write".
Ten sub-pages. Each is a long-form walkthrough with runtime source links and references — the runtime/ source tree, the memory model spec, talks from the maintainers.
The thirteen mechanisms
Goroutines
What a goroutine actually is — a stackful coroutine, 2KB initial stack, segmented growth, parked on G-queues. Why `go f()` is cheaper than a thread but still not free.
M:P:G scheduler
The scheduler in three letters — M (OS thread), P (logical processor, GOMAXPROCS), G (goroutine). Local run queues, work stealing, hand-off, syscall blocking. The thing that makes goroutines fast.
Channels
How `chan` is implemented — a circular buffer, a sendq, a recvq, a mutex. Why a buffered channel of capacity 1 is not the same as an atomic, and what `select` actually compiles to.
Memory model
The Go memory model in plain words — happens-before, synchronization rules, what `sync/atomic` does and what it doesn't. The rules that let you reason about concurrent code.
Garbage collection
Tri-color mark-and-sweep, write barriers, GC pacing, the pacer's targets. Why the GC stop-the-world is sub-millisecond and how to actually read GODEBUG=gctrace=1.
Escape analysis
When does a value escape to the heap and when does it stay on the stack? The compiler's rules, the `-gcflags=-m` flag, and the patterns that keep allocations down.
Interfaces & dynamic dispatch
How an interface value is laid out — an itab pointer plus a data pointer. Why type assertions are cheap, why interface conversions allocate, and how generics changed the calculus.
Generics & type parameters
GC-shape stenciling, the dictionary, why `T constraints.Ordered` compiles fast and why type-set constraints don't blow up the binary. What 1.18 actually shipped and what's coming.
The runtime package
GOMAXPROCS, NumGoroutine, Stack, ReadMemStats, SetFinalizer, the unsafe corners. The bits of the standard library that talk directly to the scheduler and the heap.
Network poller
How net/http does a million open connections on a handful of OS threads — netpoll, the runtime poller, epoll/kqueue/IOCP under the hood, goroutine-per-connection done right.
Cgo
How Go calls into C and what every crossing costs. The cgo preamble, runtime.cgocall, the stack switch, the ~200 ns overhead, when batching at the boundary matters, and when cgo is the wrong tool.
Sync primitives
sync.Mutex's spin-then-park, the 1 ms starvation-mode threshold, RWMutex's reader counter, the sync.Once double-check, sync.Map's read/dirty split, and when sync/atomic is enough on its own.
Reflection
How reflect.Type and reflect.Value wrap the runtime type descriptors. Why every reflect call allocates, what TypeOf and ValueOf actually read, the cached-encoder pattern, and what generics replaced.