<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/how-go-s-green-tea-garbage-collector-handles-memory-layout-and-cache-performance-dtrkefcyh" -->

---
title: How Go&#x27;s Green Tea garbage collector handles memory...
description: Go 1.26 made Green Tea the default garbage collector. The new GC improves cache performance by allocating objects into contiguous spans grouped by size class,...
canonical: https://daily.dev/posts/how-go-s-green-tea-garbage-collector-handles-memory-layout-and-cache-performance-dtrkefcyh
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: How Go&#x27;s Green Tea garbage collector handles memory layout and cache performance | daily.dev
og:description: Go 1.26 made Green Tea the default garbage collector. The new GC improves cache performance by allocating objects into contiguous spans grouped by size class,...
og:url: https://daily.dev/posts/how-go-s-green-tea-garbage-collector-handles-memory-layout-and-cache-performance-dtrkefcyh
og:image: https://api.daily.dev/og/posts/dtRKEFCyH.png
og:image:alt: How Go&#x27;s Green Tea garbage collector handles memory layout and cache performance
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# How Go's Green Tea garbage collector handles memory layout and cache performance

**[Collections](https://daily.dev/sources/collections)** · 3 min read · 3 upvotes · 0 comments

## Summary

Go 1.26 made Green Tea the default garbage collector. The new GC improves cache performance by allocating objects into contiguous spans grouped by size class, measurably reducing L1 and L3 cache miss rates. However, Go's non-moving collector has a significant limitation: freeing most objects doesn't shrink the heap footprint because a single surviving object pins an entire span. Unlike C#'s compacting GC, Go won't return memory to the OS automatically after spiky allocation bursts. Manual copy-compaction is a workaround but impractical for routine use. Green Tea is a genuine win for cache-sensitive workloads, but memory-sensitive deployments on shared infrastructure should be aware that RSS won't shrink as expected after allocation spikes.

## Content

Go 1.26 made Green Tea the default garbage collector. Here's what that actually means in practice, measured on bare-metal hardware.

## How Green Tea works

The core change is how the collector scans for live objects. The old approach tracked individual pointers. Green Tea switches to span-based scanning: objects of similar sizes are grouped into contiguous spans, and the collector walks those spans rather than chasing scattered pointers across the heap.

This matters because pointer chasing is brutal for CPU caches. When objects are packed together, the prefetcher can do its job. When they're scattered, every pointer dereference is potentially a cache miss.

## What the numbers look like

Using `perf` to measure L1 cache behavior on two workloads - one with packed pointer graphs, one with scattered allocations:

- Scattered layout: 31.57 L1 MPKI (misses per kilo-instruction), runtime 11.44 seconds
- After Green Tea: 14.06 L1 MPKI, runtime 7.01 seconds

That's a meaningful improvement. The span-based approach keeps related objects closer together in memory, which the hardware cache hierarchy rewards.

## The non-moving collector problem

Here's where things get interesting, and a little uncomfortable. Go's GC doesn't move objects. Once something is allocated at an address, it stays there.

The practical consequence: if you free 90% of your objects, the heap spans those objects lived in don't get reclaimed. In testing, freeing 90% of objects left span count at 463 versus the original 464. `HeapInuse` barely moved.

The memory is technically free in the sense that Go knows those slots are available for new allocations. But the virtual memory footprint stays pinned. If your process had a large heap and then shed most of its load, the OS won't see that reflected in RSS for a long time, if ever.

## How this compares to C#

C#'s GC is compacting. After collection, it moves surviving objects together, updates all the references, and releases the now-empty pages back. The heap actually shrinks.

Go's heap layout is also different at the allocation level. Go groups objects by size class into contiguous spans, which is visible when you visualize the heap directly. C# uses a generational model with different heap regions. Neither approach is strictly better - they involve different tradeoffs around pause times, throughput, and memory overhead.

## The workaround

For Go programs that need to actually reclaim memory after shedding load, there's a manual copy-compaction approach: allocate new objects, copy data over, drop references to the old ones, and let the GC collect the now-unreachable originals. It works, but it's opt-in and requires you to know you need it.

Green Tea is a real improvement for cache behavior and throughput. The non-moving limitation is a known constraint of Go's design, not something Green Tea changes. Worth understanding both sides before assuming the new GC solves all your memory problems.

## Similar posts on daily.dev

- [Go 1.26 turned on a new garbage collector. Whether it helps you depends on how your heap is shaped.](https://daily.dev/posts/go-1-26-turned-on-a-new-garbage-collector-whether-it-helps-you-depends-on-how-your-heap-is-shaped--4agvnc3q3) · Medium · 8 upvotes · 0 comments
- [Go's New Green Tea Garbage Collector May Improve Performance up to 40%](https://daily.dev/posts/go-s-new-green-tea-garbage-collector-may-improve-performance-up-to-40--8lrm23smt) · InfoQ · 3 upvotes · 0 comments

---

Tags: [#golang](https://daily.dev/tags/golang)

[View this post on daily.dev](https://daily.dev/posts/how-go-s-green-tea-garbage-collector-handles-memory-layout-and-cache-performance-dtrkefcyh)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"How Go's Green Tea garbage collector handles memory layout and cache performance","url":"https://daily.dev/posts/how-go-s-green-tea-garbage-collector-handles-memory-layout-and-cache-performance-dtrkefcyh","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/how-go-s-green-tea-garbage-collector-handles-memory-layout-and-cache-performance-dtrkefcyh"},"datePublished":"2026-07-25T08:15:35.330Z","dateModified":"2026-07-27T19:39:33.619Z","description":"Go 1.26 made Green Tea the default garbage collector. The new GC improves cache performance by allocating objects into contiguous spans grouped by size class,...","image":"https://theconsensus.dev/static/observing-gos-garbage-collector-old-and-new.avif","thumbnailUrl":"https://theconsensus.dev/static/observing-gos-garbage-collector-old-and-new.avif","isAccessibleForFree":true,"articleSection":"Collections","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Collections","logo":"https://media.daily.dev/image/upload/s--fk_6ycEi--/f_auto,q_auto/v1780996001/logos/collections?_a=BAMAMiWQ0","url":"https://daily.dev/sources/collections"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/how-go-s-green-tea-garbage-collector-handles-memory-layout-and-cache-performance-dtrkefcyh","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":3},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"golang","timeRequired":"PT3M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Collections","item":"https://daily.dev/sources/collections"},{"@type":"ListItem","position":3,"name":"How Go's Green Tea garbage collector handles memory layout and cache performance"}]}
```

