Go 1.26 Interview: Green Tea GC, go fix and Stack Optimizations
Prepare for Go 1.26 interview questions covering the Green Tea garbage collector, revamped go fix tool, stack allocation optimizations, and key performance improvements.

Go 1.26, released in February 2026, ships the Green Tea garbage collector as the default GC, a fully revamped go fix tool, and significant stack allocation optimizations. These changes represent some of the most impactful runtime improvements in recent Go releases, and interviewers increasingly test candidates on them.
The three headline features: Green Tea GC (10-40% GC overhead reduction), revamped go fix with modernizers, and stack-allocated slice backing stores. All three require zero code changes to benefit from.
What is the Green Tea garbage collector in Go 1.26?
Expected answer: Green Tea is the new default garbage collector in Go 1.26, replacing the previous tri-color concurrent collector's scanning strategy. Instead of scanning individual objects scattered across the heap (pointer-chasing), Green Tea scans entire 8 KiB memory pages. This contiguous memory access pattern allows CPU prefetching to work effectively, resulting in 10-40% reduction in GC overhead for real-world programs.
On modern CPUs (Intel Ice Lake or AMD Zen 4 and newer), the GC leverages SIMD vector instructions for scanning small objects, adding roughly 10% more improvement.
Follow-up question: How does Green Tea improve CPU cache behavior during garbage collection?
The previous GC followed object pointers across the heap, causing frequent cache misses. Green Tea instead processes objects page-by-page in contiguous 8 KiB blocks. The CPU prefetcher can predict sequential memory access patterns, keeping the L1/L2 caches warm. This locality improvement is the primary driver behind the 10-40% overhead reduction.
// Previous approach: follow pointers across heap
func scanObject(obj *mspan) {
for _, ptr := range obj.pointers {
markReachable(ptr) // cache miss likely
}
}
// Green Tea approach: scan contiguous pages
func scanPage(page *pageBlock) {
// Sequential 8 KiB scan - CPU prefetcher friendly
for offset := 0; offset < pageSize; offset += objSize {
scanSlot(page.base + offset) // cache hit likely
}
}Green Tea can be disabled with GOEXPERIMENT=nogreenteagc at build time, but this opt-out is expected to be removed in Go 1.27.
How does Go 1.26 optimize stack allocation for slices?
Expected answer: Go 1.26 extends stack allocation to slice backing stores during append-based accumulation. Previously, the first append call allocated a slice of length 1 on the heap, then 2, then 4, then 8 (standard doubling). Go 1.26 allocates a small stack-based backing store before the loop begins, so the first several appends use the stack buffer with zero heap involvement.
func collectTasks(items []Item) []Task {
var tasks []Task
// Before Go 1.26: first append allocates on heap (size 1, 2, 4...)
// Go 1.26: compiler inserts a stack-backed buffer
for _, item := range items {
if item.IsReady() {
tasks = append(tasks, item.ToTask())
// First ~4 appends use stack buffer, zero heap allocations
}
}
return tasks
// If slice escapes, runtime.move2heap() copies once at return
}Follow-up question: What happens when the slice escapes the function scope?
Even when the slice must escape to the heap (because the function returns it), Go 1.26 still uses the stack buffer during accumulation. The compiler inserts a runtime.move2heap() call that copies the final data to the heap exactly once at the return point. Instead of 3+ startup heap allocations (size 1, 2, 4...), the result is exactly 1 heap allocation at the end. This is actually better than hand-optimized pre-allocation in many cases because the copy only happens if the data was exclusively stack-backed up to the return point.
What changed in the go fix tool in Go 1.26?
Expected answer: The go fix tool has been completely rewritten as a home for Go modernizers. It provides a push-button way to update Go code bases to the latest idioms and core library APIs. The new go fix is built on the same analysis framework as go vet, meaning the same analyzers that provide diagnostics can now suggest and apply fixes.
Key characteristics of the new go fix:
- Dozens of fixers for modern Go idioms and APIs
- A source-level inliner activated by
//go:fix inlinedirectives - Guarantees zero behavior changes (safe for production code)
- Legacy obsolete fixers from the old tool have been removed
# Apply all modernizers to the current module
go fix ./...
# The tool automatically updates patterns like:
# - Old-style error wrapping to fmt.Errorf with %w
# - Deprecated API calls to their replacements
# - Legacy patterns to modern Go idiomsFollow-up question: How does //go:fix inline work?
The //go:fix inline directive marks a function or method as a candidate for source-level inlining by go fix. When go fix runs, it replaces call sites of the annotated function with its body. This is different from compiler inlining: it transforms source code, not generated machine code. Library authors use it to deprecate wrapper functions by inlining them into modern equivalents at the call site.
Explain the cgo performance improvement in Go 1.26
Expected answer: Go 1.26 reduces the baseline overhead of every cgo call by approximately 30%. The runtime achieved this by eliminating the _Psyscall processor state, an intermediate state that goroutines transitioned through during cgo calls. Removing this transitional state cuts the number of state transitions per cgo call, directly reducing latency.
This matters for applications that make frequent cgo calls, such as programs using C libraries for database drivers, image processing, or cryptographic operations. The improvement requires no code changes.
What are the language changes in Go 1.26?
Expected answer: Go 1.26 introduces two language changes:
1. Enhanced new() function: The built-in new function now accepts an expression as its operand, specifying the initial value of the variable. Previously, new(T) always returned a zero-valued *T.
type Config struct {
Timeout *int
MaxRetry *int
}
// Before Go 1.26: helper function needed
func intPtr(v int) *int { return &v }
func makeConfig() Config {
return Config{
Timeout: intPtr(30),
MaxRetry: intPtr(3),
}
}
// Go 1.26: direct initialization
func makeConfig() Config {
return Config{
Timeout: new(30), // *int pointing to 30
MaxRetry: new(3), // *int pointing to 3
}
}2. Self-referential generic types: Generic types can now reference themselves in type parameter constraints, enabling more advanced type abstraction patterns like F-bounded polymorphism.
type Adder[A Adder[A]] interface {
Add(A) A
}
type Vector2D struct{ X, Y float64 }
func (v Vector2D) Add(other Vector2D) Vector2D {
return Vector2D{v.X + other.X, v.Y + other.Y}
}
// The constraint ensures the return type matches the receiver type
func Sum[A Adder[A]](items []A) A {
var result A
for _, item := range items {
result = result.Add(item)
}
return result
}Ready to ace your Go interviews?
Practice with our interactive simulators, flashcards, and technical tests.
How does goroutine leak detection work in Go 1.26?
Expected answer: Go 1.26 introduces an experimental goroutineleak profile type in runtime/pprof. A leaked goroutine is one blocked on a concurrency primitive (channel, sync.Mutex, sync.Cond) that cannot possibly become unblocked. The runtime detects these leaks using the garbage collector: if goroutine G is blocked on primitive P, and P is unreachable from any runnable goroutine, then G can never wake up.
func processWorkItems(ws []workItem) ([]workResult, error) {
ch := make(chan result)
for _, w := range ws {
go func() {
res, err := processWorkItem(w)
ch <- result{res, err} // goroutine blocks here if early return
}()
}
for range len(ws) {
r := <-ch
if r.err != nil {
return nil, r.err // remaining goroutines leak
}
}
return results, nil
}
// Enable detection: GOEXPERIMENT=goroutineleakprofile
// Endpoint: /debug/pprof/goroutineleakThe detection leverages GC reachability analysis, so it catches a large class of leaks with no manual instrumentation. It is expected to be enabled by default in Go 1.27.
What security improvements does Go 1.26 introduce?
Expected answer: Two notable security improvements:
Heap base address randomization (64-bit platforms): The runtime now randomizes the heap base address at startup, making it harder for attackers to predict memory addresses when exploiting vulnerabilities through cgo. This is an ASLR-like defense for Go heap memory. It can be disabled with GOEXPERIMENT=norandomizedheapbase64.
Post-quantum cryptography enabled by default: TLS connections now use hybrid key exchange by default (SecP256r1MLKEM768, SecP384r1MLKEM1024), combining classical elliptic curve cryptography with ML-KEM (formerly CRYSTALS-Kyber) for quantum resistance. The crypto/mlkem package also got ~18% faster encapsulation/decapsulation.
Describe the standard library performance wins in Go 1.26
Expected answer: Several standard library functions received targeted optimizations:
| Function | Improvement | Detail |
|----------|------------|--------|
| fmt.Errorf (no format verbs) | ~92% faster | Unformatted calls now match errors.New performance |
| io.ReadAll | ~2x faster, 50% less memory | Uses exponential buffer growth instead of linear |
| crypto/mlkem | ~18% faster | Optimized encapsulation and decapsulation |
| image/jpeg | Faster, more accurate | New encoder/decoder implementation |
Additionally, bytes.Buffer gained a Peek() method, errors gained a generic AsType() function, and reflect gained iterator methods (Type.Fields(), Type.Methods(), Value.Fields()) aligned with Go's range-over-func pattern.
How would the new errors.AsType function simplify error handling?
Expected answer: errors.AsType[T]() is a generic alternative to errors.As(). It eliminates the need to declare a target variable before calling As, reducing boilerplate.
// Before Go 1.26: two-step process
var pathErr *os.PathError
if errors.As(err, &pathErr) {
log.Printf("path error on %s: %v", pathErr.Path, pathErr.Err)
}
// Go 1.26: single expression
if pathErr, ok := errors.AsType[*os.PathError](err); ok {
log.Printf("path error on %s: %v", pathErr.Path, pathErr.Err)
}The generic version is type-safe at compile time and reads more naturally in conditional chains.
Ready to ace your Go interviews?
Practice with our interactive simulators, flashcards, and technical tests.
Conclusion
- Green Tea GC scans 8 KiB memory pages instead of chasing pointers, delivering 10-40% GC overhead reduction with zero code changes
- Stack-allocated slice backing stores eliminate 3+ startup heap allocations during append loops, copying to heap only once at escape points
- The revamped
go fixtool applies dozens of modernizers built on thego vetanalysis framework, with guaranteed zero behavior changes new()now accepts expressions, removing the need for pointer helper functions- Self-referential generic type constraints enable F-bounded polymorphism patterns
- Goroutine leak detection (experimental) uses GC reachability to find permanently blocked goroutines
fmt.Errorfwithout format verbs is now 92% faster, andio.ReadAlluses 50% less memory- Post-quantum hybrid key exchange is enabled by default in TLS connections
Prepare for Go interview questions by understanding these runtime changes. The Go concurrency guide covers foundational goroutine patterns that complement the leak detection feature discussed here.
Start practicing!
Test your knowledge with our interview simulators and technical tests.
Tags
Share
Related articles

Top 25 Go Interview Questions: Complete Developer Guide
Ace your Go interviews with the 25 most asked questions. Master goroutines, channels, interfaces, concurrency patterns with practical code examples.

Go Technical Interview: Goroutines, Channels and Concurrency
Go interview questions on goroutines, channels, and concurrency patterns. Code examples, common pitfalls, and expert-level answers to prepare for Go technical interviews in 2026.

Go Concurrency: Goroutines and Channels - Complete Guide
Master Go concurrency with goroutines and channels. Advanced patterns, synchronization, select statements, and best practices with detailed code examples.