<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Alexander Obregon's Substack: Golang]]></title><description><![CDATA[All my Go content is here, covering practical examples, code, mechanics, and ideas written in Go.]]></description><link>https://alexanderobregon.substack.com/s/golang</link><image><url>https://substackcdn.com/image/fetch/$s_!4Mj9!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Falexanderobregon.substack.com%2Fimg%2Fsubstack.png</url><title>Alexander Obregon&apos;s Substack: Golang</title><link>https://alexanderobregon.substack.com/s/golang</link></image><generator>Substack</generator><lastBuildDate>Wed, 06 May 2026 01:43:17 GMT</lastBuildDate><atom:link href="https://alexanderobregon.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Alexander Obregon]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[alexanderobregon@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[alexanderobregon@substack.com]]></itunes:email><itunes:name><![CDATA[Alexander Obregon]]></itunes:name></itunes:owner><itunes:author><![CDATA[Alexander Obregon]]></itunes:author><googleplay:owner><![CDATA[alexanderobregon@substack.com]]></googleplay:owner><googleplay:email><![CDATA[alexanderobregon@substack.com]]></googleplay:email><googleplay:author><![CDATA[Alexander Obregon]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Algorithms That Work Well with Go's Mechanics]]></title><description><![CDATA[A lot of people choose Go because it already comes with the building blocks you reach for during algorithm work.]]></description><link>https://alexanderobregon.substack.com/p/algorithms-that-work-well-with-gos</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/algorithms-that-work-well-with-gos</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Fri, 20 Feb 2026 19:04:46 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/65f2a1bc-28cc-46ba-851f-a61c0130c876_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lh0H!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5e8d206-f869-4965-b137-d78f2d80497d_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lh0H!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5e8d206-f869-4965-b137-d78f2d80497d_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!lh0H!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5e8d206-f869-4965-b137-d78f2d80497d_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!lh0H!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5e8d206-f869-4965-b137-d78f2d80497d_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!lh0H!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5e8d206-f869-4965-b137-d78f2d80497d_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lh0H!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5e8d206-f869-4965-b137-d78f2d80497d_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f5e8d206-f869-4965-b137-d78f2d80497d_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lh0H!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5e8d206-f869-4965-b137-d78f2d80497d_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!lh0H!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5e8d206-f869-4965-b137-d78f2d80497d_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!lh0H!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5e8d206-f869-4965-b137-d78f2d80497d_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!lh0H!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5e8d206-f869-4965-b137-d78f2d80497d_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>A lot of people choose Go because it already comes with the building blocks you reach for during algorithm work. You see that in heaps for priority queues, generic helpers for slices and maps, and concurrency tools that make coordination part of the language. Today we are going to walk through some algorithm families that fit Go particularly well, starting with what the standard library gives you, then tying those tools to the problems they solve and the tradeoffs that come with them.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>Standard Library Building Blocks That Map to Algorithms</h3><p>You can stay in the standard library for most of the reusable areas that show up in algorithm work. Heaps give a priority queue, the <code>slices</code> package covers sorting plus binary search with generics, and maps cover fast membership checks plus counting. With those parts in place, the algorithm logic stays focused on the loop and the state you track, not on rewriting helpers.</p><h4>Priority Queues with container heap</h4><p>Priority queues fit work where the next item is chosen by rank, not by arrival order. Scheduling, best first search, top K selection, and shortest path loops all fall into that category. The <code>container/heap</code> package supplies the heap operations, and you provide a small type that satisfies <code>heap.Interface</code>. Ordering comes from <code>Less</code>. <code>heap.Pop</code> removes the element that <code>Less</code> treats as smallest, so a max priority queue flips the comparison so higher numeric priority comes out first.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;go&quot;,&quot;nodeId&quot;:&quot;924405bf-c37b-46a2-81b8-de8eedec85d5&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-go">package main

import (
 &#8220;container/heap&#8221;
 &#8220;fmt&#8221;
)

type WorkItem struct {
 Name     string
 Priority int
 index    int
}

type WorkPQ []*WorkItem

func (pq WorkPQ) Len() int { return len(pq) }
func (pq WorkPQ) Less(i, j int) bool {
 return pq[i].Priority &gt; pq[j].Priority
}
func (pq WorkPQ) Swap(i, j int) {
 pq[i], pq[j] = pq[j], pq[i]
 pq[i].index = i
 pq[j].index = j
}

func (pq *WorkPQ) Push(x any) {
 it := x.(*WorkItem)
 it.index = len(*pq)
 *pq = append(*pq, it)
}

func (pq *WorkPQ) Pop() any {
 old := *pq
 n := len(old)
 it := old[n-1]
 old[n-1] = nil
 it.index = -1
 *pq = old[:n-1]
 return it
}

func main() {
 pq := &amp;WorkPQ{}
 heap.Init(pq)

 heap.Push(pq, &amp;WorkItem{Name: &#8220;Alex sync invoices&#8221;, Priority: 3})
 heap.Push(pq, &amp;WorkItem{Name: &#8220;Kaitlyn rotate logs&#8221;, Priority: 1})
 heap.Push(pq, &amp;WorkItem{Name: &#8220;Pippin index search&#8221;, Priority: 4})

 for pq.Len() &gt; 0 {
  it := heap.Pop(pq).(*WorkItem)
  fmt.Println(it.Priority, it.Name)
 }
}</code></pre></div><p>Time and space behavior stays consistent across heap-backed algorithms. Each <code>heap.Push</code> and <code>heap.Pop</code> runs in O(log n) time, where n is the number of items currently in the queue. Space is O(n) to store the items.</p><p>Distance updates in Dijkstra style loops bring <code>heap.Fix</code> into play. <code>Fix</code> restores heap order after a priority change, and it also runs in O(log n). That is why the index field is practical, because it points <code>Fix</code> at the right slot without searching.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;go&quot;,&quot;nodeId&quot;:&quot;23b5a10b-e034-4e8a-b7e0-039f189997b4&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-go">func (pq *WorkPQ) UpdatePriority(it *WorkItem, newPriority int) {
 it.Priority = newPriority
 heap.Fix(pq, it.index)
}</code></pre></div><h4>Sorting plus Binary Search with slices Helpers</h4><p>A lot of algorithm steps start with ordering data so later passes become quicker. Sorting also sets you up for binary search, dedup passes, interval merges, and two-pointer scans.</p><p>The <code>slices</code> package adds generic helpers such as <code>Sort</code>, <code>SortFunc</code>, <code>BinarySearch</code>, and <code>BinarySearchFunc</code>. Those helpers keep the code type safe without writing conversions or comparator boilerplate. Sorting structs works well with <code>slices.SortFunc</code>. The comparison function returns a negative value when the first element should come first, zero for a tie, and a positive value when it should come after.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;go&quot;,&quot;nodeId&quot;:&quot;2d759d36-64a8-43e6-90a1-b90f00999cfc&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-go">package main

import (
 "cmp"
 "fmt"
 "slices"
)

type Route struct {
 City     string
 Distance int
}

func main() {
 routes := []Route{
  {City: "Eau Claire", Distance: 92},
  {City: "Madison", Distance: 201},
  {City: "Duluth", Distance: 162},
  {City: "Milwaukee", Distance: 246},
 }

 slices.SortFunc(routes, func(a, b Route) int {
  return cmp.Compare(a.Distance, b.Distance)
 })

 fmt.Println(routes)
}</code></pre></div><p>Sorting runs in O(n log n) time for n elements. Extra space depends on the implementation of the sorting routine, so treat the auxiliary space bound as implementation dependent.</p><p>Binary search builds on sorted data. <code>slices.BinarySearch</code> returns an index plus a boolean. If the value is missing, the index returned is the insertion position that keeps the slice sorted, which is useful for ordered tables where inserts happen occasionally but lookups happen frequently.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;go&quot;,&quot;nodeId&quot;:&quot;508babcc-d9a3-42e0-9b82-b59d2f637f30&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-go">package main

import (
 "fmt"
 "slices"
)

func main() {
 limits := []int{5, 9, 12, 18, 27}
 pos, found := slices.BinarySearch(limits, 12)
 fmt.Println(pos, found)

 insertAt, ok := slices.BinarySearch(limits, 10)
 fmt.Println(insertAt, ok)
}</code></pre></div><p>Binary search runs in O(log n) time and O(1) extra space. The sorted slice itself still costs O(n) space, but that is the input storage rather than extra memory created by the search.</p><h4>Partitioning plus Window Scans on Slices</h4><p>Sorting gives total order, but plenty of problems only need a split or a rolling scan.</p><p>Partitioning rearranges elements so everything matching a rule lands on the left side and the rest lands on the right side. Quickselect style selection relies on that because it can place the Kth element into its final position without sorting the entire slice. The mechanics come down to two indices. One index reads across the slice. Another index tracks where the next accepted value should land, swapping values into place.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;go&quot;,&quot;nodeId&quot;:&quot;929bec55-392b-4bef-8b2a-c2970541b992&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-go">package main

import "fmt"

// Returns the first index of the right side where values are &gt;= pivot.
func PartitionByPivot(nums []int, pivot int) int {
 write := 0
 for read := 0; read &lt; len(nums); read++ {
  if nums[read] &lt; pivot {
   nums[write], nums[read] = nums[read], nums[write]
   write++
  }
 }
 return write
}

func main() {
 nums := []int{19, 4, 11, 25, 7, 3, 16}
 split := PartitionByPivot(nums, 12)
 fmt.Println(nums)
 fmt.Println(split)
}</code></pre></div><p>Partition runs in O(n) time and needs O(1) extra space because it rearranges elements in place. That makes it good when memory pressure matters and full sorting would be extra work.</p><p>Window scans deal with a moving range across a slice. Rolling sums, recent event counts, and rate checks can all be written as a scan where you adjust state as the window advances. Two indices track the window edges, and the state updates as each edge moves.</p><p>A fixed-size sum window is a good starting point because the update rule is direct. Start by summing the first window. Then slide right by one element at a time, subtracting the element that leaves the window and adding the element that enters.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;go&quot;,&quot;nodeId&quot;:&quot;79a28d1e-af21-4732-9594-17f084d75bfa&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-go">package main

import "fmt"

func RollingSums(nums []int, window int) []int {
 if window &lt;= 0 || window &gt; len(nums) {
  return nil
 }

 out := make([]int, 0, len(nums)-window+1)
 sum := 0
 for i := 0; i &lt; window; i++ {
  sum += nums[i]
 }
 out = append(out, sum)

 for right := window; right &lt; len(nums); right++ {
  left := right - window
  sum -= nums[left]
  sum += nums[right]
  out = append(out, sum)
 }
 return out
}

func main() {
 nums := []int{2, 6, 3, 8, 1, 9, 4}
 fmt.Println(RollingSums(nums, 3))
}</code></pre></div><p>Rolling sums run in O(n) time and need O(1) extra space for the running sum. The returned output slice costs O(n) space relative to the number of windows produced.</p><p>With long-lived slices, a small sub-slice can keep a large backing array alive if that sub-slice is stored for a long time. When a window needs to live beyond the larger buffer, copying the window into a new slice drops the reference to the larger backing array.</p><h4>Graph Traversal with Slice Queues and Stacks</h4><p>Traversal work in Go stays readable when you keep the state in slices and keep the control flow in loops. BFS works with a queue, and a slice does that job well when you append on the right and advance a <code>head</code> index. DFS works with a stack, and a slice handles that too when you <code>append</code> and then pop from the end.</p><p>BFS is a good fit when you want the fewest edges between two nodes, so the first time you reach the target, you already have the shortest hop count. <code>dist</code> is the whole story there. <code>-1</code> means unseen, and <code>dist[nb] = dist[v] + 1</code> builds the hop count as the queue expands outward.</p><p>DFS is the version that answers reachability with minimal bookkeeping. <code>seen</code> stops revisits. The stack keeps the next nodes to expand, and the loop keeps running until the stack is empty or the target shows up.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;go&quot;,&quot;nodeId&quot;:&quot;13e32c5f-045a-4d8c-9d44-8fc5e88752df&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-go">package main

import "fmt"

func BFSShortestHops(graph [][]int, start, target int) int {
 n := len(graph)
 if start == target {
  return 0
 }

 dist := make([]int, n)
 for i := range dist {
  dist[i] = -1
 }

 q := make([]int, 0, n)
 head := 0

 dist[start] = 0
 q = append(q, start)

 for head &lt; len(q) {
  v := q[head]
  head++

  for _, nb := range graph[v] {
   if dist[nb] != -1 {
    continue
   }
   dist[nb] = dist[v] + 1
   if nb == target {
    return dist[nb]
   }
   q = append(q, nb)
  }
 }

 return -1
}

func DFSReachable(graph [][]int, start, target int) bool {
 n := len(graph)
 seen := make([]bool, n)

 stack := make([]int, 0, n)
 stack = append(stack, start)

 for len(stack) &gt; 0 {
  v := stack[len(stack)-1]
  stack = stack[:len(stack)-1]

  if seen[v] {
   continue
  }
  seen[v] = true

  if v == target {
   return true
  }

  for _, nb := range graph[v] {
   if !seen[nb] {
    stack = append(stack, nb)
   }
  }
 }

 return false
}

func main() {
 // 0 -&gt; 1,2   1 -&gt; 3   2 -&gt; 3,4   3 -&gt; 5   4 -&gt; 5
 graph := [][]int{
  {1, 2},
  {3},
  {3, 4},
  {5},
  {5},
  {},
 }

 fmt.Println(BFSShortestHops(graph, 0, 5))
 fmt.Println(DFSReachable(graph, 0, 5))
}</code></pre></div><p>BFS time is O(V + E) and space is O(V) for <code>dist</code> plus the queue storage. DFS time is O(V + E) and space is O(V) for <code>seen</code> plus the stack. The practical win is how directly slices map to queue and stack behavior through <code>append</code> and slicing.</p><h4>Dynamic Programming with Rolling Slices</h4><p>DP work pairs nicely with Go when the state can live in a <code>[]int</code> and each step updates a small neighborhood of previous results. When a recurrence only depends on a short trailing range, a rolling window keeps the memory footprint tiny while staying easy to trace.</p><p>This next example counts ways to reach exactly <code>n</code> steps when you can take <code>1</code>, <code>2</code>, or <code>3</code> at a time. The recurrence is <code>dp[i] = dp[i-1] + dp[i-2] + dp[i-3]</code>. Instead of storing every <code>dp[i]</code>, the code keeps only the last three values and shifts them on each iteration. That shift is just assignments to a three slot slice.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;go&quot;,&quot;nodeId&quot;:&quot;6d3cc5e4-4cbd-4a66-9a3a-d99005830063&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-go">package main

import "fmt"

// CountWays counts the number of ways to reach exactly n steps
// when you can take 1, 2, or 3 steps at a time.
func CountWays(n int) int {
 if n &lt; 0 {
  return 0
 }
 if n == 0 {
  return 1
 }

 // roll[0] = dp[i-1], roll[1] = dp[i-2], roll[2] = dp[i-3]
 roll := []int{1, 0, 0}

 for step := 1; step &lt;= n; step++ {
  next := roll[0]
  if step-2 &gt;= 0 {
   next += roll[1]
  }
  if step-3 &gt;= 0 {
   next += roll[2]
  }

  roll[2] = roll[1]
  roll[1] = roll[0]
  roll[0] = next
 }

 return roll[0]
}

func main() {
 fmt.Println(CountWays(5))
 fmt.Println(CountWays(8))
}</code></pre></div><p>Time is O(n). Extra space is O(1) because the rolling state stays at three integers. The slice itself also keeps the update logic tight, because each iteration becomes compute <code>next</code>, then shift, then store.</p><h4>Counting, Dedup, Indexing with maps Helpers</h4><p>Maps work well for fast membership checks, grouping, and counting. Sets are commonly written as <code>map[T]struct{}</code>. Frequency tables are commonly written as <code>map[T]int</code>. Lookup indexes usually map ids to values.</p><p>The <code>maps</code> package adds helpers for cloning, copying, equality checks, and deletion by predicate. Counting runs as a single pass that increments a counter for each token. Average lookup and update time for maps is O(1), so the full pass is O(n) on average for n items. Space grows with the number of distinct tokens, so it is O(u) where u is the number of unique values observed.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;go&quot;,&quot;nodeId&quot;:&quot;3d7a46a6-2862-4f2c-a2af-586dbf88acac&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-go">package main

import (
 "fmt"
 "maps"
)

func main() {
 tags := []string{"api", "db", "api", "cache", "db", "api"}

 counts := make(map[string]int, 8)
 for _, t := range tags {
  counts[t]++
 }

 snapshot := maps.Clone(counts)
 counts["api"]++

 fmt.Println(counts)
 fmt.Println(snapshot)
}</code></pre></div><p>Deletion by predicate is handy when you want to prune a map without writing a manual loop that deletes while ranging. <code>maps.DeleteFunc</code> walks the map and removes pairs that match the predicate. That walk is O(n) time in the number of entries in the map, and extra space stays at O(1) past the map storage itself.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;go&quot;,&quot;nodeId&quot;:&quot;e1e9fcc8-1613-44c2-8562-a998e8824751&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-go">package main

import (
 "fmt"
 "maps"
)

func main() {
 active := map[string]int{
  "alex":    3,
  "kaitlyn": 0,
  "pippin":  1,
  "riley":   0,
 }

 maps.DeleteFunc(active, func(_ string, v int) bool {
  return v == 0
 })

 fmt.Println(active)
}</code></pre></div><p>Map iteration order is not stable. Any algorithm that needs ordered output should collect keys into a slice, sort that slice, then read values in that sorted key order. Collecting keys costs O(k) time and O(k) space for k keys, and sorting those keys costs O(k log k) time.</p><h4>Union Find with Slice Backing for Grid Grouping</h4><p>Grids and connectivity questions map well to union find in Go because the data structure is basically two slices plus two small methods. The grid side stays in <code>(row, col)</code> math, and the union find side stays in integer ids from <code>0</code> to <code>rows*cols-1</code>. The mapping <code>r*cols+c</code> is the bridge.</p><p>This version unions only right and down neighbors. That keeps the scan single pass and avoids duplicating work, because left and up would get handled when you were on the earlier cell. <code>Find</code> uses path compression, and <code>Union</code> uses union by size, so repeated operations stay fast in practice.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;go&quot;,&quot;nodeId&quot;:&quot;4ccdf1b0-7c36-414b-9d76-8de83e734488&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-go">package main

import "fmt"

type UnionFind struct {
 parent []int
 size   []int
}

func NewUnionFind(n int) *UnionFind {
 p := make([]int, n)
 s := make([]int, n)
 for i := 0; i &lt; n; i++ {
  p[i] = i
  s[i] = 1
 }
 return &amp;UnionFind{parent: p, size: s}
}

func (uf *UnionFind) Find(x int) int {
 for x != uf.parent[x] {
  uf.parent[x] = uf.parent[uf.parent[x]]
  x = uf.parent[x]
 }
 return x
}

func (uf *UnionFind) Union(a, b int) bool {
 ra := uf.Find(a)
 rb := uf.Find(b)
 if ra == rb {
  return false
 }

 if uf.size[ra] &lt; uf.size[rb] {
  ra, rb = rb, ra
 }

 uf.parent[rb] = ra
 uf.size[ra] += uf.size[rb]
 return true
}

func CountIslandGroups(grid [][]byte) int {
 rows := len(grid)
 if rows == 0 {
  return 0
 }
 cols := len(grid[0])
 if cols == 0 {
  return 0
 }

 id := func(r, c int) int { return r*cols + c }

 uf := NewUnionFind(rows * cols)

 for r := 0; r &lt; rows; r++ {
  for c := 0; c &lt; cols; c++ {
   if grid[r][c] == '0' {
    continue
   }

   if c+1 &lt; cols &amp;&amp; grid[r][c+1] == '1' {
    uf.Union(id(r, c), id(r, c+1))
   }
   if r+1 &lt; rows &amp;&amp; grid[r+1][c] == '1' {
    uf.Union(id(r, c), id(r+1, c))
   }
  }
 }

 roots := 0
 seen := make(map[int]struct{}, rows*cols)

 for r := 0; r &lt; rows; r++ {
  for c := 0; c &lt; cols; c++ {
   if grid[r][c] == '0' {
    continue
   }
   root := uf.Find(id(r, c))
   if _, ok := seen[root]; ok {
    continue
   }
   seen[root] = struct{}{}
   roots++
  }
 }

 return roots
}

func main() {
 grid := [][]byte{
  []byte("11001"),
  []byte("11011"),
  []byte("00100"),
  []byte("11100"),
 }

 fmt.Println(CountIslandGroups(grid))
}</code></pre></div><p>The grid scan is O(RC) work, and the union find calls stay near constant amortized time per operation with path compression and union by size. Space is O(RC) for <code>parent</code> and <code>size</code>, plus the <code>seen</code> map used to count unique roots for land cells.</p><h3>Concurrency Shaped Algorithm Patterns in Go</h3><p>Concurrency tools in Go turn coordination into something you can express directly in the code, not as an afterthought. In algorithm work, that shows up as bounded parallel work over a collection, plus staged flows where data moves through a sequence of transformations. Context cancellation matters in both cases, because it gives one stop signal that every goroutine can check.</p><h4>Worker Pools with Bounded Parallelism</h4><p>Bounded parallelism comes up when you have a batch of independent work items and you want more throughput without spinning up one goroutine per item. Worker pools keep concurrency capped, which helps when each work item involves I O, CPU, or both.</p><p>Worker pools tend to follow the same shape across problems, so the moving parts are easy to spot. One part feeds work into a channel. A fixed number of workers read from that channel, do the work, then send results somewhere safe. <code>sync.WaitGroup</code> coordinates shutdown so the caller can wait until all workers finish. Time cost tracks the amount of work you feed in. If you process n items and each item takes T, the total work is O(n) in the number of items, with wall clock time closer to O(n / p) in the best case when p workers stay busy and the work is evenly distributed. Memory is O(n) if you store all results, or closer to O(p) if you stream results out and don&#8217;t keep them.</p><p>This version uses a jobs channel, a results channel, plus a wait group. The results channel closes after all workers exit, so the receiver can range until completion.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;go&quot;,&quot;nodeId&quot;:&quot;7966a9c3-3a70-4245-8032-6031974e9152&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-go">package main

import (
 "fmt"
 "sync"
 "time"
)

type Job struct {
 ID   int
 Op   string
 Cost time.Duration
}

type Result struct {
 ID     int
 Output string
}

func worker(id int, jobs &lt;-chan Job, results chan&lt;- Result, wg *sync.WaitGroup) {
 defer wg.Done()

 for j := range jobs {
  time.Sleep(j.Cost)
  results &lt;- Result{
   ID:     j.ID,
   Output: fmt.Sprintf("worker %d ran %s", id, j.Op),
  }
 }
}

func main() {
 jobs := make(chan Job)
 results := make(chan Result)

 var wg sync.WaitGroup
 workerCount := 3

 for i := 0; i &lt; workerCount; i++ {
  wg.Add(1)
  go worker(i+1, jobs, results, &amp;wg)
 }

 // Close results after all workers finish
 go func() {
  wg.Wait()
  close(results)
 }()

 // Send jobs, then close jobs from the sending goroutine
 go func() {
  jobs &lt;- Job{ID: 1, Op: "Alex parse batch", Cost: 120 * time.Millisecond}
  jobs &lt;- Job{ID: 2, Op: "Kaitlyn hash chunk", Cost: 80 * time.Millisecond}
  jobs &lt;- Job{ID: 3, Op: "Pippin validate row", Cost: 90 * time.Millisecond}
  jobs &lt;- Job{ID: 4, Op: "Jules compress block", Cost: 110 * time.Millisecond}
  close(jobs)
 }()

 for r := range results {
  fmt.Println(r.ID, r.Output)
 }
}</code></pre></div><p>The facts that matter in pools are about coordination and failure. With a wait group alone, an error in one worker does not automatically stop other workers. That is where context comes in. When each goroutine checks <code>ctx.Done()</code>, one cancel signal can stop the whole group.</p><p><code>errgroup</code> from <code>golang.org/x/sync/errgroup</code> provides two things in one place. It returns the first error from any goroutine, and it gives a derived context that is canceled when a goroutine returns an error. That makes error flow and cancellation feel natural when you run a set of goroutines as one unit. Bounded parallelism can be done by pairing <code>errgroup</code> with a buffered channel that acts as a semaphore. Sending into that channel acquires a slot. Receiving releases it. Each work item still runs in its own goroutine, but the semaphore caps how many work items run at the same time.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;go&quot;,&quot;nodeId&quot;:&quot;d4859722-ca1a-410f-b7e7-5615f9366086&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-go">package main

import (
 "context"
 "fmt"
 "time"

 "golang.org/x/sync/errgroup"
)

func main() {
 ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
 defer cancel()

 items := []string{
  "Eau Claire ingest",
  "Madison index",
  "Duluth normalize",
  "Milwaukee aggregate",
  "St Paul checkpoint",
 }

 maxParallel := 2
 sem := make(chan struct{}, maxParallel)

 g, ctx := errgroup.WithContext(ctx)

 out := make([]string, len(items))
 for i, name := range items {
  i, name := i, name

  g.Go(func() error {
   select {
   case sem &lt;- struct{}{}:
   case &lt;-ctx.Done():
    return ctx.Err()
   }
   defer func() { &lt;-sem }()

   time.Sleep(150 * time.Millisecond)
   out[i] = fmt.Sprintf("done %s", name)
   return nil
  })
 }

 if err := g.Wait(); err != nil {
  fmt.Println("stopped", err)
  return
 }

 fmt.Println(out)
}</code></pre></div><p>The time cost stays O(n) in the number of items, plus coordination overhead. Semaphore operations are O(1) per work item. Memory stays O(n) because the output slice keeps one entry per item.</p><h4>Pipelines with Cancellation plus Error Flow</h4><p>Pipeline work shows up when data moves through stages, where each stage reads input, transforms it, then passes output to the next stage. Channels connect the stages, and each stage runs in its own goroutine. This structure fits streaming transforms, staged parsing, and chunked processing where you want to limit memory growth by keeping data in motion.</p><p>If a downstream stage stops early, upstream stages need a stop signal so they don&#8217;t keep sending into a channel that no longer has a reader. <code>context.Context</code> gives one shared signal through <code>ctx.Done()</code>. When each stage selects on <code>ctx.Done()</code>, shutdown becomes coordinated.</p><p>Backpressure comes from channel capacity and receiver speed. With an unbuffered channel, a send waits until a receive happens. With a buffered channel, a send waits once the buffer fills. That behavior is part of what makes pipelines feel algorithmic. Speed differences between stages naturally control throughput.</p><p>Channel closing rules prevent subtle shutdown bugs. The goroutine that sends values on a channel should be the one that closes it. Downstream stages can range over an input channel until it closes, then close their own output channel to signal completion to the next stage.</p><p>Time cost is O(n) for n items flowing through, with each stage adding its own per item work. Memory is tied to buffering plus any state each stage holds. With small buffers and streaming output, memory stays closer to O(b), where b is total buffered items across channels, plus whatever each stage needs for its local state.</p><p>This pipeline has three stages. Stage one emits log lines, stage two parses them into a small record, stage three counts by level.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;go&quot;,&quot;nodeId&quot;:&quot;f1c927ca-4cef-4f79-88fc-72b0c7094ef5&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-go">package main

import (
 "context"
 "fmt"
 "strings"
 "time"
)

type Entry struct {
 Level string
 Msg   string
}

func source(ctx context.Context, out chan&lt;- string) {
 defer close(out)

 lines := []string{
  "INFO Alex started sync",
  "WARN Kaitlyn retry scheduled",
  "INFO Pippin wrote checkpoint",
  "ERROR Jules failed parse",
  "INFO Alex finished sync",
 }

 for _, line := range lines {
  select {
  case out &lt;- line:
  case &lt;-ctx.Done():
   return
  }
 }
}

func parse(ctx context.Context, in &lt;-chan string, out chan&lt;- Entry) {
 defer close(out)

 for {
  select {
  case &lt;-ctx.Done():
   return
  case line, ok := &lt;-in:
   if !ok {
    return
   }

   parts := strings.SplitN(line, " ", 2)
   if len(parts) != 2 {
    continue
   }

   e := Entry{Level: parts[0], Msg: parts[1]}

   select {
   case &lt;-ctx.Done():
    return
   case out &lt;- e:
   }
  }
 }
}

func count(ctx context.Context, in &lt;-chan Entry) (map[string]int, error) {
 counts := make(map[string]int, 4)

 for {
  select {
  case &lt;-ctx.Done():
   return nil, ctx.Err()
  case e, ok := &lt;-in:
   if !ok {
    return counts, nil
   }
   counts[e.Level]++
  }
 }
}

func main() {
 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
 defer cancel()

 ch1 := make(chan string, 2)
 ch2 := make(chan Entry, 2)

 go source(ctx, ch1)
 go parse(ctx, ch1, ch2)

 counts, err := count(ctx, ch2)
 if err != nil {
  fmt.Println("stopped", err)
  return
 }

 fmt.Println(counts)
}</code></pre></div><p>Error flow can be handled a few ways. One common route is to have stages return errors and coordinate them with <code>errgroup</code>, so any stage failure cancels the derived context and the pipeline stops quickly. The same idea works with a dedicated error channel, paired with context cancellation, where the first error triggers cancel and downstream stages exit on <code>ctx.Done()</code>.</p><h3>Conclusion</h3><p>Go fits algorithm work best when the data structure and control flow match what the language already provides. Heaps handle priority ordering in O(log n) per push or pop, slice based work covers O(n log n) sorts plus O(log n) binary searches and O(n) scans, and maps give average O(1) membership checks and counting with space tied to the number of distinct entries. Concurrency adds one more layer, where bounded parallel work keeps throughput high without runaway goroutines, and pipelines move data stage by stage with backpressure plus coordinated stopping through <code>context.Context</code>, so the algorithm stays centered on state updates and stop conditions.</p><ol><li><p><em><a href="https://pkg.go.dev/container/heap">container/heap Package Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/slices">slices Package Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/maps">maps Package Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/sort">sort Package Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/context">context Package Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/sync">sync Package Documentation</a></em></p></li><li><p><em><a href="https://go.dev/tour/concurrency/2">Channels in The Go Tour</a></em></p></li><li><p><em><a href="https://go.dev/blog/context">context Cancellation in The Go Blog</a></em></p></li><li><p><em><a href="https://pkg.go.dev/golang.org/x/sync/errgroup">errgroup Package Documentation</a></em></p></li><li><p><em><a href="https://go.dev/doc/go1.21">Go 1.21 Release Notes</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[File Descriptor Lifecycle in Go]]></title><description><![CDATA[Behavior of file descriptors in Go affects how every open file, socket, or pipe moves through a process, from the moment the operating system assigns a small integer handle until that handle returns to the pool or stops working because the process has reached its limit.]]></description><link>https://alexanderobregon.substack.com/p/file-descriptor-lifecycle-in-go</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/file-descriptor-lifecycle-in-go</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Thu, 15 Jan 2026 18:29:26 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/da145f15-e56e-4edc-95c8-4ed010f6b62c_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gWQC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf4ba7bc-3750-490f-8f71-6e352232d343_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gWQC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf4ba7bc-3750-490f-8f71-6e352232d343_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!gWQC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf4ba7bc-3750-490f-8f71-6e352232d343_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!gWQC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf4ba7bc-3750-490f-8f71-6e352232d343_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!gWQC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf4ba7bc-3750-490f-8f71-6e352232d343_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gWQC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf4ba7bc-3750-490f-8f71-6e352232d343_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/df4ba7bc-3750-490f-8f71-6e352232d343_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gWQC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf4ba7bc-3750-490f-8f71-6e352232d343_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!gWQC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf4ba7bc-3750-490f-8f71-6e352232d343_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!gWQC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf4ba7bc-3750-490f-8f71-6e352232d343_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!gWQC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf4ba7bc-3750-490f-8f71-6e352232d343_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>Behavior of file descriptors in Go affects how every open file, socket, or pipe moves through a process, from the moment the operating system assigns a small integer handle until that handle returns to the pool or stops working because the process has reached its limit. Go ties these descriptors to objects in the standard library so they can be opened, tracked across I/O, reused by the kernel after close, and handled predictably when resources grow scarce.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>How File Descriptors Work in Go</h3><p>Every running Go process on a Unix style system sits on top of the same file descriptor model that the operating system gives to C programs and shells. The runtime does not replace that model. It builds on it by wrapping the integer descriptors in Go values and adding safety checks, but the core idea still starts with small integers that index into a table owned by the process.</p><h4>Process View of Descriptors</h4><p>On Unix and similar systems, a file descriptor is a non-negative integer that points into a table the kernel keeps for each process. Entry 5 in that table, for example, refers to a single open file description in the kernel that holds the current offset, access mode, status flags, and a reference to the backing object such as a regular file, socket, pipe, or device node. Several descriptors in one process, or in different processes, can refer to the same open file description when duplication or inheritance happens, but each descriptor value itself is just a small integer.</p><p>When a Go binary starts from a shell, the operating system already has three descriptors assigned. Descriptor 0 is standard input, descriptor 1 is standard output, and descriptor 2 is standard error. The Go runtime keeps these values and exposes them as <code>os.Stdin</code>, <code>os.Stdout</code>, and <code>os.Stderr</code>, which wrap the existing descriptors instead of opening new ones. That means a Go command that prints to standard output is writing through descriptor 1 that the shell provided.</p><p>Every process has limits on how many descriptors it can hold at once. Typical Unix systems use a per-process limit such as <code>RLIMIT_NOFILE</code>, with a soft value that normal calls respect and a hard value that only privileged operations can raise. There is also usually a global kernel bound on the total number of open file descriptions across the whole machine. When a limit is reached and the Go runtime asks the kernel to open a new file or socket, the kernel reports an error such as <code>EMFILE</code> for &#8220;too many open files&#8221; in that process or <code>ENFILE</code> when the system wide pool is exhausted. Go turns those into <code>error</code> values so normal code can see what happened.</p><p>Descriptor numbers are reused after close. When a Go process closes descriptor 7, that integer index becomes available for a later open or socket call. The kernel does not keep counts for specific numbers, it only needs a free entry in the current process table. That reuse means code that reads a descriptor value through <code>File.Fd</code> and stores the integer away has to be careful about lifetime. After the original <code>*os.File</code> is closed and collected, the same descriptor number can belong to an unrelated file or socket.</p><p>Let&#8217;s look at a quick Go example to help connect these ideas:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QmqI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a8d6e66-26b1-498e-8a98-b01646a17bd4_1556x703.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QmqI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a8d6e66-26b1-498e-8a98-b01646a17bd4_1556x703.png 424w, https://substackcdn.com/image/fetch/$s_!QmqI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a8d6e66-26b1-498e-8a98-b01646a17bd4_1556x703.png 848w, https://substackcdn.com/image/fetch/$s_!QmqI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a8d6e66-26b1-498e-8a98-b01646a17bd4_1556x703.png 1272w, https://substackcdn.com/image/fetch/$s_!QmqI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a8d6e66-26b1-498e-8a98-b01646a17bd4_1556x703.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QmqI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a8d6e66-26b1-498e-8a98-b01646a17bd4_1556x703.png" width="1456" height="658" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9a8d6e66-26b1-498e-8a98-b01646a17bd4_1556x703.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:658,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:87147,&quot;alt&quot;:&quot;package main  import ( \t\&quot;fmt\&quot; \t\&quot;os\&quot; )  func main() { \tfmt.Println(\&quot;stdin fd:\&quot;, os.Stdin.Fd()) \tfmt.Println(\&quot;stdout fd:\&quot;, os.Stdout.Fd()) \tfmt.Println(\&quot;stderr fd:\&quot;, os.Stderr.Fd())  \tf, err := os.Open(\&quot;data.txt\&quot;) \tif err != nil { \t\tpanic(err) \t} \tdefer f.Close()  \tfmt.Println(\&quot;data.txt fd:\&quot;, f.Fd()) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/183857597?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a8d6e66-26b1-498e-8a98-b01646a17bd4_1556x703.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import ( &#9;&quot;fmt&quot; &#9;&quot;os&quot; )  func main() { &#9;fmt.Println(&quot;stdin fd:&quot;, os.Stdin.Fd()) &#9;fmt.Println(&quot;stdout fd:&quot;, os.Stdout.Fd()) &#9;fmt.Println(&quot;stderr fd:&quot;, os.Stderr.Fd())  &#9;f, err := os.Open(&quot;data.txt&quot;) &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;defer f.Close()  &#9;fmt.Println(&quot;data.txt fd:&quot;, f.Fd()) }" title="package main  import ( &#9;&quot;fmt&quot; &#9;&quot;os&quot; )  func main() { &#9;fmt.Println(&quot;stdin fd:&quot;, os.Stdin.Fd()) &#9;fmt.Println(&quot;stdout fd:&quot;, os.Stdout.Fd()) &#9;fmt.Println(&quot;stderr fd:&quot;, os.Stderr.Fd())  &#9;f, err := os.Open(&quot;data.txt&quot;) &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;defer f.Close()  &#9;fmt.Println(&quot;data.txt fd:&quot;, f.Fd()) }" srcset="https://substackcdn.com/image/fetch/$s_!QmqI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a8d6e66-26b1-498e-8a98-b01646a17bd4_1556x703.png 424w, https://substackcdn.com/image/fetch/$s_!QmqI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a8d6e66-26b1-498e-8a98-b01646a17bd4_1556x703.png 848w, https://substackcdn.com/image/fetch/$s_!QmqI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a8d6e66-26b1-498e-8a98-b01646a17bd4_1556x703.png 1272w, https://substackcdn.com/image/fetch/$s_!QmqI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a8d6e66-26b1-498e-8a98-b01646a17bd4_1556x703.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This program prints the descriptor numbers for the three standard streams, then opens <code>data.txt</code> and prints the descriptor used for that file in the same process. Running it a few times usually reveals that the first three lines stay at 0, 1, and 2, while the descriptor for <code>data.txt</code> takes the lowest free value at that moment.</p><p>Descriptor reuse can be seen with a small variation:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jbZc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3433153-00f8-40a9-8500-e235ecde72dd_1557x770.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jbZc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3433153-00f8-40a9-8500-e235ecde72dd_1557x770.png 424w, https://substackcdn.com/image/fetch/$s_!jbZc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3433153-00f8-40a9-8500-e235ecde72dd_1557x770.png 848w, https://substackcdn.com/image/fetch/$s_!jbZc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3433153-00f8-40a9-8500-e235ecde72dd_1557x770.png 1272w, https://substackcdn.com/image/fetch/$s_!jbZc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3433153-00f8-40a9-8500-e235ecde72dd_1557x770.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jbZc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3433153-00f8-40a9-8500-e235ecde72dd_1557x770.png" width="1456" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a3433153-00f8-40a9-8500-e235ecde72dd_1557x770.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:87820,&quot;alt&quot;:&quot;package main  import ( \t\&quot;fmt\&quot; \t\&quot;os\&quot; )  func main() { \tf1, err := os.Open(\&quot;first.log\&quot;) \tif err != nil { \t\tpanic(err) \t} \tfmt.Println(\&quot;first.log fd:\&quot;, f1.Fd()) \tf1.Close()  \tf2, err := os.Open(\&quot;second.log\&quot;) \tif err != nil { \t\tpanic(err) \t} \tfmt.Println(\&quot;second.log fd:\&quot;, f2.Fd()) \tf2.Close() }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/183857597?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3433153-00f8-40a9-8500-e235ecde72dd_1557x770.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import ( &#9;&quot;fmt&quot; &#9;&quot;os&quot; )  func main() { &#9;f1, err := os.Open(&quot;first.log&quot;) &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;fmt.Println(&quot;first.log fd:&quot;, f1.Fd()) &#9;f1.Close()  &#9;f2, err := os.Open(&quot;second.log&quot;) &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;fmt.Println(&quot;second.log fd:&quot;, f2.Fd()) &#9;f2.Close() }" title="package main  import ( &#9;&quot;fmt&quot; &#9;&quot;os&quot; )  func main() { &#9;f1, err := os.Open(&quot;first.log&quot;) &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;fmt.Println(&quot;first.log fd:&quot;, f1.Fd()) &#9;f1.Close()  &#9;f2, err := os.Open(&quot;second.log&quot;) &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;fmt.Println(&quot;second.log fd:&quot;, f2.Fd()) &#9;f2.Close() }" srcset="https://substackcdn.com/image/fetch/$s_!jbZc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3433153-00f8-40a9-8500-e235ecde72dd_1557x770.png 424w, https://substackcdn.com/image/fetch/$s_!jbZc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3433153-00f8-40a9-8500-e235ecde72dd_1557x770.png 848w, https://substackcdn.com/image/fetch/$s_!jbZc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3433153-00f8-40a9-8500-e235ecde72dd_1557x770.png 1272w, https://substackcdn.com/image/fetch/$s_!jbZc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3433153-00f8-40a9-8500-e235ecde72dd_1557x770.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>On many systems the two descriptor values printed end up the same, because the kernel reuses the slot freed by closing <code>first.log</code> when <code>second.log</code> opens immediately afterward. That behavior reflects the descriptor table layout and helps explain why stale integer file descriptors cause bugs when their lifetimes are not tied to the Go values that own them.</p><h4>Go Wrapper Structures for Files</h4><p>Go code normally works with <code>*os.File</code> values instead of raw descriptor integers. That <code>File</code> type wraps the descriptor and holds extra fields that track the name, I/O state, and internal poll structures that link the descriptor to the runtime. Standard constructors such as <code>os.Open</code>, <code>os.Create</code>, and <code>os.OpenFile</code> call into the operating system with <code>open</code> or an equivalent function, then build a <code>File</code> around the returned descriptor.</p><p>This small example shows that pattern from the surface level:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!y0wR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01afb30e-fb5d-4eae-b1ad-507e65f51c53_1567x908.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!y0wR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01afb30e-fb5d-4eae-b1ad-507e65f51c53_1567x908.png 424w, https://substackcdn.com/image/fetch/$s_!y0wR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01afb30e-fb5d-4eae-b1ad-507e65f51c53_1567x908.png 848w, https://substackcdn.com/image/fetch/$s_!y0wR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01afb30e-fb5d-4eae-b1ad-507e65f51c53_1567x908.png 1272w, https://substackcdn.com/image/fetch/$s_!y0wR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01afb30e-fb5d-4eae-b1ad-507e65f51c53_1567x908.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!y0wR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01afb30e-fb5d-4eae-b1ad-507e65f51c53_1567x908.png" width="1456" height="844" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/01afb30e-fb5d-4eae-b1ad-507e65f51c53_1567x908.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:844,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:98088,&quot;alt&quot;:&quot;package main  import ( \t\&quot;fmt\&quot; \t\&quot;os\&quot; )  func main() { \tf, err := os.Create(\&quot;log.txt\&quot;) \tif err != nil { \t\tpanic(err) \t} \tdefer f.Close()  \t_, err = f.WriteString(\&quot;hello from Go\\n\&quot;) \tif err != nil { \t\tpanic(err) \t}  \tinfo, err := f.Stat() \tif err != nil { \t\tpanic(err) \t} \tfmt.Println(\&quot;name:\&quot;, info.Name()) \tfmt.Println(\&quot;size:\&quot;, info.Size()) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/183857597?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01afb30e-fb5d-4eae-b1ad-507e65f51c53_1567x908.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import ( &#9;&quot;fmt&quot; &#9;&quot;os&quot; )  func main() { &#9;f, err := os.Create(&quot;log.txt&quot;) &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;defer f.Close()  &#9;_, err = f.WriteString(&quot;hello from Go\n&quot;) &#9;if err != nil { &#9;&#9;panic(err) &#9;}  &#9;info, err := f.Stat() &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;fmt.Println(&quot;name:&quot;, info.Name()) &#9;fmt.Println(&quot;size:&quot;, info.Size()) }" title="package main  import ( &#9;&quot;fmt&quot; &#9;&quot;os&quot; )  func main() { &#9;f, err := os.Create(&quot;log.txt&quot;) &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;defer f.Close()  &#9;_, err = f.WriteString(&quot;hello from Go\n&quot;) &#9;if err != nil { &#9;&#9;panic(err) &#9;}  &#9;info, err := f.Stat() &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;fmt.Println(&quot;name:&quot;, info.Name()) &#9;fmt.Println(&quot;size:&quot;, info.Size()) }" srcset="https://substackcdn.com/image/fetch/$s_!y0wR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01afb30e-fb5d-4eae-b1ad-507e65f51c53_1567x908.png 424w, https://substackcdn.com/image/fetch/$s_!y0wR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01afb30e-fb5d-4eae-b1ad-507e65f51c53_1567x908.png 848w, https://substackcdn.com/image/fetch/$s_!y0wR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01afb30e-fb5d-4eae-b1ad-507e65f51c53_1567x908.png 1272w, https://substackcdn.com/image/fetch/$s_!y0wR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F01afb30e-fb5d-4eae-b1ad-507e65f51c53_1567x908.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This asks the runtime to create a file, writes a short line, then calls <code>Stat</code> on the <code>File</code>. The descriptor value sits inside the <code>File</code> struct and travels through all those calls without the caller needing to see or manage the integer directly.</p><p>Inside the standard library, that <code>File</code> struct owns a field of an internal type usually named something like <code>fd</code> which is based on the <code>internal/poll.FD</code> type. That internal type stores the system descriptor as an integer on Unix or as a handle on Windows, along with status bits, deadline data, locking fields, and bookkeeping that lets the runtime know when I/O is in progress. Networking types in the <code>net</code> package embed the same <code>FD</code> type, so sockets, pipes, and regular files follow a similar pattern for read and write calls.</p><p>The <code>os</code> package also provides a path from a raw descriptor to a <code>File</code>. That path is useful when code obtains a descriptor from somewhere other than <code>os.Open</code>. A example is a process that receives an inherited descriptor from a parent or from a file descriptor passing mechanism. The constructor <code>os.NewFile</code> supports that case:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!S_Ww!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9ffa9a0-c95c-45ea-987d-0241e46e7e8f_1585x877.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!S_Ww!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9ffa9a0-c95c-45ea-987d-0241e46e7e8f_1585x877.png 424w, https://substackcdn.com/image/fetch/$s_!S_Ww!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9ffa9a0-c95c-45ea-987d-0241e46e7e8f_1585x877.png 848w, https://substackcdn.com/image/fetch/$s_!S_Ww!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9ffa9a0-c95c-45ea-987d-0241e46e7e8f_1585x877.png 1272w, https://substackcdn.com/image/fetch/$s_!S_Ww!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9ffa9a0-c95c-45ea-987d-0241e46e7e8f_1585x877.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!S_Ww!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9ffa9a0-c95c-45ea-987d-0241e46e7e8f_1585x877.png" width="1456" height="806" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a9ffa9a0-c95c-45ea-987d-0241e46e7e8f_1585x877.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:806,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:105932,&quot;alt&quot;:&quot;package main  import ( \t\&quot;fmt\&quot; \t\&quot;os\&quot; )  func main() { \t// Pretend fd 3 was handed to this process by its parent. \tfd := uintptr(3)  \tf := os.NewFile(fd, \&quot;inherited\&quot;) \tif f == nil { \t\tfmt.Println(\&quot;fd was not valid\&quot;) \t\treturn \t} \tdefer f.Close()  \tbuf := make([]byte, 64) \tn, err := f.Read(buf) \tif err != nil { \t\tpanic(err) \t} \tfmt.Printf(\&quot;read %d bytes: %q\\n\&quot;, n, buf[:n]) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/183857597?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9ffa9a0-c95c-45ea-987d-0241e46e7e8f_1585x877.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import ( &#9;&quot;fmt&quot; &#9;&quot;os&quot; )  func main() { &#9;// Pretend fd 3 was handed to this process by its parent. &#9;fd := uintptr(3)  &#9;f := os.NewFile(fd, &quot;inherited&quot;) &#9;if f == nil { &#9;&#9;fmt.Println(&quot;fd was not valid&quot;) &#9;&#9;return &#9;} &#9;defer f.Close()  &#9;buf := make([]byte, 64) &#9;n, err := f.Read(buf) &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;fmt.Printf(&quot;read %d bytes: %q\n&quot;, n, buf[:n]) }" title="package main  import ( &#9;&quot;fmt&quot; &#9;&quot;os&quot; )  func main() { &#9;// Pretend fd 3 was handed to this process by its parent. &#9;fd := uintptr(3)  &#9;f := os.NewFile(fd, &quot;inherited&quot;) &#9;if f == nil { &#9;&#9;fmt.Println(&quot;fd was not valid&quot;) &#9;&#9;return &#9;} &#9;defer f.Close()  &#9;buf := make([]byte, 64) &#9;n, err := f.Read(buf) &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;fmt.Printf(&quot;read %d bytes: %q\n&quot;, n, buf[:n]) }" srcset="https://substackcdn.com/image/fetch/$s_!S_Ww!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9ffa9a0-c95c-45ea-987d-0241e46e7e8f_1585x877.png 424w, https://substackcdn.com/image/fetch/$s_!S_Ww!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9ffa9a0-c95c-45ea-987d-0241e46e7e8f_1585x877.png 848w, https://substackcdn.com/image/fetch/$s_!S_Ww!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9ffa9a0-c95c-45ea-987d-0241e46e7e8f_1585x877.png 1272w, https://substackcdn.com/image/fetch/$s_!S_Ww!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9ffa9a0-c95c-45ea-987d-0241e46e7e8f_1585x877.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This style of code wraps an existing descriptor in a <code>File</code> so that normal <code>Read</code>, <code>Write</code>, and <code>Close</code> calls can apply. The <code>os</code> package does not open a new descriptor in this case. It trusts that the integer refers to a real resource in the current process and attaches the same internal polling and state management as it would for a descriptor it opened itself.</p><p>Go exposes the descriptor value back out through the <code>Fd</code> method on <code>File</code>. That method returns a <code>uintptr</code> copy of the descriptor and leaves ownership with the <code>File</code>. Code that calls <code>Fd</code> can pass the integer to system specific functions, pass it into other libraries, or log it for debugging. The <code>File</code> still owns lifecycle duties, so <code>Close</code> on the <code>File</code> should remain the standard way to release the resource. Keeping the <code>File</code> value reachable while the descriptor is in use ensures that finalizers and internal bookkeeping do not close it early.</p><h3>Runtime Management of File Descriptors</h3><p>Runtime behavior around file descriptors in Go centers on how goroutines block on I/O, how the netpoller waits for readiness, and how the runtime tracks state so that close calls, deadlines, and descriptor reuse stay consistent. Network sockets and other pollable descriptors run through the polling machinery, while many regular files go straight through system calls without readiness events, because disk I/O on common platforms usually returns quickly when data is available.</p><h3>Netpoller Integration with Descriptors</h3><p>Go uses an internal netpoller that sits on top of <code>epoll</code> on Linux, <code>kqueue</code> on BSD and macOS, and I/O Completion Ports on Windows. One or more runtime threads call these kernel interfaces and wait there while the kernel tracks which descriptors are ready for read or write operations. When data arrives or space opens up in a socket buffer, the kernel reports that to the poller, and the runtime wakes goroutines that had been waiting.</p><p>Descriptors that participate in nonblocking I/O have polling records inside the runtime, usually named <code>pollDesc</code> in the source. Those records remember which kind of event matters for a given descriptor, store deadlines, keep a sequence number to separate old events from new ones, and hold references to goroutines that are asleep on that descriptor. When a goroutine calls <code>Read</code> or <code>Write</code> on a socket and the kernel says the operation would block, the runtime registers interest in the right event and parks the goroutine until the netpoller sees a change.</p><p>This client example gives a simplified view of how a socket ends up under netpoller control:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!O-AA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F386a4aaa-6ba3-4ae2-a9d7-820f30c36280_1566x910.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!O-AA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F386a4aaa-6ba3-4ae2-a9d7-820f30c36280_1566x910.png 424w, https://substackcdn.com/image/fetch/$s_!O-AA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F386a4aaa-6ba3-4ae2-a9d7-820f30c36280_1566x910.png 848w, https://substackcdn.com/image/fetch/$s_!O-AA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F386a4aaa-6ba3-4ae2-a9d7-820f30c36280_1566x910.png 1272w, https://substackcdn.com/image/fetch/$s_!O-AA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F386a4aaa-6ba3-4ae2-a9d7-820f30c36280_1566x910.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!O-AA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F386a4aaa-6ba3-4ae2-a9d7-820f30c36280_1566x910.png" width="1456" height="846" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/386a4aaa-6ba3-4ae2-a9d7-820f30c36280_1566x910.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:846,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:107963,&quot;alt&quot;:&quot;package main  import ( \t\&quot;fmt\&quot; \t\&quot;net\&quot; )  func main() { \tconn, err := net.Dial(\&quot;tcp\&quot;, \&quot;example.com:80\&quot;) \tif err != nil { \t\tpanic(err) \t} \tdefer conn.Close()  \t_, err = conn.Write([]byte(\&quot;GET / HTTP/1.0\\r\\nHost: example.com\\r\\n\\r\\n\&quot;)) \tif err != nil { \t\tpanic(err) \t}  \tbuf := make([]byte, 128) \tn, err := conn.Read(buf) \tif err != nil { \t\tpanic(err) \t} \tfmt.Println(string(buf[:n])) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/183857597?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F386a4aaa-6ba3-4ae2-a9d7-820f30c36280_1566x910.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import ( &#9;&quot;fmt&quot; &#9;&quot;net&quot; )  func main() { &#9;conn, err := net.Dial(&quot;tcp&quot;, &quot;example.com:80&quot;) &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;defer conn.Close()  &#9;_, err = conn.Write([]byte(&quot;GET / HTTP/1.0\r\nHost: example.com\r\n\r\n&quot;)) &#9;if err != nil { &#9;&#9;panic(err) &#9;}  &#9;buf := make([]byte, 128) &#9;n, err := conn.Read(buf) &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;fmt.Println(string(buf[:n])) }" title="package main  import ( &#9;&quot;fmt&quot; &#9;&quot;net&quot; )  func main() { &#9;conn, err := net.Dial(&quot;tcp&quot;, &quot;example.com:80&quot;) &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;defer conn.Close()  &#9;_, err = conn.Write([]byte(&quot;GET / HTTP/1.0\r\nHost: example.com\r\n\r\n&quot;)) &#9;if err != nil { &#9;&#9;panic(err) &#9;}  &#9;buf := make([]byte, 128) &#9;n, err := conn.Read(buf) &#9;if err != nil { &#9;&#9;panic(err) &#9;} &#9;fmt.Println(string(buf[:n])) }" srcset="https://substackcdn.com/image/fetch/$s_!O-AA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F386a4aaa-6ba3-4ae2-a9d7-820f30c36280_1566x910.png 424w, https://substackcdn.com/image/fetch/$s_!O-AA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F386a4aaa-6ba3-4ae2-a9d7-820f30c36280_1566x910.png 848w, https://substackcdn.com/image/fetch/$s_!O-AA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F386a4aaa-6ba3-4ae2-a9d7-820f30c36280_1566x910.png 1272w, https://substackcdn.com/image/fetch/$s_!O-AA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F386a4aaa-6ba3-4ae2-a9d7-820f30c36280_1566x910.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This client asks the runtime to connect and then issues a request, and reads can cause the goroutine to sleep while the netpoller waits for response data from the remote host.</p><p>Regular files do not always use the same path. On many Unix systems a plain file read returns right away unless the operation hits unusual conditions, so the runtime can call straight into the system without adding that descriptor to the readiness set. The <code>os</code> and <code>net</code> packages hide this split, so code written against <code>Read</code> and <code>Write</code> sees a single I/O model, while the runtime selects either a direct call or netpoller integration based on the type of descriptor.</p><h4>Closing Files plus Reference Tracking</h4><p>Internal structures that wrap file descriptors in Go carry flags and counters that help the runtime decide when it is safe to call the kernel close function. The <code>internal/poll.FD</code> type holds the raw descriptor, a mutex that guards concurrent access, fields that track whether reads or writes are allowed, and a reference count that tracks active I O operations and close coordination so <code>Close()</code> can return while the real <code>close(2)</code> waits for in flight work to finish.</p><p>When code calls <code>Close</code> on a <code>*os.File</code> or on a <code>net.Conn</code>, control passes down to that internal <code>FD</code> value. The close logic marks the descriptor as closing, cancels waits in the polling layer, and decrements the reference count. At the point where the last reference is gone, the runtime issues the actual <code>close</code> system call and returns that descriptor slot to the operating system. Later calls to <code>Read</code> or <code>Write</code> on the same Go value see an error such as <code>ErrClosed</code>, which signals that the descriptor is no longer valid.</p><p>Finalizers sit in the background as a safety net. The <code>os</code> package attaches a finalizer to many <code>File</code> values so that if a file becomes unreachable without an explicit <code>Close</code>, the garbage collector can eventually call an internal close helper and free the descriptor. The exact moment that happens depends on garbage collection cycles and reachability, so explicit <code>Close</code> calls remain the main tool for managing descriptors that count toward process and system limits.</p><p>Take this short code fragment shows the life of a shared file handle visually:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!W7vI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37265ec5-1eb9-446a-be8d-551cc2ecf914_1556x561.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!W7vI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37265ec5-1eb9-446a-be8d-551cc2ecf914_1556x561.png 424w, https://substackcdn.com/image/fetch/$s_!W7vI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37265ec5-1eb9-446a-be8d-551cc2ecf914_1556x561.png 848w, https://substackcdn.com/image/fetch/$s_!W7vI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37265ec5-1eb9-446a-be8d-551cc2ecf914_1556x561.png 1272w, https://substackcdn.com/image/fetch/$s_!W7vI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37265ec5-1eb9-446a-be8d-551cc2ecf914_1556x561.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!W7vI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37265ec5-1eb9-446a-be8d-551cc2ecf914_1556x561.png" width="1456" height="525" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/37265ec5-1eb9-446a-be8d-551cc2ecf914_1556x561.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:525,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:71847,&quot;alt&quot;:&quot;f, err := os.Create(\&quot;shared.log\&quot;) if err != nil { \tpanic(err) }  // other goroutines write to f here  err = f.Close() if err != nil { \tpanic(err) }  _, err = f.WriteString(\&quot;after close\\n\&quot;) if err != nil { \tfmt.Println(\&quot;expected error:\&quot;, err) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/183857597?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37265ec5-1eb9-446a-be8d-551cc2ecf914_1556x561.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="f, err := os.Create(&quot;shared.log&quot;) if err != nil { &#9;panic(err) }  // other goroutines write to f here  err = f.Close() if err != nil { &#9;panic(err) }  _, err = f.WriteString(&quot;after close\n&quot;) if err != nil { &#9;fmt.Println(&quot;expected error:&quot;, err) }" title="f, err := os.Create(&quot;shared.log&quot;) if err != nil { &#9;panic(err) }  // other goroutines write to f here  err = f.Close() if err != nil { &#9;panic(err) }  _, err = f.WriteString(&quot;after close\n&quot;) if err != nil { &#9;fmt.Println(&quot;expected error:&quot;, err) }" srcset="https://substackcdn.com/image/fetch/$s_!W7vI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37265ec5-1eb9-446a-be8d-551cc2ecf914_1556x561.png 424w, https://substackcdn.com/image/fetch/$s_!W7vI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37265ec5-1eb9-446a-be8d-551cc2ecf914_1556x561.png 848w, https://substackcdn.com/image/fetch/$s_!W7vI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37265ec5-1eb9-446a-be8d-551cc2ecf914_1556x561.png 1272w, https://substackcdn.com/image/fetch/$s_!W7vI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37265ec5-1eb9-446a-be8d-551cc2ecf914_1556x561.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This fragment shows the sequence where a file is created, used by other goroutines, closed, and then written again, and that last write hits an error because the internal state now marks the descriptor as closed.</p><h4>Handling Descriptor Exhaustion</h4><p>Descriptor exhaustion connects the Go runtime to operating system limits. Every open file, socket, and pipe for a process consumes one entry in the descriptor table that the kernel keeps for that process, and that table has a fixed capacity. On Unix style systems the capacity is controlled by <code>RLIMIT_NOFILE</code>, which has a soft value for ordinary code and a hard value that only privileged calls can raise. The kernel also tracks a global cap on all open file descriptions across the machine, such as the <code>fs.file-max</code> setting on Linux.</p><p>Go calls such as <code>os.Open</code>, <code>net.Dial</code>, and <code>net.Listen</code> end up in system calls like <code>open</code>, <code>socket</code>, and <code>accept</code>. When the per-process limit is reached, those system calls return <code>EMFILE</code>, which Go reports as an <code>error</code> whose message usually includes the text <code>too many open files</code>. When the system as a whole runs out of file descriptions, calls can fail with <code>ENFILE</code>, which points to pressure across processes rather than a single Go service. Two broad patterns lead to exhaustion in Go code. One is a leak where descriptors are opened and never closed, so the count only grows. The other is a workload that legitimately needs more concurrent descriptors than the current limit allows, such as a server with many active network clients or many open log files. Both patterns result in system calls that try to allocate fresh descriptors and receive <code>EMFILE</code> or <code>ENFILE</code> instead.</p><p>A short loop makes a leak very visible:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kOIi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e12f7a9-26b0-4204-b608-155c1947ff56_1583x663.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kOIi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e12f7a9-26b0-4204-b608-155c1947ff56_1583x663.png 424w, https://substackcdn.com/image/fetch/$s_!kOIi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e12f7a9-26b0-4204-b608-155c1947ff56_1583x663.png 848w, https://substackcdn.com/image/fetch/$s_!kOIi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e12f7a9-26b0-4204-b608-155c1947ff56_1583x663.png 1272w, https://substackcdn.com/image/fetch/$s_!kOIi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e12f7a9-26b0-4204-b608-155c1947ff56_1583x663.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kOIi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e12f7a9-26b0-4204-b608-155c1947ff56_1583x663.png" width="1456" height="610" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7e12f7a9-26b0-4204-b608-155c1947ff56_1583x663.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:610,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:60609,&quot;alt&quot;:&quot;package main  import ( \t\&quot;fmt\&quot; \t\&quot;os\&quot; )  func main() { \tvar files []*os.File  \tfor { \t\tf, err := os.Open(\&quot;data.bin\&quot;) \t\tif err != nil { \t\t\tfmt.Println(\&quot;open error:\&quot;, err) \t\t\tbreak \t\t} \t\tfiles = append(files, f) \t} }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/183857597?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e12f7a9-26b0-4204-b608-155c1947ff56_1583x663.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import ( &#9;&quot;fmt&quot; &#9;&quot;os&quot; )  func main() { &#9;var files []*os.File  &#9;for { &#9;&#9;f, err := os.Open(&quot;data.bin&quot;) &#9;&#9;if err != nil { &#9;&#9;&#9;fmt.Println(&quot;open error:&quot;, err) &#9;&#9;&#9;break &#9;&#9;} &#9;&#9;files = append(files, f) &#9;} }" title="package main  import ( &#9;&quot;fmt&quot; &#9;&quot;os&quot; )  func main() { &#9;var files []*os.File  &#9;for { &#9;&#9;f, err := os.Open(&quot;data.bin&quot;) &#9;&#9;if err != nil { &#9;&#9;&#9;fmt.Println(&quot;open error:&quot;, err) &#9;&#9;&#9;break &#9;&#9;} &#9;&#9;files = append(files, f) &#9;} }" srcset="https://substackcdn.com/image/fetch/$s_!kOIi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e12f7a9-26b0-4204-b608-155c1947ff56_1583x663.png 424w, https://substackcdn.com/image/fetch/$s_!kOIi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e12f7a9-26b0-4204-b608-155c1947ff56_1583x663.png 848w, https://substackcdn.com/image/fetch/$s_!kOIi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e12f7a9-26b0-4204-b608-155c1947ff56_1583x663.png 1272w, https://substackcdn.com/image/fetch/$s_!kOIi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e12f7a9-26b0-4204-b608-155c1947ff56_1583x663.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This small main function keeps opening the same file and holds every <code>*os.File</code> value in a slice without calling <code>Close</code>, so descriptor use keeps increasing until the kernel returns a failure such as <code>too many open files</code>.</p><p>Network servers run into related issues if connections are accepted and left open for long periods without matching <code>Close</code> calls. Limits can be raised through <code>RLIMIT_NOFILE</code> and system configuration when that fits operational needs, but application code still has to return descriptors to the operating system when work with that resource ends so the process does not gradually run out of descriptors.</p><h3>Conclusion</h3><p>File descriptor behavior in Go comes from a tight link between the kernel&#8217;s integer handles and the runtime&#8217;s wrappers, schedulers, and limits. The operating system hands out numbers that point into per-process tables, Go wraps those numbers in <code>os.File</code> and <code>net</code> types backed by <code>internal/poll.FD</code>, and the netpoller arranges for goroutines to sleep and wake as I/O becomes possible. Close paths, reference tracking, and finalizers decide when a descriptor really returns to the kernel pool, while operating system limits and error codes such as <code>EMFILE</code> and <code>ENFILE</code> mark the boundaries for how many descriptors a process or a whole machine can hold. Having a clearer view of that life cycle makes it easier to open, use, and release files and sockets in Go without drifting into leaks or surprise failures when limits are reached.</p><ol><li><p><em><a href="https://pkg.go.dev/os">Go os Package Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/net">Go net Package Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/syscall">Go syscall Package Documentation</a></em></p></li><li><p><em><a href="https://man7.org/linux/man-pages/man2/open.2.html">Linux man page open</a></em></p></li><li><p><em><a href="https://man7.org/linux/man-pages/man7/epoll.7.html">Linux man page epoll</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Dead Code Elimination in Go Builds]]></title><description><![CDATA[Code that never runs in Go builds still takes space in binaries and can make long term maintenance harder.]]></description><link>https://alexanderobregon.substack.com/p/dead-code-elimination-in-go-builds</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/dead-code-elimination-in-go-builds</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Sat, 10 Jan 2026 18:30:31 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/76e83518-1d4f-4dfd-b8fa-61f2c58e93f0_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vmYO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vmYO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!vmYO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>Code that never runs in Go builds still takes space in binaries and can make long term maintenance harder. Go toolchain runs several stages that track reachability of functions and variables, remove work that has no effect on results, and trim data no part of the executable ever reads. Dead code elimination starts at the compiler, which turns Go source into an intermediate form and prunes unreachable instructions inside functions. Later, the linker walks through reachable symbols for the whole build and drops functions that can never run. Go ecosystem also includes a separate <code>deadcode</code> tool that scans source with a call graph and reports functions that no entry point can reach.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>Compiler View Of Dead Code In Go</h3><p>The compiler sits at the front of the toolchain and handles dead code at a very local level. Source files get parsed, type checked, and lowered into an internal graph based form before any machine code appears. That internal form lets the compiler track how values move through branches and loops, so it can erase work that never has any effect on results. Unreachable branches, unused temporary values, and stores to variables that never get read fall away during these passes, long before the linker looks at whole functions.</p><p>Work happens package by package. Each package turns into object files that contain machine code for its functions and metadata for later stages. Dead instructions and dead basic blocks disappear inside that package as SSA passes run, but functions that never get called still exist at this point. Reachability across packages belongs to the linker. Compiler view focuses on what happens inside a single function body and how values inside that function either feed later computation or stop mattering.</p><h4>Dead Code In Go SSA Form</h4><p>Go compiler transforms each function into SSA form before any serious optimization runs. SSA form gives every intermediate value a single assignment point and organizes control flow into basic blocks. Within that structure, an optimizer can answer questions about reachability and variable use in a precise way. Branches guarded by constant conditions, computations that feed values nobody reads, and stores whose results never reach observable behavior all become candidates for removal.</p><p>Source like this is common in real projects:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3Qew!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F303814cb-4903-48b2-8d99-9f802aaa67e0_1481x462.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3Qew!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F303814cb-4903-48b2-8d99-9f802aaa67e0_1481x462.png 424w, https://substackcdn.com/image/fetch/$s_!3Qew!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F303814cb-4903-48b2-8d99-9f802aaa67e0_1481x462.png 848w, https://substackcdn.com/image/fetch/$s_!3Qew!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F303814cb-4903-48b2-8d99-9f802aaa67e0_1481x462.png 1272w, https://substackcdn.com/image/fetch/$s_!3Qew!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F303814cb-4903-48b2-8d99-9f802aaa67e0_1481x462.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3Qew!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F303814cb-4903-48b2-8d99-9f802aaa67e0_1481x462.png" width="1456" height="454" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/303814cb-4903-48b2-8d99-9f802aaa67e0_1481x462.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:454,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:40468,&quot;alt&quot;:&quot;package main  func flagExample(x int) int {     const debug = false      if debug {         x = x + 10     }      return x }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182731877?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F303814cb-4903-48b2-8d99-9f802aaa67e0_1481x462.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  func flagExample(x int) int {     const debug = false      if debug {         x = x + 10     }      return x }" title="package main  func flagExample(x int) int {     const debug = false      if debug {         x = x + 10     }      return x }" srcset="https://substackcdn.com/image/fetch/$s_!3Qew!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F303814cb-4903-48b2-8d99-9f802aaa67e0_1481x462.png 424w, https://substackcdn.com/image/fetch/$s_!3Qew!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F303814cb-4903-48b2-8d99-9f802aaa67e0_1481x462.png 848w, https://substackcdn.com/image/fetch/$s_!3Qew!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F303814cb-4903-48b2-8d99-9f802aaa67e0_1481x462.png 1272w, https://substackcdn.com/image/fetch/$s_!3Qew!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F303814cb-4903-48b2-8d99-9f802aaa67e0_1481x462.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Compiler evaluates the <code>debug</code> constant long before final code generation. SSA form for <code>flagExample</code> still contains a conditional block at first, but after constant folding the branch whose condition can never be true becomes unreachable. That basic block and the <code>x = x + 10</code> computation drop out of the function. Generated machine code behaves as if the <code>if debug</code> line never existed, yet the source stays readable for humans who want a toggle.</p><p>Dead code in SSA also comes from values that have no live uses. Arithmetic on temporary variables that never influence a store, a branch, or a function call can vanish completely. A more arithmetic heavy example looks like this:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9V16!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf77322e-aba7-43a0-a0d3-3996bd5edb1f_1485x377.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9V16!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf77322e-aba7-43a0-a0d3-3996bd5edb1f_1485x377.png 424w, https://substackcdn.com/image/fetch/$s_!9V16!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf77322e-aba7-43a0-a0d3-3996bd5edb1f_1485x377.png 848w, https://substackcdn.com/image/fetch/$s_!9V16!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf77322e-aba7-43a0-a0d3-3996bd5edb1f_1485x377.png 1272w, https://substackcdn.com/image/fetch/$s_!9V16!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf77322e-aba7-43a0-a0d3-3996bd5edb1f_1485x377.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9V16!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf77322e-aba7-43a0-a0d3-3996bd5edb1f_1485x377.png" width="1456" height="370" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/df77322e-aba7-43a0-a0d3-3996bd5edb1f_1485x377.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:370,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:40336,&quot;alt&quot;:&quot;package main  func compute(a, b int) int {     t1 := a * 4     t2 := b * 5     t3 := t1 + t2     t4 := t3 * 2   // never used     return t3 }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182731877?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf77322e-aba7-43a0-a0d3-3996bd5edb1f_1485x377.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  func compute(a, b int) int {     t1 := a * 4     t2 := b * 5     t3 := t1 + t2     t4 := t3 * 2   // never used     return t3 }" title="package main  func compute(a, b int) int {     t1 := a * 4     t2 := b * 5     t3 := t1 + t2     t4 := t3 * 2   // never used     return t3 }" srcset="https://substackcdn.com/image/fetch/$s_!9V16!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf77322e-aba7-43a0-a0d3-3996bd5edb1f_1485x377.png 424w, https://substackcdn.com/image/fetch/$s_!9V16!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf77322e-aba7-43a0-a0d3-3996bd5edb1f_1485x377.png 848w, https://substackcdn.com/image/fetch/$s_!9V16!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf77322e-aba7-43a0-a0d3-3996bd5edb1f_1485x377.png 1272w, https://substackcdn.com/image/fetch/$s_!9V16!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf77322e-aba7-43a0-a0d3-3996bd5edb1f_1485x377.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Compiler evaluates the <code>debug</code> constant long before final code generation. SSA graph for <code>compute</code> assigns each <code>t</code> value once and tracks where it flows. Value <code>t4</code> never feeds any later operation or return, so the multiplication by <code>2</code> serves no purpose. Dead code elimination in the SSA pass removes that multiply and the <code>t4</code> name entirely. Fewer instructions reach the assembler, but the observable behavior of <code>compute</code> stays the same.</p><p>Control flow graphs gain from SSA based removal as well. When a branch condition leads into a block that performs only dead work, that whole branch can collapse. Loops whose bodies simplify to no side effects can vanish or shrink to minimal checks. Debug output and logging that is guarded behind constant flags turn into dead basic blocks once those flags resolve at compile time. This keeps source flexible while avoiding extra work in release builds. Compiler pieces that handle SSA live inside the <code>cmd/compile/internal/ssa</code> subtree of the Go repository. That area holds passes for constant propagation, common subexpression elimination, dead code elimination, and related work. Each pass runs over a function, reads the SSA graph, and either removes nodes or rewrites them into cheaper forms. Dead code removal runs after other simplifications so that any new opportunities exposed by earlier steps can be taken advantage of in the same optimization pipeline.</p><h4>Liveness Analysis For Go Variables</h4><p>Liveness analysis answers a direct question at every point in a function body. For each instruction, some set of variables must still hold meaningful values, because those values can be read later along some execution path. Anything not in that set at that point is dead with respect to future computation. That idea drives both code removal and stack map construction for garbage collection.</p><p>Stack variables in Go carry a bit more structure than local scalars in many older toolchains. Go runtime needs to know which stack slots contain pointers at each garbage collection safe point, so the collector can trace objects correctly. Compiler runs liveness over the SSA graph and produces information that maps safe points back to live pointer sets. This data gets stored in function metadata and read by the garbage collector whenever it pauses goroutines.</p><p>Code with unused locals gives a good sense of how liveness and dead code intersect:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FnZC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F553250fd-213f-4c1f-9877-fc9a6ee9f9d8_1485x501.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FnZC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F553250fd-213f-4c1f-9877-fc9a6ee9f9d8_1485x501.png 424w, https://substackcdn.com/image/fetch/$s_!FnZC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F553250fd-213f-4c1f-9877-fc9a6ee9f9d8_1485x501.png 848w, https://substackcdn.com/image/fetch/$s_!FnZC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F553250fd-213f-4c1f-9877-fc9a6ee9f9d8_1485x501.png 1272w, https://substackcdn.com/image/fetch/$s_!FnZC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F553250fd-213f-4c1f-9877-fc9a6ee9f9d8_1485x501.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FnZC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F553250fd-213f-4c1f-9877-fc9a6ee9f9d8_1485x501.png" width="1456" height="491" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/553250fd-213f-4c1f-9877-fc9a6ee9f9d8_1485x501.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:491,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:40213,&quot;alt&quot;:&quot;package main  func worker(n int) int {     value := n * 2     tmp := n * 3      if n > 10 {         return value     }      return value + 1 }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182731877?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F553250fd-213f-4c1f-9877-fc9a6ee9f9d8_1485x501.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  func worker(n int) int {     value := n * 2     tmp := n * 3      if n > 10 {         return value     }      return value + 1 }" title="package main  func worker(n int) int {     value := n * 2     tmp := n * 3      if n > 10 {         return value     }      return value + 1 }" srcset="https://substackcdn.com/image/fetch/$s_!FnZC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F553250fd-213f-4c1f-9877-fc9a6ee9f9d8_1485x501.png 424w, https://substackcdn.com/image/fetch/$s_!FnZC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F553250fd-213f-4c1f-9877-fc9a6ee9f9d8_1485x501.png 848w, https://substackcdn.com/image/fetch/$s_!FnZC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F553250fd-213f-4c1f-9877-fc9a6ee9f9d8_1485x501.png 1272w, https://substackcdn.com/image/fetch/$s_!FnZC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F553250fd-213f-4c1f-9877-fc9a6ee9f9d8_1485x501.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Variable <code>tmp</code> never influences control flow or the return value. Liveness analysis sees that <code>tmp</code> is never read after its assignment, so its storage does not contribute to any live set. SSA based dead code elimination then removes the <code>n * 3</code> computation and the write into <code>tmp</code>. Generated code no longer allocates stack space for that variable, and the garbage collector does not need to track it.</p><p>Garbage collection safe points interact tightly with liveness. Every function compiled with stack maps has designated points where the runtime can stop execution and start tracing. At those positions, liveness data tells the collector which stack slots and registers currently hold pointers. Any local variable that lost all future uses before that step disappears from those maps. Values that only hold integers or floating numbers also drop from GC data, because they cannot refer to heap objects.</p><p>Compiler liveness system connects with escape analysis as well. Escape analysis decides whether a value can stay on the stack or must move to the heap. Both analyses work over graphs that describe variable use across the function and its callees. Flags such as <code>-gcflags=-m</code> ask the compiler to print escape diagnostics, and <code>go tool compile -live</code> prints liveness details. Those outputs help advanced developers study how their code interacts with stack maps and garbage collection, though regular day to day workflow does not require reading them.</p><h3>Linker Reachability In Go Builds</h3><p>The linker step looks at the whole Go build rather than a single package. Object files from all compiled packages arrive with symbols for functions, globals, and runtime support code. Linker <code>cmd/link</code> then walks from known entry roots and decides which symbols stay and which ones drop out as dead code. That global view lets it remove entire functions that no caller can reach, even if those functions were fully compiled earlier. Reachability work happens on symbols, not on source text. Each function body is represented as a text symbol in the link graph, and the linker maintains a list of these symbols in structures such as <code>Textp</code>. A pass named <code>deadcode</code> visits roots like <code>main.main</code>, <code>init</code> functions, and required runtime pieces, then traces calls and references to mark further symbols as reachable. Anything in <code>Textp</code> that never gets marked can be removed from the final binary.</p><h4>Dead Code Elimination During Linking</h4><p>Go linker treats certain symbols as starting points. These include <code>main.main</code>, all package <code>init</code> functions, and symbols that the runtime marks as mandatory. References from those roots to other functions and globals form edges in a reachability graph. Indirect calls, interface method calls, and calls recorded through relocation entries in object files all feed that graph. When traversal finishes, only marked symbols are kept.</p><p>Some symbols in <code>Textp</code> have zero length. Compiler can emit such entries when an SSA optimization pass removes an entire function body. Those symbols still exist so that references in metadata do not break, yet they have no machine code attached. Linker <code>deadcode</code> pass skips these zero sized symbols because there is nothing left to place in the binary for them.</p><p>Take this small example with unused helpers:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-NIH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0386bd5e-d9f6-47f1-9688-10a9d3ea40c2_1484x628.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-NIH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0386bd5e-d9f6-47f1-9688-10a9d3ea40c2_1484x628.png 424w, https://substackcdn.com/image/fetch/$s_!-NIH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0386bd5e-d9f6-47f1-9688-10a9d3ea40c2_1484x628.png 848w, https://substackcdn.com/image/fetch/$s_!-NIH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0386bd5e-d9f6-47f1-9688-10a9d3ea40c2_1484x628.png 1272w, https://substackcdn.com/image/fetch/$s_!-NIH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0386bd5e-d9f6-47f1-9688-10a9d3ea40c2_1484x628.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-NIH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0386bd5e-d9f6-47f1-9688-10a9d3ea40c2_1484x628.png" width="1456" height="616" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0386bd5e-d9f6-47f1-9688-10a9d3ea40c2_1484x628.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:616,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:56355,&quot;alt&quot;:&quot;package main  import \&quot;fmt\&quot;  func main() {     fmt.Println(square(3)) }  func square(n int) int {     return n * n }  func unusedHelper(n int) int {     return n * 10 }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182731877?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0386bd5e-d9f6-47f1-9688-10a9d3ea40c2_1484x628.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;fmt&quot;  func main() {     fmt.Println(square(3)) }  func square(n int) int {     return n * n }  func unusedHelper(n int) int {     return n * 10 }" title="package main  import &quot;fmt&quot;  func main() {     fmt.Println(square(3)) }  func square(n int) int {     return n * n }  func unusedHelper(n int) int {     return n * 10 }" srcset="https://substackcdn.com/image/fetch/$s_!-NIH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0386bd5e-d9f6-47f1-9688-10a9d3ea40c2_1484x628.png 424w, https://substackcdn.com/image/fetch/$s_!-NIH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0386bd5e-d9f6-47f1-9688-10a9d3ea40c2_1484x628.png 848w, https://substackcdn.com/image/fetch/$s_!-NIH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0386bd5e-d9f6-47f1-9688-10a9d3ea40c2_1484x628.png 1272w, https://substackcdn.com/image/fetch/$s_!-NIH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0386bd5e-d9f6-47f1-9688-10a9d3ea40c2_1484x628.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Reachability graph for this code starts at <code>main.main</code>. That function calls <code>square</code>, so both <code>main.main</code> and <code>square</code> stay marked. Function <code>unusedHelper</code> never receives an edge in the graph, so the linker can safely drop its text symbol. Source still holds the helper, but the compiled binary has no machine code for it.</p><p>Reflection changes reachability rules. Go reflection package can call methods by names known only at runtime, which means the linker cannot always see explicit call edges. Methods <code>reflect.Value.Method</code>, <code>reflect.Type.Method</code>, and <code>reflect.Type.MethodByName</code> support that behavior. To avoid dropping methods that might be used through reflection, linker logic marks exported methods of reachable types whenever reflective entry points appear in the call graph.</p><p>This small reflective example helps show the effect visually:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hFkf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c91ddc9-e763-43cd-927b-2e12a3e0c5e1_1487x796.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hFkf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c91ddc9-e763-43cd-927b-2e12a3e0c5e1_1487x796.png 424w, https://substackcdn.com/image/fetch/$s_!hFkf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c91ddc9-e763-43cd-927b-2e12a3e0c5e1_1487x796.png 848w, https://substackcdn.com/image/fetch/$s_!hFkf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c91ddc9-e763-43cd-927b-2e12a3e0c5e1_1487x796.png 1272w, https://substackcdn.com/image/fetch/$s_!hFkf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c91ddc9-e763-43cd-927b-2e12a3e0c5e1_1487x796.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hFkf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c91ddc9-e763-43cd-927b-2e12a3e0c5e1_1487x796.png" width="1456" height="779" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7c91ddc9-e763-43cd-927b-2e12a3e0c5e1_1487x796.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:779,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:79291,&quot;alt&quot;:&quot;package main  import (     \&quot;fmt\&quot;     \&quot;reflect\&quot; )  type worker struct{}  func (worker) Run() {     fmt.Println(\&quot;running\&quot;) }  func main() {     w := worker{}     v := reflect.ValueOf(w)     m := v.MethodByName(\&quot;Run\&quot;)     m.Call(nil) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182731877?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c91ddc9-e763-43cd-927b-2e12a3e0c5e1_1487x796.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (     &quot;fmt&quot;     &quot;reflect&quot; )  type worker struct{}  func (worker) Run() {     fmt.Println(&quot;running&quot;) }  func main() {     w := worker{}     v := reflect.ValueOf(w)     m := v.MethodByName(&quot;Run&quot;)     m.Call(nil) }" title="package main  import (     &quot;fmt&quot;     &quot;reflect&quot; )  type worker struct{}  func (worker) Run() {     fmt.Println(&quot;running&quot;) }  func main() {     w := worker{}     v := reflect.ValueOf(w)     m := v.MethodByName(&quot;Run&quot;)     m.Call(nil) }" srcset="https://substackcdn.com/image/fetch/$s_!hFkf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c91ddc9-e763-43cd-927b-2e12a3e0c5e1_1487x796.png 424w, https://substackcdn.com/image/fetch/$s_!hFkf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c91ddc9-e763-43cd-927b-2e12a3e0c5e1_1487x796.png 848w, https://substackcdn.com/image/fetch/$s_!hFkf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c91ddc9-e763-43cd-927b-2e12a3e0c5e1_1487x796.png 1272w, https://substackcdn.com/image/fetch/$s_!hFkf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7c91ddc9-e763-43cd-927b-2e12a3e0c5e1_1487x796.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Code above calls <code>Run</code> only through <code>MethodByName</code>. Direct call edges from <code>main</code> to <code>worker.Run</code> never appear in the object files. Linker sees use of reflective method lookup and treats exported methods on reachable types more conservatively. <code>worker.Run</code> stays in the binary even though the call is not visible as a regular static reference.</p><p>Go issue tracker has open discussions about flags and <code>GODEBUG</code> settings that could tighten method trimming while still keeping reflection support in place. Those proposals sit in front of the same reachability machinery already described. Build tags live alongside this system as well. Code wrapped in a <code>//go:build</code> expression that does not match current build constraints never reaches compilation, so linker never sees it at all. Dead code elimination during linking only applies to functions that passed through compilation and then turned out to be unreachable from any entry root.</p><h4>Data Removed From Go Binaries</h4><p>Dead code elimination cuts machine code for unreachable functions. Size of the text segment shrinks, and the binary does less work at runtime. Go toolchain also offers options that strip metadata such as symbol tables and debug information without touching reachability decisions.</p><p>Linker flag <code>-w</code> omits the DWARF symbol table. DWARF records map machine addresses back to file names, line numbers, and variable locations. Debuggers and profilers rely on that information to present human readable stacks and breakpoints. Linker flag <code>-s</code> omits the symbol table and debug information, and it implies <code>-w</code> unless <code>-w=0</code> is set. Binary size drops, but tooling that relies on symbols and line info has less to work with.</p><p>Command line usage sits inside <code>go build</code> through <code>-ldflags</code>:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PWzj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb2c5b21-2653-4f51-9ceb-f7938cad4154_1499x123.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PWzj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb2c5b21-2653-4f51-9ceb-f7938cad4154_1499x123.png 424w, https://substackcdn.com/image/fetch/$s_!PWzj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb2c5b21-2653-4f51-9ceb-f7938cad4154_1499x123.png 848w, https://substackcdn.com/image/fetch/$s_!PWzj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb2c5b21-2653-4f51-9ceb-f7938cad4154_1499x123.png 1272w, https://substackcdn.com/image/fetch/$s_!PWzj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb2c5b21-2653-4f51-9ceb-f7938cad4154_1499x123.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PWzj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb2c5b21-2653-4f51-9ceb-f7938cad4154_1499x123.png" width="1456" height="119" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bb2c5b21-2653-4f51-9ceb-f7938cad4154_1499x123.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:119,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:27074,&quot;alt&quot;:&quot;go build ./cmd/server  go build -ldflags=\&quot;-s -w\&quot; -o server_stripped ./cmd/server&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182731877?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb2c5b21-2653-4f51-9ceb-f7938cad4154_1499x123.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="go build ./cmd/server  go build -ldflags=&quot;-s -w&quot; -o server_stripped ./cmd/server" title="go build ./cmd/server  go build -ldflags=&quot;-s -w&quot; -o server_stripped ./cmd/server" srcset="https://substackcdn.com/image/fetch/$s_!PWzj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb2c5b21-2653-4f51-9ceb-f7938cad4154_1499x123.png 424w, https://substackcdn.com/image/fetch/$s_!PWzj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb2c5b21-2653-4f51-9ceb-f7938cad4154_1499x123.png 848w, https://substackcdn.com/image/fetch/$s_!PWzj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb2c5b21-2653-4f51-9ceb-f7938cad4154_1499x123.png 1272w, https://substackcdn.com/image/fetch/$s_!PWzj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb2c5b21-2653-4f51-9ceb-f7938cad4154_1499x123.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>First command produces a normal binary with full debug metadata. Second command sends <code>-s -w</code> to the linker and writes output into <code>server_stripped</code>. Reachability result is identical in both builds. Any function that the linker marked reachable remains in each binary, and any function that dead code elimination removed is absent from both. Only metadata surrounding that code changes.</p><p>Some developers also call platform <code>strip</code> tools on top of <code>-s -w</code>. External strippers can remove more low level metadata that Go linker left in place. That can lead to even smaller binaries on certain platforms, yet can interfere with Go specific tools that expect certain sections to exist. Dead code elimination still happens in the same way before these extra passes run.</p><h4>Deadcode Tool For Unreachable Functions</h4><p>Go team maintains a <code>deadcode</code> command in <code>golang.org/x/tools</code> that looks for unreachable functions at the source level. While linker works on object files and symbols, <code>deadcode</code> operates on Go packages and module graphs. It loads code, performs Rapid Type Analysis, builds a call graph starting from <code>main</code>, and marks all functions reachable through direct calls, interface method calls, and certain reflective edges. Any function that never becomes reachable appears in the output report.</p><p>Installation uses <code>go install</code> and places the binary in the module aware <code>GOBIN</code> or <code>GOPATH/bin</code> directory.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JybG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7ae4b06-5895-4a52-b7d1-fb2f664113d7_1495x40.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JybG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7ae4b06-5895-4a52-b7d1-fb2f664113d7_1495x40.png 424w, https://substackcdn.com/image/fetch/$s_!JybG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7ae4b06-5895-4a52-b7d1-fb2f664113d7_1495x40.png 848w, https://substackcdn.com/image/fetch/$s_!JybG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7ae4b06-5895-4a52-b7d1-fb2f664113d7_1495x40.png 1272w, https://substackcdn.com/image/fetch/$s_!JybG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7ae4b06-5895-4a52-b7d1-fb2f664113d7_1495x40.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JybG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7ae4b06-5895-4a52-b7d1-fb2f664113d7_1495x40.png" width="1456" height="39" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b7ae4b06-5895-4a52-b7d1-fb2f664113d7_1495x40.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:39,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:17340,&quot;alt&quot;:&quot;go install golang.org/x/tools/cmd/deadcode@latest&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182731877?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7ae4b06-5895-4a52-b7d1-fb2f664113d7_1495x40.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="go install golang.org/x/tools/cmd/deadcode@latest" title="go install golang.org/x/tools/cmd/deadcode@latest" srcset="https://substackcdn.com/image/fetch/$s_!JybG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7ae4b06-5895-4a52-b7d1-fb2f664113d7_1495x40.png 424w, https://substackcdn.com/image/fetch/$s_!JybG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7ae4b06-5895-4a52-b7d1-fb2f664113d7_1495x40.png 848w, https://substackcdn.com/image/fetch/$s_!JybG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7ae4b06-5895-4a52-b7d1-fb2f664113d7_1495x40.png 1272w, https://substackcdn.com/image/fetch/$s_!JybG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7ae4b06-5895-4a52-b7d1-fb2f664113d7_1495x40.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Invocation usually points <code>deadcode</code> at a module root or package pattern.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YaKz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dfc02b-d5b4-4bce-9ca2-a5dea0f30b58_1504x39.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YaKz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dfc02b-d5b4-4bce-9ca2-a5dea0f30b58_1504x39.png 424w, https://substackcdn.com/image/fetch/$s_!YaKz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dfc02b-d5b4-4bce-9ca2-a5dea0f30b58_1504x39.png 848w, https://substackcdn.com/image/fetch/$s_!YaKz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dfc02b-d5b4-4bce-9ca2-a5dea0f30b58_1504x39.png 1272w, https://substackcdn.com/image/fetch/$s_!YaKz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dfc02b-d5b4-4bce-9ca2-a5dea0f30b58_1504x39.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YaKz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dfc02b-d5b4-4bce-9ca2-a5dea0f30b58_1504x39.png" width="1456" height="38" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/10dfc02b-d5b4-4bce-9ca2-a5dea0f30b58_1504x39.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:38,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6036,&quot;alt&quot;:&quot;deadcode ./...&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182731877?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dfc02b-d5b4-4bce-9ca2-a5dea0f30b58_1504x39.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="deadcode ./..." title="deadcode ./..." srcset="https://substackcdn.com/image/fetch/$s_!YaKz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dfc02b-d5b4-4bce-9ca2-a5dea0f30b58_1504x39.png 424w, https://substackcdn.com/image/fetch/$s_!YaKz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dfc02b-d5b4-4bce-9ca2-a5dea0f30b58_1504x39.png 848w, https://substackcdn.com/image/fetch/$s_!YaKz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dfc02b-d5b4-4bce-9ca2-a5dea0f30b58_1504x39.png 1272w, https://substackcdn.com/image/fetch/$s_!YaKz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10dfc02b-d5b4-4bce-9ca2-a5dea0f30b58_1504x39.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Tool runs analysis and prints names of functions that no entry point can reach, grouped by package path. That output gives developers candidates for removal or further inspection.</p><p>Let&#8217;s look at a short example with extra helper code to help understand how <code>deadcode</code> sees the same unreachable function that the linker would discard:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!62vZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf244285-fc95-462c-8d8e-9ce2b15a05c5_1487x626.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!62vZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf244285-fc95-462c-8d8e-9ce2b15a05c5_1487x626.png 424w, https://substackcdn.com/image/fetch/$s_!62vZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf244285-fc95-462c-8d8e-9ce2b15a05c5_1487x626.png 848w, https://substackcdn.com/image/fetch/$s_!62vZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf244285-fc95-462c-8d8e-9ce2b15a05c5_1487x626.png 1272w, https://substackcdn.com/image/fetch/$s_!62vZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf244285-fc95-462c-8d8e-9ce2b15a05c5_1487x626.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!62vZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf244285-fc95-462c-8d8e-9ce2b15a05c5_1487x626.png" width="1456" height="613" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/af244285-fc95-462c-8d8e-9ce2b15a05c5_1487x626.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:613,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:67484,&quot;alt&quot;:&quot;package main  import \&quot;fmt\&quot;  func main() {     fmt.Println(greet(\&quot;world\&quot;)) }  func greet(name string) string {     return \&quot;hello \&quot; + name }  func neverUsed() {     fmt.Println(\&quot;unused\&quot;) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182731877?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf244285-fc95-462c-8d8e-9ce2b15a05c5_1487x626.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;fmt&quot;  func main() {     fmt.Println(greet(&quot;world&quot;)) }  func greet(name string) string {     return &quot;hello &quot; + name }  func neverUsed() {     fmt.Println(&quot;unused&quot;) }" title="package main  import &quot;fmt&quot;  func main() {     fmt.Println(greet(&quot;world&quot;)) }  func greet(name string) string {     return &quot;hello &quot; + name }  func neverUsed() {     fmt.Println(&quot;unused&quot;) }" srcset="https://substackcdn.com/image/fetch/$s_!62vZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf244285-fc95-462c-8d8e-9ce2b15a05c5_1487x626.png 424w, https://substackcdn.com/image/fetch/$s_!62vZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf244285-fc95-462c-8d8e-9ce2b15a05c5_1487x626.png 848w, https://substackcdn.com/image/fetch/$s_!62vZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf244285-fc95-462c-8d8e-9ce2b15a05c5_1487x626.png 1272w, https://substackcdn.com/image/fetch/$s_!62vZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf244285-fc95-462c-8d8e-9ce2b15a05c5_1487x626.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Compiler builds all three functions into object files. Linker then starts from <code>main.main</code>, follows the call to <code>greet</code>, and never reaches <code>neverUsed</code>. Dead code elimination removes <code>neverUsed</code> from the final executable. <code>deadcode</code> sees the same call structure at the source level and reports <code>neverUsed</code> as unreachable.</p><p>Rapid Type Analysis lets <code>deadcode</code> track interface use and some reflective calls more closely than a naive static pass. Methods reached through interface values still count as live when calls pass through interface variables. Certain reflective entry points become edges in the call graph as well, which avoids false positives in cases where reflection is part of normal control flow. Tool output still needs human review, because functions in a shared library may be unused in one module yet required in another that reuses the same codebase.</p><p>The editor support through <code>gopls</code> already flags unused private functions inside a single package, yet stops at that boundary. <code>deadcode</code> spans packages, dependencies, and the full entry graph rooted at <code>main</code>. That wider view makes <code>deadcode</code> a useful companion to linker reachability and compiler level diagnostics when searching for dead code in large Go codebases.</p><h3>Conclusion</h3><p>Go dead code elimination comes from a chain of concrete steps rather than a single feature. Compiler SSA passes trim unreachable branches, unused values, and stack slots, while liveness and escape analysis prepare stack maps that let the garbage collector see exactly which pointers matter at each safe point. Linker reachability then walks symbols from entry points and erases whole functions that have no callers, with reflection and build tags influencing what remains. The <code>Deadcode</code> tool adds a source level view on top of that, so developers can see which parts of the codebase no longer matter even before the linker strips them from the final binary.</p><ol><li><p><em><a href="https://pkg.go.dev/cmd/compile">Go Compiler Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/cmd/link">Go Linker Documentation</a></em></p></li><li><p><em><a href="https://go.dev/doc/gc-guide">Go Garbage Collector Guide</a></em></p></li><li><p><em><a href="https://pkg.go.dev/reflect">Go Reflect Package Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/golang.org/x/tools/cmd/deadcode">Deadcode Tool Reference</a></em></p></li><li><p><em><a href="https://go.dev/src/cmd/compile/internal/ssa/README">Go SSA Backend Article</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Go Memory Zeroing Rules]]></title><description><![CDATA[Memory safety in Go relies on strict rules that control how memory is wiped before code reads from it.]]></description><link>https://alexanderobregon.substack.com/p/go-memory-zeroing-rules</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/go-memory-zeroing-rules</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Tue, 06 Jan 2026 18:07:31 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/4a14bff0-10b7-494d-a955-9a0a4112940f_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vmYO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vmYO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!vmYO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>Memory safety in Go relies on strict rules that control how memory is wiped before code reads from it. The language defines how every type starts at a well defined zero state, and the runtime allocator follows that contract for fresh allocations and for memory that gets recycled, so bytes from old values are not exposed to new ones. That behavior covers both stack variables and heap objects, from small integers to composite structs and slices, and keeps the starting state of new values predictable for all code that works with them.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>Zero Values In Go Allocations</h3><p>In Go, memory that back values always comes from somewhere inside the runtime allocator or from stack space the compiler arranged. New memory in Go does not appear with leftover bytes from earlier activity. Language rules say that any fresh variable or heap object begins in a zeroed state that matches its type, and allocator logic follows that rule whenever new storage is set up. That promise applies to global variables, locals on the stack, and heap allocations requested through helpers such as <code>new</code> and <code>make</code>, so code that reads a value for the first time always sees a predictable starting state.</p><h4>Language Rules For Zero Values</h4><p>Go defines a zero value for every type, and that rule lives at the language level, not just in the runtime implementation. Numeric types use <code>0</code>, <code>0.0</code>, or <code>0+0i</code>, booleans use <code>false</code>, strings use <code>""</code>, and reference types such as slices, maps, channels, pointers, functions, and interfaces use <code>nil</code>. Composite types apply the same idea to their parts, so arrays contain zeroed elements and structs zero each field according to its type. Code that declares a variable without an explicit initializer still receives a fully defined value. A declaration such as <code>var n int</code> or <code>var ready bool</code> does not translate to literal assignments at the source level, yet the compiler arranges for the storage behind those variables to be zeroed before the first read. That behavior extends to package level variables, to locals in functions, and to fields inside composite types.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rQhy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae8ad4b-526a-403c-9fe5-dff963aa6d93_1551x699.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rQhy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae8ad4b-526a-403c-9fe5-dff963aa6d93_1551x699.png 424w, https://substackcdn.com/image/fetch/$s_!rQhy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae8ad4b-526a-403c-9fe5-dff963aa6d93_1551x699.png 848w, https://substackcdn.com/image/fetch/$s_!rQhy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae8ad4b-526a-403c-9fe5-dff963aa6d93_1551x699.png 1272w, https://substackcdn.com/image/fetch/$s_!rQhy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae8ad4b-526a-403c-9fe5-dff963aa6d93_1551x699.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rQhy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae8ad4b-526a-403c-9fe5-dff963aa6d93_1551x699.png" width="1456" height="656" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aae8ad4b-526a-403c-9fe5-dff963aa6d93_1551x699.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:656,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:77393,&quot;alt&quot;:&quot;package main  import \&quot;fmt\&quot;  type Session struct {  ID      int  Active  bool  Label   string  Numbers []int }  func main() {  var count int  var ready bool  var s Session   fmt.Println(count) // 0  fmt.Println(ready) // false  fmt.Printf(\&quot;%#v\\n\&quot;, s) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182814268?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae8ad4b-526a-403c-9fe5-dff963aa6d93_1551x699.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;fmt&quot;  type Session struct {  ID      int  Active  bool  Label   string  Numbers []int }  func main() {  var count int  var ready bool  var s Session   fmt.Println(count) // 0  fmt.Println(ready) // false  fmt.Printf(&quot;%#v\n&quot;, s) }" title="package main  import &quot;fmt&quot;  type Session struct {  ID      int  Active  bool  Label   string  Numbers []int }  func main() {  var count int  var ready bool  var s Session   fmt.Println(count) // 0  fmt.Println(ready) // false  fmt.Printf(&quot;%#v\n&quot;, s) }" srcset="https://substackcdn.com/image/fetch/$s_!rQhy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae8ad4b-526a-403c-9fe5-dff963aa6d93_1551x699.png 424w, https://substackcdn.com/image/fetch/$s_!rQhy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae8ad4b-526a-403c-9fe5-dff963aa6d93_1551x699.png 848w, https://substackcdn.com/image/fetch/$s_!rQhy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae8ad4b-526a-403c-9fe5-dff963aa6d93_1551x699.png 1272w, https://substackcdn.com/image/fetch/$s_!rQhy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae8ad4b-526a-403c-9fe5-dff963aa6d93_1551x699.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>That output shows <code>count</code> and <code>ready</code> with valid values and prints a <code>Session</code> with every field zeroed, including a <code>nil</code> slice in <code>Numbers</code>. No assignment is needed to reach this state, because the language demands that every declared variable starts with the zero value for its type.</p><p>Zero values also appear when code uses composite literals that omit some fields or elements. Go allows writers to specify only the fields they care about, and any field left out receives its zero value automatically. Arrays and slices built from literals also fill unspecified elements with zeros.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2hjD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26a4d1b8-02e4-46ad-8210-33f062915c31_1636x754.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2hjD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26a4d1b8-02e4-46ad-8210-33f062915c31_1636x754.png 424w, https://substackcdn.com/image/fetch/$s_!2hjD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26a4d1b8-02e4-46ad-8210-33f062915c31_1636x754.png 848w, https://substackcdn.com/image/fetch/$s_!2hjD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26a4d1b8-02e4-46ad-8210-33f062915c31_1636x754.png 1272w, https://substackcdn.com/image/fetch/$s_!2hjD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26a4d1b8-02e4-46ad-8210-33f062915c31_1636x754.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2hjD!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26a4d1b8-02e4-46ad-8210-33f062915c31_1636x754.png" width="980" height="451.63461538461536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/26a4d1b8-02e4-46ad-8210-33f062915c31_1636x754.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:671,&quot;width&quot;:1456,&quot;resizeWidth&quot;:980,&quot;bytes&quot;:68697,&quot;alt&quot;:&quot;package main  import \&quot;fmt\&quot;  type Limits struct {  Soft int  Hard int }  type Config struct {  Name   string  Limits Limits  Flags  [3]bool }  func main() {  cfg := Config{   Name: \&quot;worker\&quot;,   Limits: Limits{    Soft: 10,    // Hard left out on purpose   },   // Flags left out  }   fmt.Printf(\&quot;%#v\\n\&quot;, cfg) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182814268?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26a4d1b8-02e4-46ad-8210-33f062915c31_1636x754.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="package main  import &quot;fmt&quot;  type Limits struct {  Soft int  Hard int }  type Config struct {  Name   string  Limits Limits  Flags  [3]bool }  func main() {  cfg := Config{   Name: &quot;worker&quot;,   Limits: Limits{    Soft: 10,    // Hard left out on purpose   },   // Flags left out  }   fmt.Printf(&quot;%#v\n&quot;, cfg) }" title="package main  import &quot;fmt&quot;  type Limits struct {  Soft int  Hard int }  type Config struct {  Name   string  Limits Limits  Flags  [3]bool }  func main() {  cfg := Config{   Name: &quot;worker&quot;,   Limits: Limits{    Soft: 10,    // Hard left out on purpose   },   // Flags left out  }   fmt.Printf(&quot;%#v\n&quot;, cfg) }" srcset="https://substackcdn.com/image/fetch/$s_!2hjD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26a4d1b8-02e4-46ad-8210-33f062915c31_1636x754.png 424w, https://substackcdn.com/image/fetch/$s_!2hjD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26a4d1b8-02e4-46ad-8210-33f062915c31_1636x754.png 848w, https://substackcdn.com/image/fetch/$s_!2hjD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26a4d1b8-02e4-46ad-8210-33f062915c31_1636x754.png 1272w, https://substackcdn.com/image/fetch/$s_!2hjD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26a4d1b8-02e4-46ad-8210-33f062915c31_1636x754.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>That printout shows <code>Limits.Hard</code> as <code>0</code> and every entry in <code>Flags</code> as <code>false</code>. Composite literals do not escape the zero value rule, they just layer explicit initializations on top of a base where everything already starts at zero.</p><p>Stack allocated locals follow the same model. When a function declares a struct or array variable, Go treats that storage just like heap storage with regard to initialization. Compiler generated code may group several zeroing operations together into one block, or optimize away some zeroing when it proves that a variable always receives an explicit value before being read, yet safe Go code cannot observe bytes that were never initialized to a legal value for the type.</p><p>One more aspect of the language rule appears in function parameters and return values. Parameters are initialized with values passed from the caller, and return variables declared with named results start life at the zero value for their type, then receive assignments before the function returns. That means a function such as <code>func stats() (count int, ok bool)</code> begins with <code>count</code> equal to <code>0</code> and <code>ok</code> equal to <code>false</code> as soon as the call enters the function body, even before any line in the body executes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qluD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef714a07-1d7d-4fb7-beb3-9386b493bbfa_1560x524.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qluD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef714a07-1d7d-4fb7-beb3-9386b493bbfa_1560x524.png 424w, https://substackcdn.com/image/fetch/$s_!qluD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef714a07-1d7d-4fb7-beb3-9386b493bbfa_1560x524.png 848w, https://substackcdn.com/image/fetch/$s_!qluD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef714a07-1d7d-4fb7-beb3-9386b493bbfa_1560x524.png 1272w, https://substackcdn.com/image/fetch/$s_!qluD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef714a07-1d7d-4fb7-beb3-9386b493bbfa_1560x524.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qluD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef714a07-1d7d-4fb7-beb3-9386b493bbfa_1560x524.png" width="1456" height="489" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ef714a07-1d7d-4fb7-beb3-9386b493bbfa_1560x524.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:489,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:57654,&quot;alt&quot;:&quot;package main  import \&quot;fmt\&quot;  func stats() (count int, ok bool) {  // count is 0 here, ok is false  count = 5  ok = true  return }  func main() {  n, ready := stats()  fmt.Println(n, ready) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182814268?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef714a07-1d7d-4fb7-beb3-9386b493bbfa_1560x524.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;fmt&quot;  func stats() (count int, ok bool) {  // count is 0 here, ok is false  count = 5  ok = true  return }  func main() {  n, ready := stats()  fmt.Println(n, ready) }" title="package main  import &quot;fmt&quot;  func stats() (count int, ok bool) {  // count is 0 here, ok is false  count = 5  ok = true  return }  func main() {  n, ready := stats()  fmt.Println(n, ready) }" srcset="https://substackcdn.com/image/fetch/$s_!qluD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef714a07-1d7d-4fb7-beb3-9386b493bbfa_1560x524.png 424w, https://substackcdn.com/image/fetch/$s_!qluD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef714a07-1d7d-4fb7-beb3-9386b493bbfa_1560x524.png 848w, https://substackcdn.com/image/fetch/$s_!qluD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef714a07-1d7d-4fb7-beb3-9386b493bbfa_1560x524.png 1272w, https://substackcdn.com/image/fetch/$s_!qluD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef714a07-1d7d-4fb7-beb3-9386b493bbfa_1560x524.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>That convention keeps function results consistent with the rest of the language and removes any special case where a named result would start in an undefined state.</p><h4>Heap Allocation Behavior For Zeroing</h4><p>Heap allocations rely on the runtime allocator to provide storage that already matches the zero value contract. Go organizes heap memory into arenas, then into pages, and then into spans that hold objects of a single size class. When <code>new(T)</code> or <code>make</code> for a slice, map, or channel leads to a heap allocation, allocator code picks a span for the right size and hands back a slot from that span.</p><p>Internally, allocator code centers on <code>runtime.mallocgc</code>. That helper receives the object size, type information, and flags that describe what kind of allocation is needed. One of those flags controls whether the new object must be zeroed before use. Allocator metadata on each span tracks if free slots are already known to hold zeros or if they still carry old data. When a span is marked as needing zeroing, <code>mallocgc</code> calls <code>memclrNoHeapPointers</code> to clear the object memory before the pointer goes back to Go code. At that stage the slot is not yet a live heap object from the collector&#8217;s point of view, so zeroing with <code>memclrNoHeapPointers</code> does not need pointer bookkeeping, and later writes that store real pointers run through the standard write barrier.</p><p>Objects that contain pointers always pass through zeroing on allocation. Pointer fields form the graph that the garbage collector traces, so any stale pointer bits left in a fresh object would confuse reachability analysis. Type information passed into <code>mallocgc</code> tells the runtime where pointer fields sit inside an object. That type information is recorded in heap metadata so the garbage collector can scan pointer fields later, while allocation-time zero-initialization happens before the object becomes type-safe. Functions such as <code>typedmemclr</code> and <code>memclrHasPointers</code> get used when zeroing memory that is already type-safe, and they can run write-barrier logic so the garbage collector sees pointer slots cleared when required. Objects with no pointer fields give the runtime some room to adjust zeroing strategies for performance, yet the language promise about observable behavior still holds. A type like <code>struct{ A int64; B float64 }</code> contains only numeric data, so the collector does not need those bytes for reachability. Allocator code can sometimes rely on the operating system to provide zero filled pages for fresh spans and can skip redundant writes when metadata already records that a span contains zeros in all free slots. From the point of view of Go code, a newly allocated value of such a type still reads as <code>0</code> for every field until user code writes something else.</p><p>Heap allocation helpers at the language level build on top of this machinery. Calling <code>new(T)</code> allocates storage for a single <code>T</code>, initializes it to the zero value through <code>mallocgc</code> and related helpers when it needs heap space, and returns a pointer. Escape analysis can let the compiler place that storage on the stack for short-lived values, but the initialized state seen by Go code stays the same. Calling <code>make([]T, n)</code> creates a slice backed by an array of length <code>n</code> that starts with every element set to the zero value for <code>T</code>, with placement again decided by escape analysis. Same helper logic sets up map and channel headers with zero values for their internal fields, though maps and channels manage their own internal storage further inside the runtime.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CBb4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc34c1cc-6520-4109-b6e3-b8593a4b652b_1553x664.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CBb4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc34c1cc-6520-4109-b6e3-b8593a4b652b_1553x664.png 424w, https://substackcdn.com/image/fetch/$s_!CBb4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc34c1cc-6520-4109-b6e3-b8593a4b652b_1553x664.png 848w, https://substackcdn.com/image/fetch/$s_!CBb4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc34c1cc-6520-4109-b6e3-b8593a4b652b_1553x664.png 1272w, https://substackcdn.com/image/fetch/$s_!CBb4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc34c1cc-6520-4109-b6e3-b8593a4b652b_1553x664.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CBb4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc34c1cc-6520-4109-b6e3-b8593a4b652b_1553x664.png" width="1456" height="623" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bc34c1cc-6520-4109-b6e3-b8593a4b652b_1553x664.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:623,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:77451,&quot;alt&quot;:&quot;package main  import \&quot;fmt\&quot;  type Job struct {  ID     int  Status string  Values []float64 }  func main() {  p := new(Job)  queue := make([]Job, 3)  cache := make(map[int]*Job)   fmt.Printf(\&quot;%#v\\n\&quot;, *p)  fmt.Printf(\&quot;%#v\\n\&quot;, queue)  fmt.Println(cache == nil) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182814268?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc34c1cc-6520-4109-b6e3-b8593a4b652b_1553x664.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;fmt&quot;  type Job struct {  ID     int  Status string  Values []float64 }  func main() {  p := new(Job)  queue := make([]Job, 3)  cache := make(map[int]*Job)   fmt.Printf(&quot;%#v\n&quot;, *p)  fmt.Printf(&quot;%#v\n&quot;, queue)  fmt.Println(cache == nil) }" title="package main  import &quot;fmt&quot;  type Job struct {  ID     int  Status string  Values []float64 }  func main() {  p := new(Job)  queue := make([]Job, 3)  cache := make(map[int]*Job)   fmt.Printf(&quot;%#v\n&quot;, *p)  fmt.Printf(&quot;%#v\n&quot;, queue)  fmt.Println(cache == nil) }" srcset="https://substackcdn.com/image/fetch/$s_!CBb4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc34c1cc-6520-4109-b6e3-b8593a4b652b_1553x664.png 424w, https://substackcdn.com/image/fetch/$s_!CBb4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc34c1cc-6520-4109-b6e3-b8593a4b652b_1553x664.png 848w, https://substackcdn.com/image/fetch/$s_!CBb4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc34c1cc-6520-4109-b6e3-b8593a4b652b_1553x664.png 1272w, https://substackcdn.com/image/fetch/$s_!CBb4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc34c1cc-6520-4109-b6e3-b8593a4b652b_1553x664.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Those prints show a <code>Job</code> from <code>new</code> with every field zeroed, a <code>queue</code> slice where all three elements have zero values for each field, and a non nil map header that still holds no entries. Heap objects under those values carry zeros in their storage, and Go code reaches them only through pointers or headers that obey the same zeroing rules.</p><p>Heap allocation for composite literals also leans on the same zero value base. Literal syntax such as <code>&amp;Job{ID: 5}</code> creates a <code>Job</code> value that starts with every field at its zero value and then stores <code>5</code> into the <code>ID</code> field, leaving <code>Status</code> and <code>Values</code> unchanged. Compiler generated code turns that pattern into a call to <code>mallocgc</code> plus a short series of stores when the value needs heap storage, or keeps it on the stack when escape analysis proves that safe, but in both cases the visible result matches a manual sequence of declarations and assignments. That combination of language level rules and allocator behavior gives heap values a predictable starting point. New objects from <code>new</code>, <code>make</code>, and composite literals always begin in a state that agrees with the zero value definition for their types, and allocator helpers such as <code>mallocgc</code>, <code>memclrNoHeapPointers</code>, and <code>typedmemclr</code> carry out the low level work needed to keep that contract intact.</p><h3>Runtime Memory Reuse Behavior</h3><p>Garbage collection in Go does more than free memory. It also prepares that memory so later allocations do not observe leftover bytes from earlier values. The collector traces which objects are still reachable, marks those objects, and then sweeps through allocation spans that hold heap slots. Any slot that no longer belongs to a live object returns to a free list that the allocator can draw from, but allocator code and collector code cooperate so those slots either already contain zeros or will be wiped before they are handed to new values. This is true for the standard concurrent mark-sweep collector and for the experimental Green Tea collector when it&#8217;s enabled with <code>GOEXPERIMENT=greenteagc</code>.</p><h4>Span Free Lists With needzero Flag</h4><p>Each span belongs to a size class, and every slot inside that span has the same size, which lets the allocator hand out memory quickly without asking the operating system every time. When sweeping finishes with a span, it has a mix of live and dead objects. Dead objects are turned back into free slots and are placed on a free list or represented as a range of indexes. The span also carries a flag named <code>needzero</code> that records whether free slots in that span still require zeroing before reuse. Allocator code that serves new heap allocations checks this flag and a local <code>needzero</code> decision before calling <code>memclrNoHeapPointers</code> to wipe memory for a returning slot. If free slots are already zeroed, the allocator skips that work.</p><p>Sweep has some flexibility about where the actual zeroing happens. One option is to overwrite memory for dead slots during the sweep phase. If sweep writes zeros into all freed objects, then the span can reset <code>needzero</code> to false, and future allocations from that span do not need extra wiping. One option is to leave freed slots untouched during sweep and keep <code>needzero</code> true. Allocator code later sees that the slot comes from a span that still needs zeroing and calls <code>memclrNoHeapPointers</code> on that region before publishing a pointer back to Go code. Both choices lead to the same outcome for allocations, but they trade work between background sweeping and on demand allocation. Green Tea keeps this basic contract but changes the way marking steps through spans, focusing more on spatial locality by visiting objects in nearby memory blocks instead of jumping through pointer chains across the heap. That change affects cache use and collector throughput but does not relax the guarantees about zeroing and safe reuse.</p><p>User code cannot see the <code>needzero</code> flag directly, yet the effect shows up in how allocations behave when many short lived objects appear. A loop that builds and discards structures will cause spans to fill, be swept, and then be reused. Even if the same span slot is used first for a <code>User</code> object and later for a <code>Job</code> object, the second allocation will see zeros before any field writes run. That means no string data, IDs, or other bytes from the earlier <code>User</code> value leak into the <code>Job</code> that replaces it in that slot. The allocator accomplishes this either by having sweep set every freed byte to zero ahead of time or by calling <code>memclrNoHeapPointers</code> on the exact region for the new object when allocating from a span that still carries <code>needzero</code>.</p><p>This short example helps connect this process visually:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dICA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F008431e4-04bc-459f-b918-ddcc574fb60f_1554x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dICA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F008431e4-04bc-459f-b918-ddcc574fb60f_1554x768.png 424w, https://substackcdn.com/image/fetch/$s_!dICA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F008431e4-04bc-459f-b918-ddcc574fb60f_1554x768.png 848w, https://substackcdn.com/image/fetch/$s_!dICA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F008431e4-04bc-459f-b918-ddcc574fb60f_1554x768.png 1272w, https://substackcdn.com/image/fetch/$s_!dICA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F008431e4-04bc-459f-b918-ddcc574fb60f_1554x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dICA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F008431e4-04bc-459f-b918-ddcc574fb60f_1554x768.png" width="1456" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/008431e4-04bc-459f-b918-ddcc574fb60f_1554x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:74607,&quot;alt&quot;:&quot;package main  import \&quot;fmt\&quot;  type Record struct {  ID   int  Data [16]byte }  func makeAndDrop(n int) {  for i := 0; i < n; i++ {   r := &amp;Record{ID: i}   _ = r  } }  func main() {  makeAndDrop(1_000_000)   r2 := &amp;Record{}  fmt.Printf(\&quot;%#v\\n\&quot;, r2) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182814268?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F008431e4-04bc-459f-b918-ddcc574fb60f_1554x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;fmt&quot;  type Record struct {  ID   int  Data [16]byte }  func makeAndDrop(n int) {  for i := 0; i < n; i++ {   r := &amp;Record{ID: i}   _ = r  } }  func main() {  makeAndDrop(1_000_000)   r2 := &amp;Record{}  fmt.Printf(&quot;%#v\n&quot;, r2) }" title="package main  import &quot;fmt&quot;  type Record struct {  ID   int  Data [16]byte }  func makeAndDrop(n int) {  for i := 0; i < n; i++ {   r := &amp;Record{ID: i}   _ = r  } }  func main() {  makeAndDrop(1_000_000)   r2 := &amp;Record{}  fmt.Printf(&quot;%#v\n&quot;, r2) }" srcset="https://substackcdn.com/image/fetch/$s_!dICA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F008431e4-04bc-459f-b918-ddcc574fb60f_1554x768.png 424w, https://substackcdn.com/image/fetch/$s_!dICA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F008431e4-04bc-459f-b918-ddcc574fb60f_1554x768.png 848w, https://substackcdn.com/image/fetch/$s_!dICA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F008431e4-04bc-459f-b918-ddcc574fb60f_1554x768.png 1272w, https://substackcdn.com/image/fetch/$s_!dICA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F008431e4-04bc-459f-b918-ddcc574fb60f_1554x768.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The <code>Record</code> created at the end arrives with <code>ID</code> set to 0 and every byte in <code>Data</code> set to zero. Nothing in the language or runtime gives a path for earlier <code>Data</code> contents from <code>makeAndDrop</code> to reappear in a fresh <code>Record</code>, even though allocation likely reuses spans and perhaps the same slot.</p><p>Sensitive workloads add one more wrinkle. <code>runtime/secret</code> is an experimental package that only exists when building with <code>GOEXPERIMENT=runtimesecret</code>. <code>secret.Do</code> wipes registers and stack space used by the call tree before returning, and it tracks heap allocations made inside the call so the runtime can erase that heap memory after it becomes unreachable.</p><h4>Compiler Driven Zeroing For Slices</h4><p>Slices bring another angle to memory reuse. A slice header is a small value with a pointer, a length, and a capacity. That header can point at existing arrays on the stack or heap, or it can point at new backing arrays that <code>make</code> allocates. Every time a new backing array arrives from <code>make</code>, that array goes through the same span allocation path as any other heap object and comes out fully zeroed. The compiler sometimes needs to request extra zeroing when growing slices or resetting them, and that work also runs through runtime helpers such as <code>memclrNoHeapPointers</code> and friends.</p><p>Let&#8217;s consider a helper that grows a slice to a specific length and keeps any existing prefix:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EBgK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915e00f3-0665-43f8-8cdc-fca274c43bbb_1558x629.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EBgK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915e00f3-0665-43f8-8cdc-fca274c43bbb_1558x629.png 424w, https://substackcdn.com/image/fetch/$s_!EBgK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915e00f3-0665-43f8-8cdc-fca274c43bbb_1558x629.png 848w, https://substackcdn.com/image/fetch/$s_!EBgK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915e00f3-0665-43f8-8cdc-fca274c43bbb_1558x629.png 1272w, https://substackcdn.com/image/fetch/$s_!EBgK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915e00f3-0665-43f8-8cdc-fca274c43bbb_1558x629.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EBgK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915e00f3-0665-43f8-8cdc-fca274c43bbb_1558x629.png" width="1456" height="588" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/915e00f3-0665-43f8-8cdc-fca274c43bbb_1558x629.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:588,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:70446,&quot;alt&quot;:&quot;package main  import \&quot;fmt\&quot;  func grow(buf []byte, n int) []byte {  if cap(buf) >= n {   return buf[:n]  }  next := make([]byte, n)  copy(next, buf)  return next }  func main() {  b := []byte{1, 2, 3}  b = grow(b, 8)  fmt.Println(b) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182814268?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915e00f3-0665-43f8-8cdc-fca274c43bbb_1558x629.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;fmt&quot;  func grow(buf []byte, n int) []byte {  if cap(buf) >= n {   return buf[:n]  }  next := make([]byte, n)  copy(next, buf)  return next }  func main() {  b := []byte{1, 2, 3}  b = grow(b, 8)  fmt.Println(b) }" title="package main  import &quot;fmt&quot;  func grow(buf []byte, n int) []byte {  if cap(buf) >= n {   return buf[:n]  }  next := make([]byte, n)  copy(next, buf)  return next }  func main() {  b := []byte{1, 2, 3}  b = grow(b, 8)  fmt.Println(b) }" srcset="https://substackcdn.com/image/fetch/$s_!EBgK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915e00f3-0665-43f8-8cdc-fca274c43bbb_1558x629.png 424w, https://substackcdn.com/image/fetch/$s_!EBgK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915e00f3-0665-43f8-8cdc-fca274c43bbb_1558x629.png 848w, https://substackcdn.com/image/fetch/$s_!EBgK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915e00f3-0665-43f8-8cdc-fca274c43bbb_1558x629.png 1272w, https://substackcdn.com/image/fetch/$s_!EBgK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915e00f3-0665-43f8-8cdc-fca274c43bbb_1558x629.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When the <code>make([]byte, n)</code> path runs, the new backing array starts with zeros, so bytes past the copied prefix are already 0. When the early return path runs and <code>buf[:n]</code> re-slices the existing backing array, bytes past <code>len(buf)</code> keep whatever values already lived in that array.</p><p>Slice zeroing matters even more when code wants to reuse a buffer across operations. Built-in <code>clear</code> works on slices and maps, setting slice elements to zero values and removing all entries from maps. For slices with non pointer elements, the compiler commonly chooses <code>memclrNoHeapPointers</code> as the helper, which zeroes a range of bytes while skipping pointer bookkeeping. For slices that hold pointers, the compiler emits calls into helpers that understand pointer layouts, such as <code>typedmemclr</code> or <code>memclrHasPointers</code>, so the garbage collector sees that references disappeared from those positions.</p><p>That behavior surfaces in pool based buffer reuse.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-16V!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F142a3d09-e8b0-4ef9-b727-777525e6149c_1456x908.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-16V!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F142a3d09-e8b0-4ef9-b727-777525e6149c_1456x908.png 424w, https://substackcdn.com/image/fetch/$s_!-16V!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F142a3d09-e8b0-4ef9-b727-777525e6149c_1456x908.png 848w, https://substackcdn.com/image/fetch/$s_!-16V!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F142a3d09-e8b0-4ef9-b727-777525e6149c_1456x908.png 1272w, https://substackcdn.com/image/fetch/$s_!-16V!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F142a3d09-e8b0-4ef9-b727-777525e6149c_1456x908.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-16V!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F142a3d09-e8b0-4ef9-b727-777525e6149c_1456x908.png" width="1154" height="719.6648351648352" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/142a3d09-e8b0-4ef9-b727-777525e6149c_1456x908.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:908,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1154,&quot;bytes&quot;:228557,&quot;alt&quot;:&quot;package main  import (  \&quot;fmt\&quot;  \&quot;sync\&quot; )  var bufPool = sync.Pool{  New: func() any {   b := make([]byte, 16)   return &amp;b  }, }  func useBuffer(id int) {  bp := bufPool.Get().(*[]byte)  b := *bp   for i := range b {   b[i] = byte(id)  }   fmt.Println(\&quot;buffer\&quot;, id, b)  *bp = b  bufPool.Put(bp) }  func resetAndUseAgain() {  bp := bufPool.Get().(*[]byte)  b := *bp   for i := range b {   b[i] = 0  }   fmt.Println(\&quot;reset buffer\&quot;, b)  bufPool.Put(bp) }  func main() {  useBuffer(1)  useBuffer(2)  resetAndUseAgain() }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182814268?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F142a3d09-e8b0-4ef9-b727-777525e6149c_1456x908.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="package main  import (  &quot;fmt&quot;  &quot;sync&quot; )  var bufPool = sync.Pool{  New: func() any {   b := make([]byte, 16)   return &amp;b  }, }  func useBuffer(id int) {  bp := bufPool.Get().(*[]byte)  b := *bp   for i := range b {   b[i] = byte(id)  }   fmt.Println(&quot;buffer&quot;, id, b)  *bp = b  bufPool.Put(bp) }  func resetAndUseAgain() {  bp := bufPool.Get().(*[]byte)  b := *bp   for i := range b {   b[i] = 0  }   fmt.Println(&quot;reset buffer&quot;, b)  bufPool.Put(bp) }  func main() {  useBuffer(1)  useBuffer(2)  resetAndUseAgain() }" title="package main  import (  &quot;fmt&quot;  &quot;sync&quot; )  var bufPool = sync.Pool{  New: func() any {   b := make([]byte, 16)   return &amp;b  }, }  func useBuffer(id int) {  bp := bufPool.Get().(*[]byte)  b := *bp   for i := range b {   b[i] = byte(id)  }   fmt.Println(&quot;buffer&quot;, id, b)  *bp = b  bufPool.Put(bp) }  func resetAndUseAgain() {  bp := bufPool.Get().(*[]byte)  b := *bp   for i := range b {   b[i] = 0  }   fmt.Println(&quot;reset buffer&quot;, b)  bufPool.Put(bp) }  func main() {  useBuffer(1)  useBuffer(2)  resetAndUseAgain() }" srcset="https://substackcdn.com/image/fetch/$s_!-16V!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F142a3d09-e8b0-4ef9-b727-777525e6149c_1456x908.png 424w, https://substackcdn.com/image/fetch/$s_!-16V!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F142a3d09-e8b0-4ef9-b727-777525e6149c_1456x908.png 848w, https://substackcdn.com/image/fetch/$s_!-16V!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F142a3d09-e8b0-4ef9-b727-777525e6149c_1456x908.png 1272w, https://substackcdn.com/image/fetch/$s_!-16V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F142a3d09-e8b0-4ef9-b727-777525e6149c_1456x908.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This pool keeps one backing array inside <code>bufPool</code>. Each call to <code>useBuffer</code> writes over every element, so no old contents survive. The <code>resetAndUseAgain</code> function loops through the slice and writes zeros by hand, but <code>clear</code> on the slice would have the same effect while going through the runtime helpers that know how to treat that memory for garbage collection. Memory for the backing array moves between active code and the pool, yet every reuse runs through writes that prepare the bytes for the next user.</p><p>Slices that store pointers call for a different pattern. When a slice holds pointers to objects and code wants those objects to become collectible, zeroing the slice elements matters for more than safety on reuse. It also removes references that keep heap objects alive.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_nuM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b9bd34b-b474-44b0-9bfd-11c42724378b_1652x756.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_nuM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b9bd34b-b474-44b0-9bfd-11c42724378b_1652x756.png 424w, https://substackcdn.com/image/fetch/$s_!_nuM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b9bd34b-b474-44b0-9bfd-11c42724378b_1652x756.png 848w, https://substackcdn.com/image/fetch/$s_!_nuM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b9bd34b-b474-44b0-9bfd-11c42724378b_1652x756.png 1272w, https://substackcdn.com/image/fetch/$s_!_nuM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b9bd34b-b474-44b0-9bfd-11c42724378b_1652x756.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_nuM!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b9bd34b-b474-44b0-9bfd-11c42724378b_1652x756.png" width="922" height="421.739010989011" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6b9bd34b-b474-44b0-9bfd-11c42724378b_1652x756.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:666,&quot;width&quot;:1456,&quot;resizeWidth&quot;:922,&quot;bytes&quot;:73454,&quot;alt&quot;:&quot;package main  import (  \&quot;fmt\&quot;  \&quot;runtime\&quot; )  type Node struct {  Value int  Next  *Node }  func main() {  nodes := make([]*Node, 3)  for i := 0; i < 3; i++ {   nodes[i] = &amp;Node{Value: i}  }   fmt.Println(\&quot;before reset\&quot;, nodes[0])   for i := range nodes {   nodes[i] = nil  }   runtime.GC()  fmt.Println(\&quot;after reset\&quot;, nodes[0]) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/182814268?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b9bd34b-b474-44b0-9bfd-11c42724378b_1652x756.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="package main  import (  &quot;fmt&quot;  &quot;runtime&quot; )  type Node struct {  Value int  Next  *Node }  func main() {  nodes := make([]*Node, 3)  for i := 0; i < 3; i++ {   nodes[i] = &amp;Node{Value: i}  }   fmt.Println(&quot;before reset&quot;, nodes[0])   for i := range nodes {   nodes[i] = nil  }   runtime.GC()  fmt.Println(&quot;after reset&quot;, nodes[0]) }" title="package main  import (  &quot;fmt&quot;  &quot;runtime&quot; )  type Node struct {  Value int  Next  *Node }  func main() {  nodes := make([]*Node, 3)  for i := 0; i < 3; i++ {   nodes[i] = &amp;Node{Value: i}  }   fmt.Println(&quot;before reset&quot;, nodes[0])   for i := range nodes {   nodes[i] = nil  }   runtime.GC()  fmt.Println(&quot;after reset&quot;, nodes[0]) }" srcset="https://substackcdn.com/image/fetch/$s_!_nuM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b9bd34b-b474-44b0-9bfd-11c42724378b_1652x756.png 424w, https://substackcdn.com/image/fetch/$s_!_nuM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b9bd34b-b474-44b0-9bfd-11c42724378b_1652x756.png 848w, https://substackcdn.com/image/fetch/$s_!_nuM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b9bd34b-b474-44b0-9bfd-11c42724378b_1652x756.png 1272w, https://substackcdn.com/image/fetch/$s_!_nuM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b9bd34b-b474-44b0-9bfd-11c42724378b_1652x756.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>After the loop that sets every element to <code>nil</code>, there are no references left in the slice to keep those <code>Node</code> instances alive. During the next garbage collection, the collector can reclaim those heap objects and eventually reuse their spans. When a new allocation later receives a slot from those spans, span metadata and helpers such as <code>memclrHasPointers</code> guarantee that previous <code>Node</code> pointers will not show up in fresh values.</p><h3>Conclusion</h3><p>Go ties language rules about zero values, allocator behavior, and garbage collection into one continuous process that keeps new and recycled memory in a defined state. New variables and heap objects start from type specific zero values, while spans on the heap move through marking, sweeping, <code>needzero</code> flags, and helpers such as <code>mallocgc</code>, <code>memclrNoHeapPointers</code>, and <code>typedmemclr</code> so reused slots are wiped before code can see them. Slice operations, stack handling, and features such as <code>secret.Do</code> apply the same ideas to buffers, stack frames, and short lived secrets, so memory that previously held data for one value is either unreachable or has been overwritten before it is presented as a fresh value again. Those mechanics give Go memory behavior where every observable value either reflects zero initialization or explicit writes, not leftover bytes from unrelated objects.</p><ol><li><p><em><a href="https://go.dev/ref/spec#The_zero_value">Go Language Specification Zero Values</a></em></p></li><li><p><em><a href="https://pkg.go.dev/runtime#hdr-Memory_allocator">Go Runtime Memory Allocator Overview</a></em></p></li><li><p><em><a href="https://go.dev/doc/gc-guide">Go Garbage Collector Guide</a></em></p></li><li><p><em><a href="https://pkg.go.dev/builtin#clear">Builtin clear And Zeroing Behavior</a></em></p></li><li><p><em><a href="https://pkg.go.dev/sync#Pool">sync.Pool Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/runtime/secret">runtime.Secret Package Overview</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Goroutine Creation Path in Go]]></title><description><![CDATA[Spawning a goroutine in Go with the go keyword looks effortless from a developer&#8217;s perspective, but the runtime does a surprising amount of work in the background to make that function call run independently.]]></description><link>https://alexanderobregon.substack.com/p/goroutine-creation-path-in-go</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/goroutine-creation-path-in-go</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Tue, 02 Dec 2025 18:21:38 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/8908408d-c95c-49b2-a056-b90624260863_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vmYO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vmYO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!vmYO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>Spawning a goroutine in Go with the go keyword looks effortless from a developer&#8217;s perspective, but the runtime does a surprising amount of work in the background to make that function call run independently. Today, we are going to take a look at the process from the moment a go statement appears, to how the runtime allocates stack memory, and finally how the new goroutine is connected to the scheduler.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>How a Goroutine Starts From the go Keyword</h3><p>Creating a goroutine begins the moment the <code>go</code> keyword appears in source code, but what follows is a carefully organized sequence handled by the compiler and the runtime. At the surface it feels no different from calling a function, yet the compiler generates instructions that branch into runtime machinery designed to create a new lightweight unit of execution. That chain of work starts with a call into special runtime functions that ordinary Go code never touches directly.</p><h4>The Entry Point of the go Statement</h4><p>When you write a <code>go</code> statement, the compiler lowers it to a call to <code>runtime.newproc</code>. That helper sets up a new <code>g</code>, builds the start frame for your function and arguments, and then enqueues the new <code>g</code> on the current <code>P</code>&#8217;s run queue, waking a worker if needed.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_ohR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb216c108-6c85-48d2-9f57-6e8c83dc5dcd_1113x278.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_ohR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb216c108-6c85-48d2-9f57-6e8c83dc5dcd_1113x278.png 424w, https://substackcdn.com/image/fetch/$s_!_ohR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb216c108-6c85-48d2-9f57-6e8c83dc5dcd_1113x278.png 848w, https://substackcdn.com/image/fetch/$s_!_ohR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb216c108-6c85-48d2-9f57-6e8c83dc5dcd_1113x278.png 1272w, https://substackcdn.com/image/fetch/$s_!_ohR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb216c108-6c85-48d2-9f57-6e8c83dc5dcd_1113x278.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_ohR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb216c108-6c85-48d2-9f57-6e8c83dc5dcd_1113x278.png" width="1113" height="278" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b216c108-6c85-48d2-9f57-6e8c83dc5dcd_1113x278.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:278,&quot;width&quot;:1113,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:29763,&quot;alt&quot;:&quot;func printNumber(n int) {     println(\&quot;number:\&quot;, n) }  func main() {     go printNumber(7)     println(\&quot;done\&quot;) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180450298?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb216c108-6c85-48d2-9f57-6e8c83dc5dcd_1113x278.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="func printNumber(n int) {     println(&quot;number:&quot;, n) }  func main() {     go printNumber(7)     println(&quot;done&quot;) }" title="func printNumber(n int) {     println(&quot;number:&quot;, n) }  func main() {     go printNumber(7)     println(&quot;done&quot;) }" srcset="https://substackcdn.com/image/fetch/$s_!_ohR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb216c108-6c85-48d2-9f57-6e8c83dc5dcd_1113x278.png 424w, https://substackcdn.com/image/fetch/$s_!_ohR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb216c108-6c85-48d2-9f57-6e8c83dc5dcd_1113x278.png 848w, https://substackcdn.com/image/fetch/$s_!_ohR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb216c108-6c85-48d2-9f57-6e8c83dc5dcd_1113x278.png 1272w, https://substackcdn.com/image/fetch/$s_!_ohR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb216c108-6c85-48d2-9f57-6e8c83dc5dcd_1113x278.png 1456w" sizes="100vw"></picture><div></div></div></a></figure></div><p>The call to <code>printNumber</code> above looks ordinary, but the compiler translates it into a sequence where a function pointer and its argument are placed into a temporary frame before calling <code>runtime.newproc</code>. That function sets up the goroutine&#8217;s internal representation and marks it as ready to be scheduled.</p><p>The <code>go</code> keyword also works with anonymous functions, which lets developers capture local variables. The compiler packages those captured values carefully so the goroutine has its own safe copy, independent of the caller&#8217;s stack.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!n5fb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc9d6df-e8ea-4317-8173-e4fc667ab16a_1130x211.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!n5fb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc9d6df-e8ea-4317-8173-e4fc667ab16a_1130x211.png 424w, https://substackcdn.com/image/fetch/$s_!n5fb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc9d6df-e8ea-4317-8173-e4fc667ab16a_1130x211.png 848w, https://substackcdn.com/image/fetch/$s_!n5fb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc9d6df-e8ea-4317-8173-e4fc667ab16a_1130x211.png 1272w, https://substackcdn.com/image/fetch/$s_!n5fb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc9d6df-e8ea-4317-8173-e4fc667ab16a_1130x211.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!n5fb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc9d6df-e8ea-4317-8173-e4fc667ab16a_1130x211.png" width="1130" height="211" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cfc9d6df-e8ea-4317-8173-e4fc667ab16a_1130x211.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:211,&quot;width&quot;:1130,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:32424,&quot;alt&quot;:&quot;func main() {     message := \&quot;hi\&quot;     go func(msg string) {         println(\&quot;message:\&quot;, msg)     }(message) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180450298?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc9d6df-e8ea-4317-8173-e4fc667ab16a_1130x211.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="func main() {     message := &quot;hi&quot;     go func(msg string) {         println(&quot;message:&quot;, msg)     }(message) }" title="func main() {     message := &quot;hi&quot;     go func(msg string) {         println(&quot;message:&quot;, msg)     }(message) }" srcset="https://substackcdn.com/image/fetch/$s_!n5fb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc9d6df-e8ea-4317-8173-e4fc667ab16a_1130x211.png 424w, https://substackcdn.com/image/fetch/$s_!n5fb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc9d6df-e8ea-4317-8173-e4fc667ab16a_1130x211.png 848w, https://substackcdn.com/image/fetch/$s_!n5fb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc9d6df-e8ea-4317-8173-e4fc667ab16a_1130x211.png 1272w, https://substackcdn.com/image/fetch/$s_!n5fb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc9d6df-e8ea-4317-8173-e4fc667ab16a_1130x211.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><p>For this case, the runtime is given a prepared copy of <code>message</code>, meaning the goroutine doesn&#8217;t depend on memory from the original stack frame. That prevents subtle memory hazards that would occur if the main function returned while the goroutine was still referencing its data.</p><h4>The G Object</h4><p>The runtime creates a new <code>G</code> object once <code>newproc</code> has been called. This is the internal data structure that represents a goroutine. While invisible to user code, it holds all the information the runtime needs to keep track of execution.</p><p>The G object records where the stack starts and ends, the entry function that should be executed, and a small state value describing whether the goroutine is waiting or ready. It also contains a unique identifier and links that allow the scheduler to place it into queues.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2XlZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4410514a-6352-4b30-a40f-aea144e41ea8_1118x455.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2XlZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4410514a-6352-4b30-a40f-aea144e41ea8_1118x455.png 424w, https://substackcdn.com/image/fetch/$s_!2XlZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4410514a-6352-4b30-a40f-aea144e41ea8_1118x455.png 848w, https://substackcdn.com/image/fetch/$s_!2XlZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4410514a-6352-4b30-a40f-aea144e41ea8_1118x455.png 1272w, https://substackcdn.com/image/fetch/$s_!2XlZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4410514a-6352-4b30-a40f-aea144e41ea8_1118x455.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2XlZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4410514a-6352-4b30-a40f-aea144e41ea8_1118x455.png" width="1118" height="455" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4410514a-6352-4b30-a40f-aea144e41ea8_1118x455.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:455,&quot;width&quot;:1118,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:60284,&quot;alt&quot;:&quot;// This is a very simplified version of a goroutine in the runtime type G struct {     stack struct {         lo uintptr         hi uintptr     }      // runtime records the entry program counter here     startpc uintptr      status uint32     goid   uint64 }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180450298?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4410514a-6352-4b30-a40f-aea144e41ea8_1118x455.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="// This is a very simplified version of a goroutine in the runtime type G struct {     stack struct {         lo uintptr         hi uintptr     }      // runtime records the entry program counter here     startpc uintptr      status uint32     goid   uint64 }" title="// This is a very simplified version of a goroutine in the runtime type G struct {     stack struct {         lo uintptr         hi uintptr     }      // runtime records the entry program counter here     startpc uintptr      status uint32     goid   uint64 }" srcset="https://substackcdn.com/image/fetch/$s_!2XlZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4410514a-6352-4b30-a40f-aea144e41ea8_1118x455.png 424w, https://substackcdn.com/image/fetch/$s_!2XlZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4410514a-6352-4b30-a40f-aea144e41ea8_1118x455.png 848w, https://substackcdn.com/image/fetch/$s_!2XlZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4410514a-6352-4b30-a40f-aea144e41ea8_1118x455.png 1272w, https://substackcdn.com/image/fetch/$s_!2XlZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4410514a-6352-4b30-a40f-aea144e41ea8_1118x455.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This isn&#8217;t the full definition in the runtime source, but I think it&#8217;s helpful to visualize the fields that explain how execution is managed.</p><p>A goroutine created from a simple function is tied to that function through the recorded entry in <code>g.startpc</code>. The runtime also prepares a start frame so execution jumps through <code>goexit</code> into your target function when the scheduler runs it.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!e3hG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3cbfed-ad31-4bd4-a289-5f252e218b6f_1130x244.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!e3hG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3cbfed-ad31-4bd4-a289-5f252e218b6f_1130x244.png 424w, https://substackcdn.com/image/fetch/$s_!e3hG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3cbfed-ad31-4bd4-a289-5f252e218b6f_1130x244.png 848w, https://substackcdn.com/image/fetch/$s_!e3hG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3cbfed-ad31-4bd4-a289-5f252e218b6f_1130x244.png 1272w, https://substackcdn.com/image/fetch/$s_!e3hG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3cbfed-ad31-4bd4-a289-5f252e218b6f_1130x244.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!e3hG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3cbfed-ad31-4bd4-a289-5f252e218b6f_1130x244.png" width="1130" height="244" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ed3cbfed-ad31-4bd4-a289-5f252e218b6f_1130x244.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:244,&quot;width&quot;:1130,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:24045,&quot;alt&quot;:&quot;func sayHello() {     println(\&quot;hello from G\&quot;) }  func main() {     go sayHello() }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180450298?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3cbfed-ad31-4bd4-a289-5f252e218b6f_1130x244.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="func sayHello() {     println(&quot;hello from G&quot;) }  func main() {     go sayHello() }" title="func sayHello() {     println(&quot;hello from G&quot;) }  func main() {     go sayHello() }" srcset="https://substackcdn.com/image/fetch/$s_!e3hG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3cbfed-ad31-4bd4-a289-5f252e218b6f_1130x244.png 424w, https://substackcdn.com/image/fetch/$s_!e3hG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3cbfed-ad31-4bd4-a289-5f252e218b6f_1130x244.png 848w, https://substackcdn.com/image/fetch/$s_!e3hG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3cbfed-ad31-4bd4-a289-5f252e218b6f_1130x244.png 1272w, https://substackcdn.com/image/fetch/$s_!e3hG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3cbfed-ad31-4bd4-a289-5f252e218b6f_1130x244.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>In this code, the G object points to <code>sayHello</code> as the entry point. When the scheduler picks it up, the goroutine begins at that function. From the developer&#8217;s perspective, it looks like a new function call running independently, but underneath it&#8217;s the G struct that makes it possible.</p><p>The G object also contains bookkeeping fields that the garbage collector and panic handler rely on. The runtime manages millions of goroutines efficiently because that information is stored in a single structure, with each one taking far less memory than a native thread would require.</p><h3>How the Runtime Sets up the Stack and Scheduler Link</h3><p>After a new goroutine is represented internally by a G object, the runtime must prepare memory for it to run and make sure it&#8217;s placed where the scheduler can pick it up. The goroutine doesn&#8217;t execute immediately at creation. Instead, it is first assigned stack memory, then attached to the scheduler&#8217;s data structures, and finally moved into a ready state.</p><h4>Initial Stack Allocation</h4><p>Each goroutine starts with a very small stack. The initial size is 2 KB and it grows on demand. This design allows Go to create hundreds of thousands of goroutines without exhausting memory. The runtime monitors stack use and can allocate a larger region when the goroutine needs more space.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FSd9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40ed5c34-4cab-474d-bddb-8793be9ba499_1119x317.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FSd9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40ed5c34-4cab-474d-bddb-8793be9ba499_1119x317.png 424w, https://substackcdn.com/image/fetch/$s_!FSd9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40ed5c34-4cab-474d-bddb-8793be9ba499_1119x317.png 848w, https://substackcdn.com/image/fetch/$s_!FSd9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40ed5c34-4cab-474d-bddb-8793be9ba499_1119x317.png 1272w, https://substackcdn.com/image/fetch/$s_!FSd9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40ed5c34-4cab-474d-bddb-8793be9ba499_1119x317.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FSd9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40ed5c34-4cab-474d-bddb-8793be9ba499_1119x317.png" width="1119" height="317" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/40ed5c34-4cab-474d-bddb-8793be9ba499_1119x317.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:317,&quot;width&quot;:1119,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:31212,&quot;alt&quot;:&quot;func deepCall(level int) {     if level > 0 {         deepCall(level - 1)     } }  func main() {     go deepCall(2000) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180450298?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40ed5c34-4cab-474d-bddb-8793be9ba499_1119x317.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="func deepCall(level int) {     if level > 0 {         deepCall(level - 1)     } }  func main() {     go deepCall(2000) }" title="func deepCall(level int) {     if level > 0 {         deepCall(level - 1)     } }  func main() {     go deepCall(2000) }" srcset="https://substackcdn.com/image/fetch/$s_!FSd9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40ed5c34-4cab-474d-bddb-8793be9ba499_1119x317.png 424w, https://substackcdn.com/image/fetch/$s_!FSd9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40ed5c34-4cab-474d-bddb-8793be9ba499_1119x317.png 848w, https://substackcdn.com/image/fetch/$s_!FSd9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40ed5c34-4cab-474d-bddb-8793be9ba499_1119x317.png 1272w, https://substackcdn.com/image/fetch/$s_!FSd9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40ed5c34-4cab-474d-bddb-8793be9ba499_1119x317.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>A recursive function like this forces the stack to expand as the depth increases. The runtime notices when the stack is about to run out of space and allocates a larger one. Existing frames are copied into the new area, and execution continues without interruption. The runtime tracks stack bounds in <code>g.stack.lo</code> and <code>g.stack.hi</code> inside the G object. These values are checked during execution to decide whether a new, larger stack is needed. That allows the goroutine to start small but still handle deeper call chains when required.</p><h4>Linking to the Scheduler</h4><p>A goroutine cannot run until it has been tied to the scheduler. The scheduler in Go operates with three primary entities:</p><ul><li><p>G for the goroutine</p></li><li><p>M for the machine, which is an operating system thread</p></li><li><p>P for the processor, which maintains a queue of goroutines and manages resources</p></li></ul><p>After stack allocation, the new <code>g</code> is put on the current <code>P</code>&#8217;s local run queue. If that queue is full, the runtime spills a batch to the global run queue and includes the new <code>g</code> there.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!e4th!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b50c458-2895-40f6-a929-e369322e0b92_1113x313.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!e4th!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b50c458-2895-40f6-a929-e369322e0b92_1113x313.png 424w, https://substackcdn.com/image/fetch/$s_!e4th!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b50c458-2895-40f6-a929-e369322e0b92_1113x313.png 848w, https://substackcdn.com/image/fetch/$s_!e4th!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b50c458-2895-40f6-a929-e369322e0b92_1113x313.png 1272w, https://substackcdn.com/image/fetch/$s_!e4th!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b50c458-2895-40f6-a929-e369322e0b92_1113x313.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!e4th!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b50c458-2895-40f6-a929-e369322e0b92_1113x313.png" width="1113" height="313" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0b50c458-2895-40f6-a929-e369322e0b92_1113x313.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:313,&quot;width&quot;:1113,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:32078,&quot;alt&quot;:&quot;func worker(id int) {     println(\&quot;worker\&quot;, id, \&quot;running\&quot;) }  func main() {     for i := 0; i < 10; i++ {         go worker(i)     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180450298?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b50c458-2895-40f6-a929-e369322e0b92_1113x313.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="func worker(id int) {     println(&quot;worker&quot;, id, &quot;running&quot;) }  func main() {     for i := 0; i < 10; i++ {         go worker(i)     } }" title="func worker(id int) {     println(&quot;worker&quot;, id, &quot;running&quot;) }  func main() {     for i := 0; i < 10; i++ {         go worker(i)     } }" srcset="https://substackcdn.com/image/fetch/$s_!e4th!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b50c458-2895-40f6-a929-e369322e0b92_1113x313.png 424w, https://substackcdn.com/image/fetch/$s_!e4th!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b50c458-2895-40f6-a929-e369322e0b92_1113x313.png 848w, https://substackcdn.com/image/fetch/$s_!e4th!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b50c458-2895-40f6-a929-e369322e0b92_1113x313.png 1272w, https://substackcdn.com/image/fetch/$s_!e4th!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b50c458-2895-40f6-a929-e369322e0b92_1113x313.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Here ten goroutines are created. Each one is given a G object and placed in a run queue tied to a P. Later, an M bound to that P will pick a G and begin execution. If all local queues are full, some of these goroutines may land in the global run queue, waiting for any processor to pick them up.</p><p>The separation into G, M, and P lets the scheduler spread goroutines across available cores. It also gives the runtime a way to balance work by stealing goroutines from one processor&#8217;s queue if another runs out of work.</p><h4>Ready State and Scheduling</h4><p>After a G is linked to a queue, its status is set to ready. That means the scheduler can choose it whenever an M is available. Goroutines don&#8217;t run until a machine thread picks them, which may happen immediately or after some delay depending on how much work is already in the system.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yXWm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae80cdbb-01b0-49f9-b4d3-45fc5230a30d_1058x350.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yXWm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae80cdbb-01b0-49f9-b4d3-45fc5230a30d_1058x350.png 424w, https://substackcdn.com/image/fetch/$s_!yXWm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae80cdbb-01b0-49f9-b4d3-45fc5230a30d_1058x350.png 848w, https://substackcdn.com/image/fetch/$s_!yXWm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae80cdbb-01b0-49f9-b4d3-45fc5230a30d_1058x350.png 1272w, https://substackcdn.com/image/fetch/$s_!yXWm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae80cdbb-01b0-49f9-b4d3-45fc5230a30d_1058x350.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yXWm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae80cdbb-01b0-49f9-b4d3-45fc5230a30d_1058x350.png" width="1058" height="350" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ae80cdbb-01b0-49f9-b4d3-45fc5230a30d_1058x350.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:350,&quot;width&quot;:1058,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:36902,&quot;alt&quot;:&quot;func printLetters() {     for c := 'a'; c <= 'd'; c++ {         println(string(c))     } }  func main() {     go printLetters()     go printLetters() }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180450298?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae80cdbb-01b0-49f9-b4d3-45fc5230a30d_1058x350.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="func printLetters() {     for c := 'a'; c <= 'd'; c++ {         println(string(c))     } }  func main() {     go printLetters()     go printLetters() }" title="func printLetters() {     for c := 'a'; c <= 'd'; c++ {         println(string(c))     } }  func main() {     go printLetters()     go printLetters() }" srcset="https://substackcdn.com/image/fetch/$s_!yXWm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae80cdbb-01b0-49f9-b4d3-45fc5230a30d_1058x350.png 424w, https://substackcdn.com/image/fetch/$s_!yXWm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae80cdbb-01b0-49f9-b4d3-45fc5230a30d_1058x350.png 848w, https://substackcdn.com/image/fetch/$s_!yXWm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae80cdbb-01b0-49f9-b4d3-45fc5230a30d_1058x350.png 1272w, https://substackcdn.com/image/fetch/$s_!yXWm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae80cdbb-01b0-49f9-b4d3-45fc5230a30d_1058x350.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Both goroutines created in this code will sit in ready state before being scheduled. One may run quickly while the other waits until a machine thread becomes available. From the perspective of user code they appear concurrent, but under the runtime they&#8217;re pulled from queues, assigned to threads, and managed through scheduling decisions.</p><p>After execution begins, the goroutine continues until it blocks on I/O, system calls, or yields back to the scheduler. At that point it may return to a queue and another ready G takes its place. The ready state is therefore the bridge between creation and execution, allowing new goroutines to enter the flow of work without being lost.</p><h3>Conclusion</h3><p>The mechanics behind goroutine creation reveal how much the Go runtime does once the <code>go</code> keyword is written. From the compiler routing calls into <code>newproc</code>, to the allocation of a small expandable stack, and finally to the scheduler linking the new G into run queues, each stage works together to keep goroutines lightweight while still bound to structured control. This design lets millions of them run within a single process, with the runtime carefully managing memory and scheduling so developers only need a short keyword to create concurrency.</p><ol><li><p><em><a href="https://pkg.go.dev/runtime">Go Runtime Package Documentation</a></em></p></li><li><p><em><a href="https://go.dev/doc/effective_go#concurrency">Go Concurrency Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/runtime#hdr-Scheduler_Traces">Scheduler Tracing with GODEBUG</a></em></p></li><li><p><em><a href="https://cs.opensource.google/go/go/+/refs/tags/go1.22.0:src/runtime/">Go Source Code for Runtime</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Sysmon Thread in Go Runtime]]></title><description><![CDATA[System-level work in Go doesn&#8217;t all run inside user goroutines.]]></description><link>https://alexanderobregon.substack.com/p/sysmon-thread-in-go-runtime</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/sysmon-thread-in-go-runtime</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Thu, 27 Nov 2025 18:17:04 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/2afb78a6-535f-433d-b22d-cfcbf71d8a4e_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vmYO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vmYO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!vmYO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>How the Sysmon Thread Works in Go</h3><p>The sysmon thread exists to handle work that can&#8217;t be left to the regular scheduler loop. While goroutines drive application logic, the sysmon thread keeps track of system events, timers, and scheduling fairness. It quietly runs alongside everything else, waking at intervals to do checks that keep execution smooth. This background presence is what makes deadlines fire at the right time, prevents CPU starvation, and keeps long-running servers from drifting out of balance.</p><h4>Monitoring System Calls</h4><p>When a goroutine makes a blocking system call, the runtime cannot predict how long it will be stuck waiting. A file read from a slow disk or a network request over a congested connection could take milliseconds or seconds. If the scheduler assumed that goroutine was still making progress, other goroutines could be delayed. The sysmon thread helps by scanning for operating system threads that remain blocked too long and then reassigns ready goroutines to threads that are free.</p><p>This ability is particularly important for workloads that rely heavily on network or file operations. It means a single blocked call won&#8217;t freeze all goroutines tied to that thread. To get a sense of this, imagine a function that makes a long read:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jEEP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58208a-8d63-4f5b-a2b1-a488fcf7b0d2_1050x663.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jEEP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58208a-8d63-4f5b-a2b1-a488fcf7b0d2_1050x663.png 424w, https://substackcdn.com/image/fetch/$s_!jEEP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58208a-8d63-4f5b-a2b1-a488fcf7b0d2_1050x663.png 848w, https://substackcdn.com/image/fetch/$s_!jEEP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58208a-8d63-4f5b-a2b1-a488fcf7b0d2_1050x663.png 1272w, https://substackcdn.com/image/fetch/$s_!jEEP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58208a-8d63-4f5b-a2b1-a488fcf7b0d2_1050x663.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jEEP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58208a-8d63-4f5b-a2b1-a488fcf7b0d2_1050x663.png" width="1050" height="663" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4d58208a-8d63-4f5b-a2b1-a488fcf7b0d2_1050x663.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:663,&quot;width&quot;:1050,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:81073,&quot;alt&quot;:&quot;package main  import (     \&quot;fmt\&quot;     \&quot;os\&quot; )  func main() {     f, err := os.Open(\&quot;largefile.log\&quot;)     if err != nil {         panic(err)     }     buf := make([]byte, 1024*1024)     n, err := f.Read(buf) // may block at the system call level     if err != nil {         panic(err)     }     fmt.Println(\&quot;Read bytes:\&quot;, n) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180061529?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58208a-8d63-4f5b-a2b1-a488fcf7b0d2_1050x663.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (     &quot;fmt&quot;     &quot;os&quot; )  func main() {     f, err := os.Open(&quot;largefile.log&quot;)     if err != nil {         panic(err)     }     buf := make([]byte, 1024*1024)     n, err := f.Read(buf) // may block at the system call level     if err != nil {         panic(err)     }     fmt.Println(&quot;Read bytes:&quot;, n) }" title="package main  import (     &quot;fmt&quot;     &quot;os&quot; )  func main() {     f, err := os.Open(&quot;largefile.log&quot;)     if err != nil {         panic(err)     }     buf := make([]byte, 1024*1024)     n, err := f.Read(buf) // may block at the system call level     if err != nil {         panic(err)     }     fmt.Println(&quot;Read bytes:&quot;, n) }" srcset="https://substackcdn.com/image/fetch/$s_!jEEP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58208a-8d63-4f5b-a2b1-a488fcf7b0d2_1050x663.png 424w, https://substackcdn.com/image/fetch/$s_!jEEP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58208a-8d63-4f5b-a2b1-a488fcf7b0d2_1050x663.png 848w, https://substackcdn.com/image/fetch/$s_!jEEP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58208a-8d63-4f5b-a2b1-a488fcf7b0d2_1050x663.png 1272w, https://substackcdn.com/image/fetch/$s_!jEEP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d58208a-8d63-4f5b-a2b1-a488fcf7b0d2_1050x663.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>During the call to <code>f.Read</code>, the goroutine can block in the kernel. If that thread holds a <code>P</code> for too long, <code>sysmon</code> retakes the <code>P</code> so other runnable goroutines keep executing. That simple redistribution is why Go scales well across many concurrent operations.</p><h4>Driving Timers</h4><p>Timers are a fundamental building block in Go. Functions like <code>time.NewTimer</code>, <code>time.After</code>, and <code>time.Ticker</code> all rely on accurate tracking of deadlines. The runtime keeps per <code>P</code> timer heaps and relies on the <code>netpoll</code> waiter for the next deadline. When a timer expires, the scheduler readies the waiting goroutine. The <code>sysmon</code> thread makes sure there&#8217;s an idle <code>M</code> blocked in <code>netpoll</code> when needed and starts work when events or deadlines show up. This isn&#8217;t only about delays measured in seconds. Many servers and clients depend on millisecond-level accuracy to enforce request deadlines or connection limits. Without the sysmon thread, expired timers could sit in the heap unnoticed for long stretches, breaking the reliability of those guarantees.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!81-Q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa62f0313-f58c-4b18-8a9a-c024ee0e3c78_1056x769.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!81-Q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa62f0313-f58c-4b18-8a9a-c024ee0e3c78_1056x769.png 424w, https://substackcdn.com/image/fetch/$s_!81-Q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa62f0313-f58c-4b18-8a9a-c024ee0e3c78_1056x769.png 848w, https://substackcdn.com/image/fetch/$s_!81-Q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa62f0313-f58c-4b18-8a9a-c024ee0e3c78_1056x769.png 1272w, https://substackcdn.com/image/fetch/$s_!81-Q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa62f0313-f58c-4b18-8a9a-c024ee0e3c78_1056x769.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!81-Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa62f0313-f58c-4b18-8a9a-c024ee0e3c78_1056x769.png" width="1056" height="769" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a62f0313-f58c-4b18-8a9a-c024ee0e3c78_1056x769.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:769,&quot;width&quot;:1056,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:92235,&quot;alt&quot;:&quot;package main  import (     \&quot;fmt\&quot;     \&quot;time\&quot; )  func main() {     t := time.NewTimer(1500 * time.Millisecond)     <-t.C     fmt.Println(\&quot;1500ms timer fired\&quot;)      ticker := time.NewTicker(1 * time.Second)     go func() {         for ts := range ticker.C {             fmt.Println(\&quot;Tick at\&quot;, ts)         }     }()      time.Sleep(3500 * time.Millisecond)     ticker.Stop() }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180061529?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa62f0313-f58c-4b18-8a9a-c024ee0e3c78_1056x769.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (     &quot;fmt&quot;     &quot;time&quot; )  func main() {     t := time.NewTimer(1500 * time.Millisecond)     <-t.C     fmt.Println(&quot;1500ms timer fired&quot;)      ticker := time.NewTicker(1 * time.Second)     go func() {         for ts := range ticker.C {             fmt.Println(&quot;Tick at&quot;, ts)         }     }()      time.Sleep(3500 * time.Millisecond)     ticker.Stop() }" title="package main  import (     &quot;fmt&quot;     &quot;time&quot; )  func main() {     t := time.NewTimer(1500 * time.Millisecond)     <-t.C     fmt.Println(&quot;1500ms timer fired&quot;)      ticker := time.NewTicker(1 * time.Second)     go func() {         for ts := range ticker.C {             fmt.Println(&quot;Tick at&quot;, ts)         }     }()      time.Sleep(3500 * time.Millisecond)     ticker.Stop() }" srcset="https://substackcdn.com/image/fetch/$s_!81-Q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa62f0313-f58c-4b18-8a9a-c024ee0e3c78_1056x769.png 424w, https://substackcdn.com/image/fetch/$s_!81-Q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa62f0313-f58c-4b18-8a9a-c024ee0e3c78_1056x769.png 848w, https://substackcdn.com/image/fetch/$s_!81-Q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa62f0313-f58c-4b18-8a9a-c024ee0e3c78_1056x769.png 1272w, https://substackcdn.com/image/fetch/$s_!81-Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa62f0313-f58c-4b18-8a9a-c024ee0e3c78_1056x769.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Here, the timer and ticker depend on the per <code>P</code> timer heaps and <code>netpoll</code> deadlines. The runtime parks an idle <code>M</code> in <code>netpoll</code> with the nearest timer deadline, and <code>sysmon</code> kicks scheduling if events or deadlines arrive. This interplay makes Go&#8217;s timing constructs dependable even across thousands of concurrent goroutines.</p><h4>Preempting Long Running Goroutines</h4><p>Without preemption, a goroutine that performs heavy CPU work could occupy a thread indefinitely. Cooperative scheduling alone depends on goroutines reaching safe points and yielding, but code doesn&#8217;t always do that quickly enough. <code>sysmon</code> requests preemption of long-running goroutines so others can run. The runtime performs asynchronous preemption at safe points.</p><p>This keeps the system fair, letting others make progress even if one is consuming cycles in a loop. Consider a worker function like this:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TOK1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf6dc126-6a06-4c67-b744-ec994507379e_1115x522.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TOK1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf6dc126-6a06-4c67-b744-ec994507379e_1115x522.png 424w, https://substackcdn.com/image/fetch/$s_!TOK1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf6dc126-6a06-4c67-b744-ec994507379e_1115x522.png 848w, https://substackcdn.com/image/fetch/$s_!TOK1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf6dc126-6a06-4c67-b744-ec994507379e_1115x522.png 1272w, https://substackcdn.com/image/fetch/$s_!TOK1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf6dc126-6a06-4c67-b744-ec994507379e_1115x522.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TOK1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf6dc126-6a06-4c67-b744-ec994507379e_1115x522.png" width="1115" height="522" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/df6dc126-6a06-4c67-b744-ec994507379e_1115x522.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:522,&quot;width&quot;:1115,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:59630,&quot;alt&quot;:&quot;package main  import \&quot;math\&quot;  func busyWork() {     for i := 0; i < 1e9; i++ {         math.Sqrt(float64(i)) // heavy calculation     } }  func main() {     go busyWork()     go busyWork()     select {} }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180061529?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf6dc126-6a06-4c67-b744-ec994507379e_1115x522.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;math&quot;  func busyWork() {     for i := 0; i < 1e9; i++ {         math.Sqrt(float64(i)) // heavy calculation     } }  func main() {     go busyWork()     go busyWork()     select {} }" title="package main  import &quot;math&quot;  func busyWork() {     for i := 0; i < 1e9; i++ {         math.Sqrt(float64(i)) // heavy calculation     } }  func main() {     go busyWork()     go busyWork()     select {} }" srcset="https://substackcdn.com/image/fetch/$s_!TOK1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf6dc126-6a06-4c67-b744-ec994507379e_1115x522.png 424w, https://substackcdn.com/image/fetch/$s_!TOK1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf6dc126-6a06-4c67-b744-ec994507379e_1115x522.png 848w, https://substackcdn.com/image/fetch/$s_!TOK1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf6dc126-6a06-4c67-b744-ec994507379e_1115x522.png 1272w, https://substackcdn.com/image/fetch/$s_!TOK1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf6dc126-6a06-4c67-b744-ec994507379e_1115x522.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Both goroutines run an expensive loop. Without the sysmon thread enforcing preemption, one could monopolize a thread and delay the other indefinitely. Instead, the sysmon thread steps in and makes sure that the time is shared across them. This is invisible to the programmer, but it&#8217;s the reason Go&#8217;s scheduler remains fair even with workloads that lean on CPU.</p><p>For developers writing compute-heavy code, this means other goroutines won&#8217;t starve. Long computations still progress, but they&#8217;re broken into time slices that let the rest of the system stay responsive.</p><h4>Scheduling Delayed Events</h4><p>The sysmon thread also performs regular checks for runtime events not directly tied to user timers. Memory scavenging is one example. Go&#8217;s garbage collector reclaims memory inside the runtime, but returning unused memory back to the operating system requires periodic work. The sysmon thread triggers this process without pausing normal execution. GC timing is driven by the GC pacer and heap growth targets. <code>sysmon</code> does two different things here: it can force a GC if none has run for about two minutes via <code>forcegcperiod</code>, and it can wake the scavenger that returns pages to the OS. Developers don&#8217;t usually see this directly, but they benefit from a system that doesn&#8217;t grow memory usage endlessly.</p><p>Here&#8217;s some simple code that allocates memory repeatedly:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!05C6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda391e25-e4cf-4002-8d60-a2b3bb9b895d_1124x245.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!05C6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda391e25-e4cf-4002-8d60-a2b3bb9b895d_1124x245.png 424w, https://substackcdn.com/image/fetch/$s_!05C6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda391e25-e4cf-4002-8d60-a2b3bb9b895d_1124x245.png 848w, https://substackcdn.com/image/fetch/$s_!05C6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda391e25-e4cf-4002-8d60-a2b3bb9b895d_1124x245.png 1272w, https://substackcdn.com/image/fetch/$s_!05C6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda391e25-e4cf-4002-8d60-a2b3bb9b895d_1124x245.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!05C6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda391e25-e4cf-4002-8d60-a2b3bb9b895d_1124x245.png" width="1124" height="245" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/da391e25-e4cf-4002-8d60-a2b3bb9b895d_1124x245.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:245,&quot;width&quot;:1124,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:29575,&quot;alt&quot;:&quot;package main  func main() {     for {         _ = make([]byte, 10*1024*1024) // allocate 10MB     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180061529?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda391e25-e4cf-4002-8d60-a2b3bb9b895d_1124x245.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  func main() {     for {         _ = make([]byte, 10*1024*1024) // allocate 10MB     } }" title="package main  func main() {     for {         _ = make([]byte, 10*1024*1024) // allocate 10MB     } }" srcset="https://substackcdn.com/image/fetch/$s_!05C6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda391e25-e4cf-4002-8d60-a2b3bb9b895d_1124x245.png 424w, https://substackcdn.com/image/fetch/$s_!05C6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda391e25-e4cf-4002-8d60-a2b3bb9b895d_1124x245.png 848w, https://substackcdn.com/image/fetch/$s_!05C6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda391e25-e4cf-4002-8d60-a2b3bb9b895d_1124x245.png 1272w, https://substackcdn.com/image/fetch/$s_!05C6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda391e25-e4cf-4002-8d60-a2b3bb9b895d_1124x245.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Running this without scavenging would push memory usage upward and never release it. The sysmon thread helps schedule background work that eventually hands memory back to the operating system. That&#8217;s why long-running servers built in Go can stay stable without ballooning in memory over time.</p><p>The scheduling of these delayed events reflects the runtime&#8217;s need to coordinate work at different levels. Application code runs in goroutines, but the sysmon thread takes care of the background tasks that keep the runtime itself healthy. Without it, timers would drift, blocked system calls would trap threads, and memory management would fail to keep up.</p><h3>Why the Sysmon Thread Matters</h3><p>The sysmon thread doesn&#8217;t run application logic directly, yet without it the Go runtime wouldn&#8217;t behave reliably. Its work provides stability to the scheduler, accuracy to timers, fairness across goroutines, and background upkeep that keeps long-running processes in balance. Developers rarely interact with this thread, but every Go program depends on it in one way or another.</p><h4>Keeping the Scheduler Moving</h4><p>Goroutines need to be scheduled across operating system threads. If one thread becomes stuck waiting for a system call, the scheduler has to find other places to run the goroutines that are still ready. The sysmon thread performs scans to detect these situations and helps the runtime move work elsewhere. That way the system as a whole keeps moving forward even when parts of it are waiting on I/O.</p><p>Consider a server that spawns goroutines for each incoming connection. Some connections are quick, while others stall on slow clients. Without sysmon stepping in, stalled goroutines could tie up threads for long stretches.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9iLb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9123d549-3bfb-47d6-8417-9a3f7d7eccc9_1116x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9iLb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9123d549-3bfb-47d6-8417-9a3f7d7eccc9_1116x768.png 424w, https://substackcdn.com/image/fetch/$s_!9iLb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9123d549-3bfb-47d6-8417-9a3f7d7eccc9_1116x768.png 848w, https://substackcdn.com/image/fetch/$s_!9iLb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9123d549-3bfb-47d6-8417-9a3f7d7eccc9_1116x768.png 1272w, https://substackcdn.com/image/fetch/$s_!9iLb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9123d549-3bfb-47d6-8417-9a3f7d7eccc9_1116x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9iLb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9123d549-3bfb-47d6-8417-9a3f7d7eccc9_1116x768.png" width="1116" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9123d549-3bfb-47d6-8417-9a3f7d7eccc9_1116x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1116,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:94051,&quot;alt&quot;:&quot;package main  import (     \&quot;fmt\&quot;     \&quot;net\&quot; )  func handleConn(c net.Conn) {     buf := make([]byte, 1024)     // Read may block if the client stops sending data     _, _ = c.Read(buf)     fmt.Println(\&quot;Finished handling client\&quot;)     c.Close() }  func main() {     ln, _ := net.Listen(\&quot;tcp\&quot;, \&quot;:8081\&quot;)     for {         conn, _ := ln.Accept()         go handleConn(conn)     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180061529?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9123d549-3bfb-47d6-8417-9a3f7d7eccc9_1116x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (     &quot;fmt&quot;     &quot;net&quot; )  func handleConn(c net.Conn) {     buf := make([]byte, 1024)     // Read may block if the client stops sending data     _, _ = c.Read(buf)     fmt.Println(&quot;Finished handling client&quot;)     c.Close() }  func main() {     ln, _ := net.Listen(&quot;tcp&quot;, &quot;:8081&quot;)     for {         conn, _ := ln.Accept()         go handleConn(conn)     } }" title="package main  import (     &quot;fmt&quot;     &quot;net&quot; )  func handleConn(c net.Conn) {     buf := make([]byte, 1024)     // Read may block if the client stops sending data     _, _ = c.Read(buf)     fmt.Println(&quot;Finished handling client&quot;)     c.Close() }  func main() {     ln, _ := net.Listen(&quot;tcp&quot;, &quot;:8081&quot;)     for {         conn, _ := ln.Accept()         go handleConn(conn)     } }" srcset="https://substackcdn.com/image/fetch/$s_!9iLb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9123d549-3bfb-47d6-8417-9a3f7d7eccc9_1116x768.png 424w, https://substackcdn.com/image/fetch/$s_!9iLb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9123d549-3bfb-47d6-8417-9a3f7d7eccc9_1116x768.png 848w, https://substackcdn.com/image/fetch/$s_!9iLb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9123d549-3bfb-47d6-8417-9a3f7d7eccc9_1116x768.png 1272w, https://substackcdn.com/image/fetch/$s_!9iLb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9123d549-3bfb-47d6-8417-9a3f7d7eccc9_1116x768.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>A client that connects but never sends data would leave a goroutine blocked inside <code>Read</code>. The sysmon thread prevents that blocked goroutine from holding up the rest of the server by making sure that the other goroutines continue running on available threads.</p><h4>Accurate Timers and Deadlines</h4><p>Deadlines in Go are only useful if they&#8217;re fired precisely. The <code>sysmon</code> thread checks pending timers across the per-<code>P</code> heaps and makes sure expired timers wake the goroutines waiting on them. Without this, network timeouts and request deadlines wouldn&#8217;t behave predictably.</p><p>One option is setting a timeout on a network dial. The timeout depends entirely on the timer being serviced promptly.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ow8Z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996ae64a-e9b5-4de2-9815-8ea92425248d_1099x522.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ow8Z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996ae64a-e9b5-4de2-9815-8ea92425248d_1099x522.png 424w, https://substackcdn.com/image/fetch/$s_!Ow8Z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996ae64a-e9b5-4de2-9815-8ea92425248d_1099x522.png 848w, https://substackcdn.com/image/fetch/$s_!Ow8Z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996ae64a-e9b5-4de2-9815-8ea92425248d_1099x522.png 1272w, https://substackcdn.com/image/fetch/$s_!Ow8Z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996ae64a-e9b5-4de2-9815-8ea92425248d_1099x522.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ow8Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996ae64a-e9b5-4de2-9815-8ea92425248d_1099x522.png" width="1099" height="522" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/996ae64a-e9b5-4de2-9815-8ea92425248d_1099x522.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:522,&quot;width&quot;:1099,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:60028,&quot;alt&quot;:&quot;package main  import (     \&quot;fmt\&quot;     \&quot;net\&quot;     \&quot;time\&quot; )  func main() {     d := net.Dialer{Timeout: 2 * time.Second}     _, err := d.Dial(\&quot;tcp\&quot;, \&quot;192.0.2.1:1234\&quot;) // unreachable     if err != nil {         fmt.Println(\&quot;Dial failed with timeout:\&quot;, err)     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180061529?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996ae64a-e9b5-4de2-9815-8ea92425248d_1099x522.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (     &quot;fmt&quot;     &quot;net&quot;     &quot;time&quot; )  func main() {     d := net.Dialer{Timeout: 2 * time.Second}     _, err := d.Dial(&quot;tcp&quot;, &quot;192.0.2.1:1234&quot;) // unreachable     if err != nil {         fmt.Println(&quot;Dial failed with timeout:&quot;, err)     } }" title="package main  import (     &quot;fmt&quot;     &quot;net&quot;     &quot;time&quot; )  func main() {     d := net.Dialer{Timeout: 2 * time.Second}     _, err := d.Dial(&quot;tcp&quot;, &quot;192.0.2.1:1234&quot;) // unreachable     if err != nil {         fmt.Println(&quot;Dial failed with timeout:&quot;, err)     } }" srcset="https://substackcdn.com/image/fetch/$s_!Ow8Z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996ae64a-e9b5-4de2-9815-8ea92425248d_1099x522.png 424w, https://substackcdn.com/image/fetch/$s_!Ow8Z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996ae64a-e9b5-4de2-9815-8ea92425248d_1099x522.png 848w, https://substackcdn.com/image/fetch/$s_!Ow8Z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996ae64a-e9b5-4de2-9815-8ea92425248d_1099x522.png 1272w, https://substackcdn.com/image/fetch/$s_!Ow8Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F996ae64a-e9b5-4de2-9815-8ea92425248d_1099x522.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The dialer here relies on the sysmon thread to wake the timer after two seconds. Without it, the operation could hang indefinitely.</p><p>Timers are not limited to network timeouts. They&#8217;re also behind scheduled jobs, delayed retries, and heartbeat signals. A ticker that drives periodic updates, for example, also depends on the sysmon thread:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mafW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb73cf0e1-49cd-4506-b72a-89cde4c3d8a2_1096x593.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mafW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb73cf0e1-49cd-4506-b72a-89cde4c3d8a2_1096x593.png 424w, https://substackcdn.com/image/fetch/$s_!mafW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb73cf0e1-49cd-4506-b72a-89cde4c3d8a2_1096x593.png 848w, https://substackcdn.com/image/fetch/$s_!mafW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb73cf0e1-49cd-4506-b72a-89cde4c3d8a2_1096x593.png 1272w, https://substackcdn.com/image/fetch/$s_!mafW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb73cf0e1-49cd-4506-b72a-89cde4c3d8a2_1096x593.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mafW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb73cf0e1-49cd-4506-b72a-89cde4c3d8a2_1096x593.png" width="1096" height="593" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b73cf0e1-49cd-4506-b72a-89cde4c3d8a2_1096x593.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:593,&quot;width&quot;:1096,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:69811,&quot;alt&quot;:&quot;package main  import (     \&quot;fmt\&quot;     \&quot;time\&quot; )  func main() {     ticker := time.NewTicker(500 * time.Millisecond)     go func() {         for t := range ticker.C {             fmt.Println(\&quot;Heartbeat at\&quot;, t)         }     }()     time.Sleep(2 * time.Second)     ticker.Stop() }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180061529?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb73cf0e1-49cd-4506-b72a-89cde4c3d8a2_1096x593.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (     &quot;fmt&quot;     &quot;time&quot; )  func main() {     ticker := time.NewTicker(500 * time.Millisecond)     go func() {         for t := range ticker.C {             fmt.Println(&quot;Heartbeat at&quot;, t)         }     }()     time.Sleep(2 * time.Second)     ticker.Stop() }" title="package main  import (     &quot;fmt&quot;     &quot;time&quot; )  func main() {     ticker := time.NewTicker(500 * time.Millisecond)     go func() {         for t := range ticker.C {             fmt.Println(&quot;Heartbeat at&quot;, t)         }     }()     time.Sleep(2 * time.Second)     ticker.Stop() }" srcset="https://substackcdn.com/image/fetch/$s_!mafW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb73cf0e1-49cd-4506-b72a-89cde4c3d8a2_1096x593.png 424w, https://substackcdn.com/image/fetch/$s_!mafW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb73cf0e1-49cd-4506-b72a-89cde4c3d8a2_1096x593.png 848w, https://substackcdn.com/image/fetch/$s_!mafW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb73cf0e1-49cd-4506-b72a-89cde4c3d8a2_1096x593.png 1272w, https://substackcdn.com/image/fetch/$s_!mafW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb73cf0e1-49cd-4506-b72a-89cde4c3d8a2_1096x593.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The steady rhythm of the ticker reflects the sysmon thread scanning timers and scheduling their events on time.</p><h4>Preemptive Fairness</h4><p>Fairness across goroutines is another area where the sysmon thread has direct impact. CPU-heavy goroutines don&#8217;t always yield naturally, which could allow them to run for extended periods while other goroutines starve. The sysmon thread interrupts those long runs by requesting preemption once they exceed their time slice.</p><p>This feature makes Go suitable for mixed workloads. A program can juggle network servers alongside compute-intensive goroutines without one category blocking the other.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gVbg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ff84970-b2bc-4374-b8b7-dadba13bc415_1111x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gVbg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ff84970-b2bc-4374-b8b7-dadba13bc415_1111x768.png 424w, https://substackcdn.com/image/fetch/$s_!gVbg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ff84970-b2bc-4374-b8b7-dadba13bc415_1111x768.png 848w, https://substackcdn.com/image/fetch/$s_!gVbg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ff84970-b2bc-4374-b8b7-dadba13bc415_1111x768.png 1272w, https://substackcdn.com/image/fetch/$s_!gVbg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ff84970-b2bc-4374-b8b7-dadba13bc415_1111x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gVbg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ff84970-b2bc-4374-b8b7-dadba13bc415_1111x768.png" width="1111" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8ff84970-b2bc-4374-b8b7-dadba13bc415_1111x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1111,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:90916,&quot;alt&quot;:&quot;package main  import (     \&quot;fmt\&quot;     \&quot;time\&quot; )  func cpuHeavy() {     for i := 0; i < 1e8; i++ {         // burn CPU     }     fmt.Println(\&quot;Finished heavy work\&quot;) }  func main() {     go cpuHeavy()     go func() {         time.Sleep(500 * time.Millisecond)         fmt.Println(\&quot;Timer fired during heavy work\&quot;)     }()     time.Sleep(2 * time.Second) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180061529?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ff84970-b2bc-4374-b8b7-dadba13bc415_1111x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (     &quot;fmt&quot;     &quot;time&quot; )  func cpuHeavy() {     for i := 0; i < 1e8; i++ {         // burn CPU     }     fmt.Println(&quot;Finished heavy work&quot;) }  func main() {     go cpuHeavy()     go func() {         time.Sleep(500 * time.Millisecond)         fmt.Println(&quot;Timer fired during heavy work&quot;)     }()     time.Sleep(2 * time.Second) }" title="package main  import (     &quot;fmt&quot;     &quot;time&quot; )  func cpuHeavy() {     for i := 0; i < 1e8; i++ {         // burn CPU     }     fmt.Println(&quot;Finished heavy work&quot;) }  func main() {     go cpuHeavy()     go func() {         time.Sleep(500 * time.Millisecond)         fmt.Println(&quot;Timer fired during heavy work&quot;)     }()     time.Sleep(2 * time.Second) }" srcset="https://substackcdn.com/image/fetch/$s_!gVbg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ff84970-b2bc-4374-b8b7-dadba13bc415_1111x768.png 424w, https://substackcdn.com/image/fetch/$s_!gVbg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ff84970-b2bc-4374-b8b7-dadba13bc415_1111x768.png 848w, https://substackcdn.com/image/fetch/$s_!gVbg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ff84970-b2bc-4374-b8b7-dadba13bc415_1111x768.png 1272w, https://substackcdn.com/image/fetch/$s_!gVbg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ff84970-b2bc-4374-b8b7-dadba13bc415_1111x768.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Even though one goroutine spends time in a large loop, the sleeping goroutine&#8217;s timer still fires because sysmon forces the heavy loop to pause at safe points. The output reflects that fairness, keeping the system responsive even when workloads vary.</p><h4>System Stability</h4><p>The sysmon thread doesn&#8217;t just service timers and preemption. It also handles background duties that make Go stable in production. Memory scavenging is one such duty, where unused memory is handed back to the operating system. Without this, long-running processes would consume memory indefinitely even after internal reuse dropped. There&#8217;s also the matter of coordinating with garbage collection. The runtime has to decide when to trigger collection cycles, and sysmon provides pacing signals to keep those cycles in balance with allocation pressure. Developers rarely see this interaction directly, but the stability of long-lived services depends on it.</p><p>Consider a service that keeps a growing in-memory buffer for work items:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0Nk-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbcbbff9-38f8-4494-9242-aa721ea383d2_1197x451.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0Nk-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbcbbff9-38f8-4494-9242-aa721ea383d2_1197x451.png 424w, https://substackcdn.com/image/fetch/$s_!0Nk-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbcbbff9-38f8-4494-9242-aa721ea383d2_1197x451.png 848w, https://substackcdn.com/image/fetch/$s_!0Nk-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbcbbff9-38f8-4494-9242-aa721ea383d2_1197x451.png 1272w, https://substackcdn.com/image/fetch/$s_!0Nk-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbcbbff9-38f8-4494-9242-aa721ea383d2_1197x451.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0Nk-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbcbbff9-38f8-4494-9242-aa721ea383d2_1197x451.png" width="1197" height="451" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cbcbbff9-38f8-4494-9242-aa721ea383d2_1197x451.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:451,&quot;width&quot;:1197,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:84476,&quot;alt&quot;:&quot;package main  func main() {     buf := make([]byte, 0, 100*1024*1024) // 100MB cap     for {         // grow the buffer in chunks         chunk := make([]byte, 5*1024*1024)         buf = append(buf, chunk...)         if len(buf) > cap(buf)/2 {             buf = buf[:0] // drop its contents and free space internally         }     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180061529?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbcbbff9-38f8-4494-9242-aa721ea383d2_1197x451.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  func main() {     buf := make([]byte, 0, 100*1024*1024) // 100MB cap     for {         // grow the buffer in chunks         chunk := make([]byte, 5*1024*1024)         buf = append(buf, chunk...)         if len(buf) > cap(buf)/2 {             buf = buf[:0] // drop its contents and free space internally         }     } }" title="package main  func main() {     buf := make([]byte, 0, 100*1024*1024) // 100MB cap     for {         // grow the buffer in chunks         chunk := make([]byte, 5*1024*1024)         buf = append(buf, chunk...)         if len(buf) > cap(buf)/2 {             buf = buf[:0] // drop its contents and free space internally         }     } }" srcset="https://substackcdn.com/image/fetch/$s_!0Nk-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbcbbff9-38f8-4494-9242-aa721ea383d2_1197x451.png 424w, https://substackcdn.com/image/fetch/$s_!0Nk-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbcbbff9-38f8-4494-9242-aa721ea383d2_1197x451.png 848w, https://substackcdn.com/image/fetch/$s_!0Nk-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbcbbff9-38f8-4494-9242-aa721ea383d2_1197x451.png 1272w, https://substackcdn.com/image/fetch/$s_!0Nk-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbcbbff9-38f8-4494-9242-aa721ea383d2_1197x451.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This pattern builds pressure in waves rather than a constant stream. Without <code>sysmon</code> coordinating scavenging and helping the GC return unused spans, the process would gradually settle at a high watermark and hold far more memory than it needs. With <code>sysmon</code> active, the runtime trims that footprint over time so the service doesn&#8217;t drift upward after repeated growth-and-drop cycles.</p><p>The stability benefits also extend to smaller periodic checks inside the runtime. The sysmon thread wakes at short intervals to see if timers are pending, if system calls are blocking too long, or if background cleanups are needed. All of these keep Go applications balanced without developers having to manage those details directly.</p><h3>Conclusion</h3><p>The sysmon thread is the quiet worker that keeps the Go runtime balanced. It monitors blocking system calls, wakes timers with precision, forces preemption when goroutines overstay their time on the CPU, and schedules background work like memory reclamation. Each of these mechanics supports the runtime in ways that aren&#8217;t visible to developers but directly affect how Go applications behave in practice. Without this thread, timers would drift, blocked calls would freeze progress, and memory use would grow unchecked. With it running in the background, Go can manage thousands of goroutines with steady scheduling and reliable timing.</p><ol><li><p><em><a href="https://golang.org/src/runtime/proc.go">Go Runtime Scheduler</a></em></p></li><li><p><em><a href="https://pkg.go.dev/time#hdr-Timers">Go Timers Documentation</a></em></p></li><li><p><em><a href="https://golang.org/doc/gc-guide">Go Memory Management</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Go Build ID and Reproducibility]]></title><description><![CDATA[Modern software needs to be compiled in a way that produces the same binary across different machines and environments.]]></description><link>https://alexanderobregon.substack.com/p/go-build-id-and-reproducibility</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/go-build-id-and-reproducibility</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Wed, 26 Nov 2025 21:02:07 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/b4e7f87b-f794-4dab-ae0c-b06365eaa852_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vmYO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vmYO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!vmYO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p></p><p>Modern software needs to be compiled in a way that produces the same binary across different machines and environments. This process is called a reproducible build. In the Go language, the build system supports this through a feature known as the build ID. The build ID serves as a hash that marks the fingerprint of a binary. Looking at how it&#8217;s generated and how the Go toolchain applies it makes it easier to see how reproducibility is achieved in projects.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>What the Build ID Represents</h3><p>The build ID in Go is a way of tying a compiled binary back to the exact environment and inputs that produced it. It acts like a fingerprint, helping developers confirm that what was built in one place can be trusted as the same thing built somewhere else. Without this kind of identifier, comparing binaries would mean depending only on file size or timestamps, which say little about the real contents. The build ID provides a reliable anchor for reproducibility.</p><h4>What the Build ID Is</h4><p>A build ID is stored as a string inside the binary itself. It&#8217;s not a random tag or a filename, but a hash that reflects the code, the compiler, the flags, and other inputs. The recorded string includes an input-hash and an output-hash, so two identical builds share the same ID. That means two identical builds should produce the same ID. If something changes, even slightly, the ID changes as well.</p><p>You can see it in practice with the <code>go tool buildid</code> command. After building a small program, running the tool against the binary gives back the identifier.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WiT3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88ee1f3-c677-4644-9c79-8e8d5363d3c5_1104x280.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WiT3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88ee1f3-c677-4644-9c79-8e8d5363d3c5_1104x280.png 424w, https://substackcdn.com/image/fetch/$s_!WiT3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88ee1f3-c677-4644-9c79-8e8d5363d3c5_1104x280.png 848w, https://substackcdn.com/image/fetch/$s_!WiT3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88ee1f3-c677-4644-9c79-8e8d5363d3c5_1104x280.png 1272w, https://substackcdn.com/image/fetch/$s_!WiT3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88ee1f3-c677-4644-9c79-8e8d5363d3c5_1104x280.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WiT3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88ee1f3-c677-4644-9c79-8e8d5363d3c5_1104x280.png" width="702" height="178.04347826086956" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b88ee1f3-c677-4644-9c79-8e8d5363d3c5_1104x280.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:280,&quot;width&quot;:1104,&quot;resizeWidth&quot;:702,&quot;bytes&quot;:27283,&quot;alt&quot;:&quot;// main.go package main  import \&quot;fmt\&quot;  func main() {     fmt.Println(\&quot;Build ID example\&quot;) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180057240?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88ee1f3-c677-4644-9c79-8e8d5363d3c5_1104x280.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="// main.go package main  import &quot;fmt&quot;  func main() {     fmt.Println(&quot;Build ID example&quot;) }" title="// main.go package main  import &quot;fmt&quot;  func main() {     fmt.Println(&quot;Build ID example&quot;) }" srcset="https://substackcdn.com/image/fetch/$s_!WiT3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88ee1f3-c677-4644-9c79-8e8d5363d3c5_1104x280.png 424w, https://substackcdn.com/image/fetch/$s_!WiT3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88ee1f3-c677-4644-9c79-8e8d5363d3c5_1104x280.png 848w, https://substackcdn.com/image/fetch/$s_!WiT3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88ee1f3-c677-4644-9c79-8e8d5363d3c5_1104x280.png 1272w, https://substackcdn.com/image/fetch/$s_!WiT3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb88ee1f3-c677-4644-9c79-8e8d5363d3c5_1104x280.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Compile and inspect the binary:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KsuR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F514c8376-9cc1-4486-9b87-d78801a76950_1122x68.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KsuR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F514c8376-9cc1-4486-9b87-d78801a76950_1122x68.png 424w, https://substackcdn.com/image/fetch/$s_!KsuR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F514c8376-9cc1-4486-9b87-d78801a76950_1122x68.png 848w, https://substackcdn.com/image/fetch/$s_!KsuR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F514c8376-9cc1-4486-9b87-d78801a76950_1122x68.png 1272w, https://substackcdn.com/image/fetch/$s_!KsuR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F514c8376-9cc1-4486-9b87-d78801a76950_1122x68.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KsuR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F514c8376-9cc1-4486-9b87-d78801a76950_1122x68.png" width="1122" height="68" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/514c8376-9cc1-4486-9b87-d78801a76950_1122x68.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:68,&quot;width&quot;:1122,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:12217,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180057240?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F514c8376-9cc1-4486-9b87-d78801a76950_1122x68.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!KsuR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F514c8376-9cc1-4486-9b87-d78801a76950_1122x68.png 424w, https://substackcdn.com/image/fetch/$s_!KsuR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F514c8376-9cc1-4486-9b87-d78801a76950_1122x68.png 848w, https://substackcdn.com/image/fetch/$s_!KsuR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F514c8376-9cc1-4486-9b87-d78801a76950_1122x68.png 1272w, https://substackcdn.com/image/fetch/$s_!KsuR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F514c8376-9cc1-4486-9b87-d78801a76950_1122x68.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The output will look like a long hash string. Rebuilding without any changes keeps that same ID, but altering the source or even the build flags will result in a different one. This behavior is what makes the build ID dependable for reproducibility.</p><p>Something worth mentioning is that the build ID doesn&#8217;t affect how the program itself runs. It&#8217;s metadata, so it only exists for the toolchain and developers to track what was built.</p><h4>How It Gets Stored</h4><p>Different operating systems have different binary formats, and the Go toolchain writes the build ID into the right place for each. On Linux, it&#8217;s in an <code>ELF PT_NOTE</code>. On macOS and Windows, Go embeds the <code>Go build ID</code> bytes near the start of the <code>.text</code> segment rather than a dedicated note. This cross-platform handling is automatic. Developers don&#8217;t have to tell the toolchain where to put the build ID, and it&#8217;s handled during the build and link process.</p><p>To verify the presence of the ID on Linux, you can use <code>readelf</code> on the binary.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GUfG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedc7e8cf-2e40-4e9f-b41e-e11f45bb0ee0_1126x31.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GUfG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedc7e8cf-2e40-4e9f-b41e-e11f45bb0ee0_1126x31.png 424w, https://substackcdn.com/image/fetch/$s_!GUfG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedc7e8cf-2e40-4e9f-b41e-e11f45bb0ee0_1126x31.png 848w, https://substackcdn.com/image/fetch/$s_!GUfG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedc7e8cf-2e40-4e9f-b41e-e11f45bb0ee0_1126x31.png 1272w, https://substackcdn.com/image/fetch/$s_!GUfG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedc7e8cf-2e40-4e9f-b41e-e11f45bb0ee0_1126x31.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GUfG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedc7e8cf-2e40-4e9f-b41e-e11f45bb0ee0_1126x31.png" width="1126" height="31" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/edc7e8cf-2e40-4e9f-b41e-e11f45bb0ee0_1126x31.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:31,&quot;width&quot;:1126,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6563,&quot;alt&quot;:&quot;readelf -n demo | grep Go&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180057240?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedc7e8cf-2e40-4e9f-b41e-e11f45bb0ee0_1126x31.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="readelf -n demo | grep Go" title="readelf -n demo | grep Go" srcset="https://substackcdn.com/image/fetch/$s_!GUfG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedc7e8cf-2e40-4e9f-b41e-e11f45bb0ee0_1126x31.png 424w, https://substackcdn.com/image/fetch/$s_!GUfG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedc7e8cf-2e40-4e9f-b41e-e11f45bb0ee0_1126x31.png 848w, https://substackcdn.com/image/fetch/$s_!GUfG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedc7e8cf-2e40-4e9f-b41e-e11f45bb0ee0_1126x31.png 1272w, https://substackcdn.com/image/fetch/$s_!GUfG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedc7e8cf-2e40-4e9f-b41e-e11f45bb0ee0_1126x31.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>This will reveal the note section containing the build ID string. On macOS, a tool like <code>otool</code> can be used instead. While the commands vary, the purpose is the same: the ID is embedded right into the binary format so it can always be retrieved later.</p><p>Embedding the build ID directly into the binary is what makes it reliable across environments. Even if a binary is moved to another system, the ID travels with it.</p><h4>Why It Matters for Developers</h4><p>Reproducibility is about trust. Developers need to know that the binary deployed to production is the same one reviewed, tested, and built in a controlled environment. Without a way to tie a binary back to its inputs, that trust would be weaker. The build ID addresses that gap.</p><p>Let&#8217;s say you&#8217;re working on a service that has to be rebuilt across different build machines or continuous integration runners. With a build ID, you can confirm whether the binaries match or not, no matter where they came from. That removes ambiguity in release pipelines. You can also use the build ID in automation. For example, a script can check whether a locally built binary matches one already stored in an artifact repository.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_NlQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2e463a3-95e5-4a4b-b48a-7f4d5977f64c_1036x273.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_NlQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2e463a3-95e5-4a4b-b48a-7f4d5977f64c_1036x273.png 424w, https://substackcdn.com/image/fetch/$s_!_NlQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2e463a3-95e5-4a4b-b48a-7f4d5977f64c_1036x273.png 848w, https://substackcdn.com/image/fetch/$s_!_NlQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2e463a3-95e5-4a4b-b48a-7f4d5977f64c_1036x273.png 1272w, https://substackcdn.com/image/fetch/$s_!_NlQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2e463a3-95e5-4a4b-b48a-7f4d5977f64c_1036x273.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_NlQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2e463a3-95e5-4a4b-b48a-7f4d5977f64c_1036x273.png" width="632" height="166.54054054054055" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d2e463a3-95e5-4a4b-b48a-7f4d5977f64c_1036x273.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:273,&quot;width&quot;:1036,&quot;resizeWidth&quot;:632,&quot;bytes&quot;:46385,&quot;alt&quot;:&quot;id_local=$(go tool buildid demo) id_repo=$(go tool buildid /artifacts/demo)  if [ \&quot;$id_local\&quot; = \&quot;$id_repo\&quot; ]; then     echo \&quot;Binaries match\&quot; else     echo \&quot;Mismatch detected\&quot; fi&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180057240?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2e463a3-95e5-4a4b-b48a-7f4d5977f64c_1036x273.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="id_local=$(go tool buildid demo) id_repo=$(go tool buildid /artifacts/demo)  if [ &quot;$id_local&quot; = &quot;$id_repo&quot; ]; then     echo &quot;Binaries match&quot; else     echo &quot;Mismatch detected&quot; fi" title="id_local=$(go tool buildid demo) id_repo=$(go tool buildid /artifacts/demo)  if [ &quot;$id_local&quot; = &quot;$id_repo&quot; ]; then     echo &quot;Binaries match&quot; else     echo &quot;Mismatch detected&quot; fi" srcset="https://substackcdn.com/image/fetch/$s_!_NlQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2e463a3-95e5-4a4b-b48a-7f4d5977f64c_1036x273.png 424w, https://substackcdn.com/image/fetch/$s_!_NlQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2e463a3-95e5-4a4b-b48a-7f4d5977f64c_1036x273.png 848w, https://substackcdn.com/image/fetch/$s_!_NlQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2e463a3-95e5-4a4b-b48a-7f4d5977f64c_1036x273.png 1272w, https://substackcdn.com/image/fetch/$s_!_NlQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2e463a3-95e5-4a4b-b48a-7f4d5977f64c_1036x273.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>This simple check lets teams compare outputs directly, which is far more reliable than relying on file names or timestamps.</p><p>For larger projects, this becomes even more valuable. Different teams may build the same project with the same inputs, and the build ID lets them prove that the outputs are identical. That confirmation saves time and prevents mistakes when distributing or deploying software at scale.</p><h3>How Go Generates and Uses the Build ID</h3><p>The process of creating and applying a build ID goes deeper than just stamping a hash onto a binary. The Go toolchain treats it as part of a workflow that begins when source files are compiled, continues through caching, and ends with a finished binary carrying its own identifier. Each step is tied to making sure that builds across environments produce the same result when inputs match.</p><h4>Steps in Build ID Generation</h4><p>The toolchain begins by collecting everything that affects the build. This means the source files, import paths of dependencies, compiler version, build flags, and even environment values that can influence output. These are combined and hashed. The result is the foundation for the build ID string that travels with the binary.</p><p>To see this in action, start with a project that has multiple packages.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fnLb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ba09ad9-873f-4c0e-a312-2750d5588056_1124x210.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fnLb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ba09ad9-873f-4c0e-a312-2750d5588056_1124x210.png 424w, https://substackcdn.com/image/fetch/$s_!fnLb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ba09ad9-873f-4c0e-a312-2750d5588056_1124x210.png 848w, https://substackcdn.com/image/fetch/$s_!fnLb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ba09ad9-873f-4c0e-a312-2750d5588056_1124x210.png 1272w, https://substackcdn.com/image/fetch/$s_!fnLb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ba09ad9-873f-4c0e-a312-2750d5588056_1124x210.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fnLb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ba09ad9-873f-4c0e-a312-2750d5588056_1124x210.png" width="1124" height="210" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2ba09ad9-873f-4c0e-a312-2750d5588056_1124x210.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:210,&quot;width&quot;:1124,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:21139,&quot;alt&quot;:&quot;// util/util.go package util  func Add(a, b int) int {     return a + b }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180057240?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ba09ad9-873f-4c0e-a312-2750d5588056_1124x210.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="// util/util.go package util  func Add(a, b int) int {     return a + b }" title="// util/util.go package util  func Add(a, b int) int {     return a + b }" srcset="https://substackcdn.com/image/fetch/$s_!fnLb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ba09ad9-873f-4c0e-a312-2750d5588056_1124x210.png 424w, https://substackcdn.com/image/fetch/$s_!fnLb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ba09ad9-873f-4c0e-a312-2750d5588056_1124x210.png 848w, https://substackcdn.com/image/fetch/$s_!fnLb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ba09ad9-873f-4c0e-a312-2750d5588056_1124x210.png 1272w, https://substackcdn.com/image/fetch/$s_!fnLb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ba09ad9-873f-4c0e-a312-2750d5588056_1124x210.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ne65!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c70a24-9b6c-4215-9c52-dbe86b44e5c3_1108x383.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ne65!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c70a24-9b6c-4215-9c52-dbe86b44e5c3_1108x383.png 424w, https://substackcdn.com/image/fetch/$s_!ne65!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c70a24-9b6c-4215-9c52-dbe86b44e5c3_1108x383.png 848w, https://substackcdn.com/image/fetch/$s_!ne65!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c70a24-9b6c-4215-9c52-dbe86b44e5c3_1108x383.png 1272w, https://substackcdn.com/image/fetch/$s_!ne65!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c70a24-9b6c-4215-9c52-dbe86b44e5c3_1108x383.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ne65!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c70a24-9b6c-4215-9c52-dbe86b44e5c3_1108x383.png" width="1108" height="383" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c1c70a24-9b6c-4215-9c52-dbe86b44e5c3_1108x383.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:383,&quot;width&quot;:1108,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:32454,&quot;alt&quot;:&quot;// main.go package main  import (     \&quot;fmt\&quot;     \&quot;example/util\&quot; )  func main() {     fmt.Println(util.Add(2, 3)) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180057240?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c70a24-9b6c-4215-9c52-dbe86b44e5c3_1108x383.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="// main.go package main  import (     &quot;fmt&quot;     &quot;example/util&quot; )  func main() {     fmt.Println(util.Add(2, 3)) }" title="// main.go package main  import (     &quot;fmt&quot;     &quot;example/util&quot; )  func main() {     fmt.Println(util.Add(2, 3)) }" srcset="https://substackcdn.com/image/fetch/$s_!ne65!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c70a24-9b6c-4215-9c52-dbe86b44e5c3_1108x383.png 424w, https://substackcdn.com/image/fetch/$s_!ne65!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c70a24-9b6c-4215-9c52-dbe86b44e5c3_1108x383.png 848w, https://substackcdn.com/image/fetch/$s_!ne65!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c70a24-9b6c-4215-9c52-dbe86b44e5c3_1108x383.png 1272w, https://substackcdn.com/image/fetch/$s_!ne65!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c70a24-9b6c-4215-9c52-dbe86b44e5c3_1108x383.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Build the project and inspect the ID:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UKSg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9dec3b-c5a7-4c63-af60-72bc9edf9363_1124x69.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UKSg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9dec3b-c5a7-4c63-af60-72bc9edf9363_1124x69.png 424w, https://substackcdn.com/image/fetch/$s_!UKSg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9dec3b-c5a7-4c63-af60-72bc9edf9363_1124x69.png 848w, https://substackcdn.com/image/fetch/$s_!UKSg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9dec3b-c5a7-4c63-af60-72bc9edf9363_1124x69.png 1272w, https://substackcdn.com/image/fetch/$s_!UKSg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9dec3b-c5a7-4c63-af60-72bc9edf9363_1124x69.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UKSg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9dec3b-c5a7-4c63-af60-72bc9edf9363_1124x69.png" width="1124" height="69" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4c9dec3b-c5a7-4c63-af60-72bc9edf9363_1124x69.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:69,&quot;width&quot;:1124,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:12320,&quot;alt&quot;:&quot;go build -o calc main.go go tool buildid calc&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180057240?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9dec3b-c5a7-4c63-af60-72bc9edf9363_1124x69.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="go build -o calc main.go go tool buildid calc" title="go build -o calc main.go go tool buildid calc" srcset="https://substackcdn.com/image/fetch/$s_!UKSg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9dec3b-c5a7-4c63-af60-72bc9edf9363_1124x69.png 424w, https://substackcdn.com/image/fetch/$s_!UKSg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9dec3b-c5a7-4c63-af60-72bc9edf9363_1124x69.png 848w, https://substackcdn.com/image/fetch/$s_!UKSg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9dec3b-c5a7-4c63-af60-72bc9edf9363_1124x69.png 1272w, https://substackcdn.com/image/fetch/$s_!UKSg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c9dec3b-c5a7-4c63-af60-72bc9edf9363_1124x69.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>If you then edit <code>util.go</code> to change the function, the new build will produce a different ID. That&#8217;s because the hash calculation takes the modified source into account. Changing compiler flags also affects it:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hfWm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07f807e3-e666-4e17-a54a-7f716c7eb4aa_1128x68.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hfWm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07f807e3-e666-4e17-a54a-7f716c7eb4aa_1128x68.png 424w, https://substackcdn.com/image/fetch/$s_!hfWm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07f807e3-e666-4e17-a54a-7f716c7eb4aa_1128x68.png 848w, https://substackcdn.com/image/fetch/$s_!hfWm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07f807e3-e666-4e17-a54a-7f716c7eb4aa_1128x68.png 1272w, https://substackcdn.com/image/fetch/$s_!hfWm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07f807e3-e666-4e17-a54a-7f716c7eb4aa_1128x68.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hfWm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07f807e3-e666-4e17-a54a-7f716c7eb4aa_1128x68.png" width="1128" height="68" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/07f807e3-e666-4e17-a54a-7f716c7eb4aa_1128x68.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:68,&quot;width&quot;:1128,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:16987,&quot;alt&quot;:&quot;go build -gcflags=all=\&quot;-N -l\&quot; -o calc main.go go tool buildid calc&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180057240?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07f807e3-e666-4e17-a54a-7f716c7eb4aa_1128x68.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="go build -gcflags=all=&quot;-N -l&quot; -o calc main.go go tool buildid calc" title="go build -gcflags=all=&quot;-N -l&quot; -o calc main.go go tool buildid calc" srcset="https://substackcdn.com/image/fetch/$s_!hfWm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07f807e3-e666-4e17-a54a-7f716c7eb4aa_1128x68.png 424w, https://substackcdn.com/image/fetch/$s_!hfWm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07f807e3-e666-4e17-a54a-7f716c7eb4aa_1128x68.png 848w, https://substackcdn.com/image/fetch/$s_!hfWm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07f807e3-e666-4e17-a54a-7f716c7eb4aa_1128x68.png 1272w, https://substackcdn.com/image/fetch/$s_!hfWm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07f807e3-e666-4e17-a54a-7f716c7eb4aa_1128x68.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The altered flags result in a new identifier, confirming that the build ID reflects more than just the code itself.</p><h4>Linking and Rewriting</h4><p>Compilation produces object files for each package, but the final build ID can&#8217;t be locked down until the linker brings everything together. During this step, the linker assigns a placeholder ID, writes the binary, then goes back to patch the binary with the actual build ID once the full picture is known. This makes sure that the final ID reflects not only the compiled code but also how it was linked.</p><p>You can see the rewriting stage by running the build with trace output.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CuEB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97322c40-9a46-4f4d-9de6-ae4e19688d24_1061x36.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CuEB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97322c40-9a46-4f4d-9de6-ae4e19688d24_1061x36.png 424w, https://substackcdn.com/image/fetch/$s_!CuEB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97322c40-9a46-4f4d-9de6-ae4e19688d24_1061x36.png 848w, https://substackcdn.com/image/fetch/$s_!CuEB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97322c40-9a46-4f4d-9de6-ae4e19688d24_1061x36.png 1272w, https://substackcdn.com/image/fetch/$s_!CuEB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97322c40-9a46-4f4d-9de6-ae4e19688d24_1061x36.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CuEB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97322c40-9a46-4f4d-9de6-ae4e19688d24_1061x36.png" width="1061" height="36" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/97322c40-9a46-4f4d-9de6-ae4e19688d24_1061x36.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:36,&quot;width&quot;:1061,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:9256,&quot;alt&quot;:&quot;go build -x -o server main.go&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180057240?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97322c40-9a46-4f4d-9de6-ae4e19688d24_1061x36.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="go build -x -o server main.go" title="go build -x -o server main.go" srcset="https://substackcdn.com/image/fetch/$s_!CuEB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97322c40-9a46-4f4d-9de6-ae4e19688d24_1061x36.png 424w, https://substackcdn.com/image/fetch/$s_!CuEB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97322c40-9a46-4f4d-9de6-ae4e19688d24_1061x36.png 848w, https://substackcdn.com/image/fetch/$s_!CuEB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97322c40-9a46-4f4d-9de6-ae4e19688d24_1061x36.png 1272w, https://substackcdn.com/image/fetch/$s_!CuEB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97322c40-9a46-4f4d-9de6-ae4e19688d24_1061x36.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The <code>-x</code> flag shows each tool invocation. Among them you&#8217;ll notice the linker running and later a call to <code>buildid -w</code>, which rewrites the binary with the computed ID. That patching step is what makes the ID accurate and complete.</p><p>This process becomes even more important for bigger projects because many packages contribute to the final binary. Each package gets its own build ID in the cache, but the final binary has a single ID that reflects the entire linked result.</p><h4>Deduplication of Build Results</h4><p>Rebuilding a project every time from scratch would be slow, so the Go toolchain uses the build ID as the anchor for its cache. When you build a package, the toolchain stores the compiled object under a directory path based on its build ID. If later you try to build the same package with the same inputs, the cached object is pulled back without recompilation.</p><p>You can inspect this cache directly:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!v0ii!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d3c6994-f0f6-4050-9de2-c836bde0e69c_1125x34.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!v0ii!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d3c6994-f0f6-4050-9de2-c836bde0e69c_1125x34.png 424w, https://substackcdn.com/image/fetch/$s_!v0ii!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d3c6994-f0f6-4050-9de2-c836bde0e69c_1125x34.png 848w, https://substackcdn.com/image/fetch/$s_!v0ii!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d3c6994-f0f6-4050-9de2-c836bde0e69c_1125x34.png 1272w, https://substackcdn.com/image/fetch/$s_!v0ii!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d3c6994-f0f6-4050-9de2-c836bde0e69c_1125x34.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!v0ii!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d3c6994-f0f6-4050-9de2-c836bde0e69c_1125x34.png" width="1125" height="34" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1d3c6994-f0f6-4050-9de2-c836bde0e69c_1125x34.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:34,&quot;width&quot;:1125,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5594,&quot;alt&quot;:&quot;go env GOCACHE&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180057240?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d3c6994-f0f6-4050-9de2-c836bde0e69c_1125x34.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="go env GOCACHE" title="go env GOCACHE" srcset="https://substackcdn.com/image/fetch/$s_!v0ii!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d3c6994-f0f6-4050-9de2-c836bde0e69c_1125x34.png 424w, https://substackcdn.com/image/fetch/$s_!v0ii!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d3c6994-f0f6-4050-9de2-c836bde0e69c_1125x34.png 848w, https://substackcdn.com/image/fetch/$s_!v0ii!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d3c6994-f0f6-4050-9de2-c836bde0e69c_1125x34.png 1272w, https://substackcdn.com/image/fetch/$s_!v0ii!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d3c6994-f0f6-4050-9de2-c836bde0e69c_1125x34.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>That command prints the location of the build cache. Inside, files and directories are named with hashes tied to build IDs. Running a build with <code>-x</code> makes it easier to see when the toolchain is pulling from cache rather than compiling fresh, and setting <code>GODEBUG=gocachetest=1</code> or <code>GODEBUG=gocachehash=1</code> prints cache debugging information.</p><p>Here&#8217;s a quick example:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-pMu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d124563-65a9-4732-91e3-a2f91c26930e_1128x69.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-pMu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d124563-65a9-4732-91e3-a2f91c26930e_1128x69.png 424w, https://substackcdn.com/image/fetch/$s_!-pMu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d124563-65a9-4732-91e3-a2f91c26930e_1128x69.png 848w, https://substackcdn.com/image/fetch/$s_!-pMu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d124563-65a9-4732-91e3-a2f91c26930e_1128x69.png 1272w, https://substackcdn.com/image/fetch/$s_!-pMu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d124563-65a9-4732-91e3-a2f91c26930e_1128x69.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-pMu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d124563-65a9-4732-91e3-a2f91c26930e_1128x69.png" width="1128" height="69" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0d124563-65a9-4732-91e3-a2f91c26930e_1128x69.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:69,&quot;width&quot;:1128,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:16787,&quot;alt&quot;:&quot;go build -o service main.go go build -o service2 main.go&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180057240?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d124563-65a9-4732-91e3-a2f91c26930e_1128x69.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="go build -o service main.go go build -o service2 main.go" title="go build -o service main.go go build -o service2 main.go" srcset="https://substackcdn.com/image/fetch/$s_!-pMu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d124563-65a9-4732-91e3-a2f91c26930e_1128x69.png 424w, https://substackcdn.com/image/fetch/$s_!-pMu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d124563-65a9-4732-91e3-a2f91c26930e_1128x69.png 848w, https://substackcdn.com/image/fetch/$s_!-pMu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d124563-65a9-4732-91e3-a2f91c26930e_1128x69.png 1272w, https://substackcdn.com/image/fetch/$s_!-pMu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d124563-65a9-4732-91e3-a2f91c26930e_1128x69.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The second build is nearly instant because the package objects are reused. They didn&#8217;t need to be rebuilt since their IDs matched what was already stored. If you modify a single dependency, only that part of the cache is invalidated, and the rest remains valid.</p><p>This system gives developers both reproducibility and speed. The same build ID that makes reproducibility possible also makes incremental builds efficient.</p><h4>Reproducible Builds in Practice</h4><p>All of these mechanics come together when reproducibility is tested in real conditions. A binary built on one machine should match the binary built on another when everything about the inputs is aligned. The build ID is what guarantees that alignment.</p><p>Suppose you package your project inside a container with a controlled Go version and module set. Building inside that container on two separate hosts should give you the same build ID. That makes verification nice and easily.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CMB6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa22ea2fa-8da2-4619-9f6b-bcf572cf5f22_1034x69.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CMB6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa22ea2fa-8da2-4619-9f6b-bcf572cf5f22_1034x69.png 424w, https://substackcdn.com/image/fetch/$s_!CMB6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa22ea2fa-8da2-4619-9f6b-bcf572cf5f22_1034x69.png 848w, https://substackcdn.com/image/fetch/$s_!CMB6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa22ea2fa-8da2-4619-9f6b-bcf572cf5f22_1034x69.png 1272w, https://substackcdn.com/image/fetch/$s_!CMB6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa22ea2fa-8da2-4619-9f6b-bcf572cf5f22_1034x69.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CMB6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa22ea2fa-8da2-4619-9f6b-bcf572cf5f22_1034x69.png" width="1034" height="69" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a22ea2fa-8da2-4619-9f6b-bcf572cf5f22_1034x69.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:69,&quot;width&quot;:1034,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:25015,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/180057240?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa22ea2fa-8da2-4619-9f6b-bcf572cf5f22_1034x69.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CMB6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa22ea2fa-8da2-4619-9f6b-bcf572cf5f22_1034x69.png 424w, https://substackcdn.com/image/fetch/$s_!CMB6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa22ea2fa-8da2-4619-9f6b-bcf572cf5f22_1034x69.png 848w, https://substackcdn.com/image/fetch/$s_!CMB6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa22ea2fa-8da2-4619-9f6b-bcf572cf5f22_1034x69.png 1272w, https://substackcdn.com/image/fetch/$s_!CMB6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa22ea2fa-8da2-4619-9f6b-bcf572cf5f22_1034x69.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Running that command on two different machines will produce the same ID, provided the inputs are identical.</p><p>This consistency matters when distributing binaries, uploading artifacts to a repository, or verifying supply chain integrity. If two builds produce the same build ID, they&#8217;re guaranteed to match at the binary level. If they differ, you immediately know that some input or environment detail has changed.</p><p>Reproducibility isn&#8217;t just about audits and security checks. It also helps in debugging. If a bug is reported against a binary, the build ID lets you identify exactly which source and configuration produced it. That makes tracking issues back to the source faster and less prone to error.</p><h3>Conclusion</h3><p>Go&#8217;s build ID ties a binary directly to the inputs and process that created it. By hashing code, dependencies, compiler flags, and environment details, then embedding that identifier into the binary, the toolchain makes reproducibility practical. The way it&#8217;s generated during compilation, patched during linking, and used in caching shows how the mechanics work together to keep builds consistent across environments.</p><ol><li><p><em><a href="https://pkg.go.dev/cmd/go">Go Command Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies">Go Tool Buildid</a></em></p></li><li><p><em><a href="https://go.dev/ref/mod">Go Modules Reference</a></em></p></li><li><p><em><a href="https://reproducible-builds.org/">Reproducible Builds Project</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Memory Fragmentation in Go]]></title><description><![CDATA[Memory management in Go balances speed, predictability, and efficiency.]]></description><link>https://alexanderobregon.substack.com/p/memory-fragmentation-in-go</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/memory-fragmentation-in-go</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Tue, 25 Nov 2025 18:29:18 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/fd7965e0-1e16-4ca8-9293-6db2f3e3d6c2_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vmYO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vmYO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vmYO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!vmYO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f94a180-b6b1-473a-8011-e15702a7db34_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>Memory management in Go balances speed, predictability, and efficiency. Programs built in Go often run for long stretches, sometimes as servers handling millions of requests. Over time, memory can become fragmented, and the allocator along with the garbage collector are responsible for dealing with that. Fragmentation shows up when memory is left in scattered pieces that don&#8217;t always fit future allocations.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>How Fragmentation Develops in Go</h3><p>Fragmentation comes from the way Go organizes memory for its runtime. The allocator works with spans and pages to keep allocation fast, but over time gaps build up. Some of these gaps are tiny leftovers inside spans, while others come from spans being locked to a single object size and never quite lining up with later allocation patterns. Long-running processes make these gaps more visible because memory churn doesn&#8217;t stop, and what was efficient at the start doesn&#8217;t always fit what happens hours or days later.</p><h4>Page Based Allocation</h4><p>The allocator doesn&#8217;t hand out memory directly from the operating system every time a new object is created. Instead, it works with spans, which are made of pages. On most platforms, a page is 8 KB, and a span can be one or more of those pages grouped together. Each span is tied to a specific size class, which means all allocations inside that span are of the same block size. This keeps allocation fast because the runtime only needs to grab the next free slot, but it also introduces rigidity. A span holding 128-byte slots only serves that size while it is assigned to that class, and once it becomes fully free its pages can be reused for another class.</p><p>You can see how this fits into application code with a small example. If you allocate lots of tiny slices, they&#8217;ll be grouped into a particular span size class:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SLxz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144b0f22-0bd4-4c77-bdcd-153a10b08102_976x312.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SLxz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144b0f22-0bd4-4c77-bdcd-153a10b08102_976x312.png 424w, https://substackcdn.com/image/fetch/$s_!SLxz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144b0f22-0bd4-4c77-bdcd-153a10b08102_976x312.png 848w, https://substackcdn.com/image/fetch/$s_!SLxz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144b0f22-0bd4-4c77-bdcd-153a10b08102_976x312.png 1272w, https://substackcdn.com/image/fetch/$s_!SLxz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144b0f22-0bd4-4c77-bdcd-153a10b08102_976x312.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SLxz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144b0f22-0bd4-4c77-bdcd-153a10b08102_976x312.png" width="701" height="224.09016393442624" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/144b0f22-0bd4-4c77-bdcd-153a10b08102_976x312.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:312,&quot;width&quot;:976,&quot;resizeWidth&quot;:701,&quot;bytes&quot;:46493,&quot;alt&quot;:&quot;package main  func main() {     // Allocates many 64-byte slices     var store [][]byte     for i := 0; i < 100000; i++ {         store = append(store, make([]byte, 64))     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179199725?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144b0f22-0bd4-4c77-bdcd-153a10b08102_976x312.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  func main() {     // Allocates many 64-byte slices     var store [][]byte     for i := 0; i < 100000; i++ {         store = append(store, make([]byte, 64))     } }" title="package main  func main() {     // Allocates many 64-byte slices     var store [][]byte     for i := 0; i < 100000; i++ {         store = append(store, make([]byte, 64))     } }" srcset="https://substackcdn.com/image/fetch/$s_!SLxz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144b0f22-0bd4-4c77-bdcd-153a10b08102_976x312.png 424w, https://substackcdn.com/image/fetch/$s_!SLxz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144b0f22-0bd4-4c77-bdcd-153a10b08102_976x312.png 848w, https://substackcdn.com/image/fetch/$s_!SLxz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144b0f22-0bd4-4c77-bdcd-153a10b08102_976x312.png 1272w, https://substackcdn.com/image/fetch/$s_!SLxz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144b0f22-0bd4-4c77-bdcd-153a10b08102_976x312.png 1456w" sizes="100vw"></picture><div></div></div></a></figure></div><p>Those slices are packed into spans for the 64-byte class. Later, if the program needs larger slices, those old spans can&#8217;t be reused for them. The allocator instead asks for new spans, leaving the older ones half used or idle.</p><h4>Internal Fragmentation</h4><p>Internal fragmentation happens inside spans when allocations don&#8217;t use up their slots fully. If an object doesn&#8217;t exactly fit the slot size, the rest of that slot goes to waste. Imagine allocating 100-byte slices, which fall into a size class that is larger than 100 bytes. Each slot leaves some bytes unused. A handful of objects will not matter, but repeated thousands of times, the waste adds up.</p><p>This example shows the mismatch:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PrqR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd90b923-8507-4d7f-ba3a-5fe930faec37_1132x313.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PrqR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd90b923-8507-4d7f-ba3a-5fe930faec37_1132x313.png 424w, https://substackcdn.com/image/fetch/$s_!PrqR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd90b923-8507-4d7f-ba3a-5fe930faec37_1132x313.png 848w, https://substackcdn.com/image/fetch/$s_!PrqR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd90b923-8507-4d7f-ba3a-5fe930faec37_1132x313.png 1272w, https://substackcdn.com/image/fetch/$s_!PrqR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd90b923-8507-4d7f-ba3a-5fe930faec37_1132x313.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PrqR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd90b923-8507-4d7f-ba3a-5fe930faec37_1132x313.png" width="1132" height="313" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dd90b923-8507-4d7f-ba3a-5fe930faec37_1132x313.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:313,&quot;width&quot;:1132,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:50430,&quot;alt&quot;:&quot;package main  func main() {     // 100-byte slices are rounded up to a larger internal slot size     var data [][]byte     for i := 0; i < 50000; i++ {         data = append(data, make([]byte, 100))     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179199725?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd90b923-8507-4d7f-ba3a-5fe930faec37_1132x313.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  func main() {     // 100-byte slices are rounded up to a larger internal slot size     var data [][]byte     for i := 0; i < 50000; i++ {         data = append(data, make([]byte, 100))     } }" title="package main  func main() {     // 100-byte slices are rounded up to a larger internal slot size     var data [][]byte     for i := 0; i < 50000; i++ {         data = append(data, make([]byte, 100))     } }" srcset="https://substackcdn.com/image/fetch/$s_!PrqR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd90b923-8507-4d7f-ba3a-5fe930faec37_1132x313.png 424w, https://substackcdn.com/image/fetch/$s_!PrqR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd90b923-8507-4d7f-ba3a-5fe930faec37_1132x313.png 848w, https://substackcdn.com/image/fetch/$s_!PrqR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd90b923-8507-4d7f-ba3a-5fe930faec37_1132x313.png 1272w, https://substackcdn.com/image/fetch/$s_!PrqR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd90b923-8507-4d7f-ba3a-5fe930faec37_1132x313.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Although every slice is exactly 100 bytes in the program&#8217;s logic, the allocator reserves a larger internal slot for each because it rounds up to the nearest size class. That padding is invisible to the code but visible in memory profiles.</p><p>Internal fragmentation also occurs when a span is only partly filled. If a span holds 512 slots for 128-byte objects but only 400 are allocated, the rest sit unused until new requests arrive for that same size class. If those requests never come, that memory stays fragmented.</p><h4>External Fragmentation</h4><p>External fragmentation shows up at the span level. Over time, spans for different sizes become scattered, and some never line up to be reused. Imagine that spans for 32-byte objects are mostly freed but still contain a few live objects. Those spans cannot be merged into a larger one for a 1 MB request, so the allocator asks the operating system for more memory instead.</p><p>A simple way to simulate the problem is to alternate small and large allocations:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bTFV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23993719-104c-493f-bcfc-81d50ce77a55_1107x628.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bTFV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23993719-104c-493f-bcfc-81d50ce77a55_1107x628.png 424w, https://substackcdn.com/image/fetch/$s_!bTFV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23993719-104c-493f-bcfc-81d50ce77a55_1107x628.png 848w, https://substackcdn.com/image/fetch/$s_!bTFV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23993719-104c-493f-bcfc-81d50ce77a55_1107x628.png 1272w, https://substackcdn.com/image/fetch/$s_!bTFV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23993719-104c-493f-bcfc-81d50ce77a55_1107x628.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bTFV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23993719-104c-493f-bcfc-81d50ce77a55_1107x628.png" width="1107" height="628" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/23993719-104c-493f-bcfc-81d50ce77a55_1107x628.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:628,&quot;width&quot;:1107,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:88319,&quot;alt&quot;:&quot;package main  import \&quot;time\&quot;  func main() {     var keep [][]byte     for i := 0; i < 1000; i++ {         // Large allocations         _ = make([]byte, 1024*64)          // Small allocations that linger         b := make([]byte, 32)         keep = append(keep, b)          // Pause to stretch allocations out         time.Sleep(1 * time.Millisecond)     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179199725?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23993719-104c-493f-bcfc-81d50ce77a55_1107x628.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;time&quot;  func main() {     var keep [][]byte     for i := 0; i < 1000; i++ {         // Large allocations         _ = make([]byte, 1024*64)          // Small allocations that linger         b := make([]byte, 32)         keep = append(keep, b)          // Pause to stretch allocations out         time.Sleep(1 * time.Millisecond)     } }" title="package main  import &quot;time&quot;  func main() {     var keep [][]byte     for i := 0; i < 1000; i++ {         // Large allocations         _ = make([]byte, 1024*64)          // Small allocations that linger         b := make([]byte, 32)         keep = append(keep, b)          // Pause to stretch allocations out         time.Sleep(1 * time.Millisecond)     } }" srcset="https://substackcdn.com/image/fetch/$s_!bTFV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23993719-104c-493f-bcfc-81d50ce77a55_1107x628.png 424w, https://substackcdn.com/image/fetch/$s_!bTFV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23993719-104c-493f-bcfc-81d50ce77a55_1107x628.png 848w, https://substackcdn.com/image/fetch/$s_!bTFV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23993719-104c-493f-bcfc-81d50ce77a55_1107x628.png 1272w, https://substackcdn.com/image/fetch/$s_!bTFV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23993719-104c-493f-bcfc-81d50ce77a55_1107x628.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The small slices stay alive in memory, locking their spans. Large allocations can&#8217;t reuse that scattered space, so the heap grows outward. Profiling such code often shows high memory use even though the garbage collector runs regularly. External fragmentation is harder to predict because it depends not only on object sizes but also on their lifetimes. Two objects of the same size can end up in different spans, and if one dies while the other lives for hours, the span cannot be reclaimed fully.</p><h4>Long Running Workloads</h4><p>Workloads that never stop bring these issues into focus. A web server, for instance, allocates millions of short-lived request objects but also holds on to caches and session data for much longer. Spans that once held short-lived data may never be reused efficiently once those allocation patterns change.</p><p>You can see this in practice with a loop that alternates between bursty short allocations and fewer large ones:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rIp2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc74b9ed8-c13e-49c4-bade-860a93b057b1_972x700.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rIp2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc74b9ed8-c13e-49c4-bade-860a93b057b1_972x700.png 424w, https://substackcdn.com/image/fetch/$s_!rIp2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc74b9ed8-c13e-49c4-bade-860a93b057b1_972x700.png 848w, https://substackcdn.com/image/fetch/$s_!rIp2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc74b9ed8-c13e-49c4-bade-860a93b057b1_972x700.png 1272w, https://substackcdn.com/image/fetch/$s_!rIp2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc74b9ed8-c13e-49c4-bade-860a93b057b1_972x700.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rIp2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc74b9ed8-c13e-49c4-bade-860a93b057b1_972x700.png" width="972" height="700" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c74b9ed8-c13e-49c4-bade-860a93b057b1_972x700.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:700,&quot;width&quot;:972,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:94984,&quot;alt&quot;:&quot;package main  import \&quot;time\&quot;  func main() {     var hold [][]byte     for cycle := 0; cycle < 2000; cycle++ {         // Burst of short-lived allocations         for i := 0; i < 1000; i++ {             _ = make([]byte, 128)         }          // Some longer-lived objects are held         if cycle%100 == 0 {             hold = append(hold, make([]byte, 1024*32))         }          time.Sleep(2 * time.Millisecond)     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179199725?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc74b9ed8-c13e-49c4-bade-860a93b057b1_972x700.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;time&quot;  func main() {     var hold [][]byte     for cycle := 0; cycle < 2000; cycle++ {         // Burst of short-lived allocations         for i := 0; i < 1000; i++ {             _ = make([]byte, 128)         }          // Some longer-lived objects are held         if cycle%100 == 0 {             hold = append(hold, make([]byte, 1024*32))         }          time.Sleep(2 * time.Millisecond)     } }" title="package main  import &quot;time&quot;  func main() {     var hold [][]byte     for cycle := 0; cycle < 2000; cycle++ {         // Burst of short-lived allocations         for i := 0; i < 1000; i++ {             _ = make([]byte, 128)         }          // Some longer-lived objects are held         if cycle%100 == 0 {             hold = append(hold, make([]byte, 1024*32))         }          time.Sleep(2 * time.Millisecond)     } }" srcset="https://substackcdn.com/image/fetch/$s_!rIp2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc74b9ed8-c13e-49c4-bade-860a93b057b1_972x700.png 424w, https://substackcdn.com/image/fetch/$s_!rIp2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc74b9ed8-c13e-49c4-bade-860a93b057b1_972x700.png 848w, https://substackcdn.com/image/fetch/$s_!rIp2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc74b9ed8-c13e-49c4-bade-860a93b057b1_972x700.png 1272w, https://substackcdn.com/image/fetch/$s_!rIp2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc74b9ed8-c13e-49c4-bade-860a93b057b1_972x700.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Over time, the heap builds up spans tied to different classes. Some of them are freed quickly, others stick around. The allocator reuses what it can, but the heap shape changes with every cycle. On long enough timelines, this uneven reuse leaves gaps that no new allocation can fit into perfectly. That&#8217;s fragmentation in action, and it explains why long-running servers sometimes appear to grow in memory even without leaks.</p><h3>How Go Handles Fragmentation</h3><p>Fragmentation doesn&#8217;t go away on its own. The Go runtime allocator and garbage collector cooperate to make memory reusable. The allocator recycles spans for future allocations, hands pages back to the operating system when possible, and relies on the collector to clear entire spans. At the same time, Go avoids heap compaction to keep latency low, which means fragmentation is managed indirectly. Each of these behaviors affects how memory grows or shrinks in long-lived workloads.</p><h3>Span Reuse</h3><p>Allocation requests first pass through per-processor caches known as mcaches. If the right slot is there, it&#8217;s returned immediately. When a cache runs dry, it&#8217;s refilled from a central pool of spans called mcentrals. Freed objects inside a span eventually go back into this cycle, which is why spans are rarely wasted if more allocations of that size come along.</p><p>A quick loop with short-lived allocations shows this recycling path:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!O1vZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd61a58d7-a766-48db-b4dd-272462e9c79d_1124x244.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!O1vZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd61a58d7-a766-48db-b4dd-272462e9c79d_1124x244.png 424w, https://substackcdn.com/image/fetch/$s_!O1vZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd61a58d7-a766-48db-b4dd-272462e9c79d_1124x244.png 848w, https://substackcdn.com/image/fetch/$s_!O1vZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd61a58d7-a766-48db-b4dd-272462e9c79d_1124x244.png 1272w, https://substackcdn.com/image/fetch/$s_!O1vZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd61a58d7-a766-48db-b4dd-272462e9c79d_1124x244.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!O1vZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd61a58d7-a766-48db-b4dd-272462e9c79d_1124x244.png" width="1124" height="244" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d61a58d7-a766-48db-b4dd-272462e9c79d_1124x244.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:244,&quot;width&quot;:1124,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:31804,&quot;alt&quot;:&quot;package main  func main() {     for i := 0; i < 1_000_000; i++ {         _ = make([]byte, 128) // short lifespan     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179199725?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd61a58d7-a766-48db-b4dd-272462e9c79d_1124x244.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  func main() {     for i := 0; i < 1_000_000; i++ {         _ = make([]byte, 128) // short lifespan     } }" title="package main  func main() {     for i := 0; i < 1_000_000; i++ {         _ = make([]byte, 128) // short lifespan     } }" srcset="https://substackcdn.com/image/fetch/$s_!O1vZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd61a58d7-a766-48db-b4dd-272462e9c79d_1124x244.png 424w, https://substackcdn.com/image/fetch/$s_!O1vZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd61a58d7-a766-48db-b4dd-272462e9c79d_1124x244.png 848w, https://substackcdn.com/image/fetch/$s_!O1vZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd61a58d7-a766-48db-b4dd-272462e9c79d_1124x244.png 1272w, https://substackcdn.com/image/fetch/$s_!O1vZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd61a58d7-a766-48db-b4dd-272462e9c79d_1124x244.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Even with millions of calls, spans for 128-byte slots don&#8217;t keep growing after the first warmup. Slots freed by the garbage collector flow back through the central pool and get reused for new slices.</p><p>When allocations vary in size, the reuse is less smooth. Some spans sit partly full because they can&#8217;t change size class:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KOA_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf8dff28-8214-4a5b-91e5-6352dd8c8d57_1112x418.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KOA_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf8dff28-8214-4a5b-91e5-6352dd8c8d57_1112x418.png 424w, https://substackcdn.com/image/fetch/$s_!KOA_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf8dff28-8214-4a5b-91e5-6352dd8c8d57_1112x418.png 848w, https://substackcdn.com/image/fetch/$s_!KOA_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf8dff28-8214-4a5b-91e5-6352dd8c8d57_1112x418.png 1272w, https://substackcdn.com/image/fetch/$s_!KOA_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf8dff28-8214-4a5b-91e5-6352dd8c8d57_1112x418.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KOA_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf8dff28-8214-4a5b-91e5-6352dd8c8d57_1112x418.png" width="1112" height="418" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bf8dff28-8214-4a5b-91e5-6352dd8c8d57_1112x418.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:418,&quot;width&quot;:1112,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:56530,&quot;alt&quot;:&quot;package main  func main() {     data := make([][]byte, 0)     for i := 0; i < 50000; i++ {         if i%2 == 0 {             data = append(data, make([]byte, 256))         } else {             data = append(data, make([]byte, 1024))         }     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179199725?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf8dff28-8214-4a5b-91e5-6352dd8c8d57_1112x418.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  func main() {     data := make([][]byte, 0)     for i := 0; i < 50000; i++ {         if i%2 == 0 {             data = append(data, make([]byte, 256))         } else {             data = append(data, make([]byte, 1024))         }     } }" title="package main  func main() {     data := make([][]byte, 0)     for i := 0; i < 50000; i++ {         if i%2 == 0 {             data = append(data, make([]byte, 256))         } else {             data = append(data, make([]byte, 1024))         }     } }" srcset="https://substackcdn.com/image/fetch/$s_!KOA_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf8dff28-8214-4a5b-91e5-6352dd8c8d57_1112x418.png 424w, https://substackcdn.com/image/fetch/$s_!KOA_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf8dff28-8214-4a5b-91e5-6352dd8c8d57_1112x418.png 848w, https://substackcdn.com/image/fetch/$s_!KOA_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf8dff28-8214-4a5b-91e5-6352dd8c8d57_1112x418.png 1272w, https://substackcdn.com/image/fetch/$s_!KOA_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf8dff28-8214-4a5b-91e5-6352dd8c8d57_1112x418.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This leaves the runtime with two sets of spans, one for 256-byte slots and one for 1024-byte slots. Recycling works within each class, but the heap is split into pools that can&#8217;t overlap, which makes fragmentation more likely when allocation patterns change.</p><h4>Page Reclamation</h4><p>When an entire span goes unused, Go can return its pages to the operating system. This shrinks the resident set size so the process footprint reflects what&#8217;s actually in use. On Linux, recent Go versions default to <code>MADV_DONTNEED</code> when releasing pages back to the kernel and can switch to <code>MADV_FREE</code> with <code>GODEBUG=madvdontneed=0</code>.</p><p>A direct way to watch this behavior is to allocate a large slice, drop it, and force a collection:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6IJN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe189e9-d9da-4922-8a96-41c80a007171_977x524.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6IJN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe189e9-d9da-4922-8a96-41c80a007171_977x524.png 424w, https://substackcdn.com/image/fetch/$s_!6IJN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe189e9-d9da-4922-8a96-41c80a007171_977x524.png 848w, https://substackcdn.com/image/fetch/$s_!6IJN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe189e9-d9da-4922-8a96-41c80a007171_977x524.png 1272w, https://substackcdn.com/image/fetch/$s_!6IJN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe189e9-d9da-4922-8a96-41c80a007171_977x524.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6IJN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe189e9-d9da-4922-8a96-41c80a007171_977x524.png" width="683" height="366.31729785056297" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/abe189e9-d9da-4922-8a96-41c80a007171_977x524.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:524,&quot;width&quot;:977,&quot;resizeWidth&quot;:683,&quot;bytes&quot;:53433,&quot;alt&quot;:&quot;package main  import (     \&quot;runtime\&quot;     \&quot;runtime/debug\&quot; )  func main() {     buf := make([]byte, 200*1024*1024) // 200 MB     _ = buf     buf = nil      runtime.GC()     debug.FreeOSMemory() }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179199725?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe189e9-d9da-4922-8a96-41c80a007171_977x524.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (     &quot;runtime&quot;     &quot;runtime/debug&quot; )  func main() {     buf := make([]byte, 200*1024*1024) // 200 MB     _ = buf     buf = nil      runtime.GC()     debug.FreeOSMemory() }" title="package main  import (     &quot;runtime&quot;     &quot;runtime/debug&quot; )  func main() {     buf := make([]byte, 200*1024*1024) // 200 MB     _ = buf     buf = nil      runtime.GC()     debug.FreeOSMemory() }" srcset="https://substackcdn.com/image/fetch/$s_!6IJN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe189e9-d9da-4922-8a96-41c80a007171_977x524.png 424w, https://substackcdn.com/image/fetch/$s_!6IJN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe189e9-d9da-4922-8a96-41c80a007171_977x524.png 848w, https://substackcdn.com/image/fetch/$s_!6IJN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe189e9-d9da-4922-8a96-41c80a007171_977x524.png 1272w, https://substackcdn.com/image/fetch/$s_!6IJN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabe189e9-d9da-4922-8a96-41c80a007171_977x524.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>After those calls, system monitors like <code>top</code> often show the process memory dropping. That&#8217;s the allocator returning spans back to the kernel. The runtime doesn&#8217;t always do this automatically because holding free spans can speed up new allocations, so active workloads may appear larger than necessary even though pages would be released if memory pressure rises.</p><h4>Garbage Collector Influence</h4><p>The collector plays a major part in reducing fragmentation. It marks all live objects in a cycle, and if a span holds none of them, that span becomes fully free. When only some slots are freed, they go back into the allocator&#8217;s pool for reuse, but the span remains bound to its original class.</p><p>Here&#8217;s a short example of spans becoming fully free:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DDm0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd565ebe4-1759-4889-9440-33cf1212437f_1109x522.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DDm0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd565ebe4-1759-4889-9440-33cf1212437f_1109x522.png 424w, https://substackcdn.com/image/fetch/$s_!DDm0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd565ebe4-1759-4889-9440-33cf1212437f_1109x522.png 848w, https://substackcdn.com/image/fetch/$s_!DDm0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd565ebe4-1759-4889-9440-33cf1212437f_1109x522.png 1272w, https://substackcdn.com/image/fetch/$s_!DDm0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd565ebe4-1759-4889-9440-33cf1212437f_1109x522.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DDm0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd565ebe4-1759-4889-9440-33cf1212437f_1109x522.png" width="1109" height="522" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d565ebe4-1759-4889-9440-33cf1212437f_1109x522.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:522,&quot;width&quot;:1109,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:65467,&quot;alt&quot;:&quot;package main  import \&quot;runtime\&quot;  func main() {     for i := 0; i < 5; i++ {         // Large burst of short-lived allocations         data := make([][]byte, 10000)         for j := 0; j < 10000; j++ {             data[j] = make([]byte, 512)         }         data = nil         runtime.GC()     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179199725?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd565ebe4-1759-4889-9440-33cf1212437f_1109x522.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;runtime&quot;  func main() {     for i := 0; i < 5; i++ {         // Large burst of short-lived allocations         data := make([][]byte, 10000)         for j := 0; j < 10000; j++ {             data[j] = make([]byte, 512)         }         data = nil         runtime.GC()     } }" title="package main  import &quot;runtime&quot;  func main() {     for i := 0; i < 5; i++ {         // Large burst of short-lived allocations         data := make([][]byte, 10000)         for j := 0; j < 10000; j++ {             data[j] = make([]byte, 512)         }         data = nil         runtime.GC()     } }" srcset="https://substackcdn.com/image/fetch/$s_!DDm0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd565ebe4-1759-4889-9440-33cf1212437f_1109x522.png 424w, https://substackcdn.com/image/fetch/$s_!DDm0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd565ebe4-1759-4889-9440-33cf1212437f_1109x522.png 848w, https://substackcdn.com/image/fetch/$s_!DDm0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd565ebe4-1759-4889-9440-33cf1212437f_1109x522.png 1272w, https://substackcdn.com/image/fetch/$s_!DDm0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd565ebe4-1759-4889-9440-33cf1212437f_1109x522.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Each cycle allocates spans of 512-byte slots, drops all references, and forces collection. The collector clears entire spans at once, giving the allocator fresh spans for the next burst.</p><h4>Large Object Allocation</h4><p>Objects larger than 32 KB bypass size classes. They grab whole spans directly, which means contiguous spans are needed. Fragmentation makes this trickier because free spans may exist but not line up side by side. In that case, Go asks the operating system for more memory.</p><p>Allocating large objects makes this obvious:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rEBh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c9e0e4-43d3-43c4-8cc9-daf4a0e78183_1113x281.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rEBh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c9e0e4-43d3-43c4-8cc9-daf4a0e78183_1113x281.png 424w, https://substackcdn.com/image/fetch/$s_!rEBh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c9e0e4-43d3-43c4-8cc9-daf4a0e78183_1113x281.png 848w, https://substackcdn.com/image/fetch/$s_!rEBh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c9e0e4-43d3-43c4-8cc9-daf4a0e78183_1113x281.png 1272w, https://substackcdn.com/image/fetch/$s_!rEBh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c9e0e4-43d3-43c4-8cc9-daf4a0e78183_1113x281.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rEBh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c9e0e4-43d3-43c4-8cc9-daf4a0e78183_1113x281.png" width="1113" height="281" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c1c9e0e4-43d3-43c4-8cc9-daf4a0e78183_1113x281.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:281,&quot;width&quot;:1113,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:40985,&quot;alt&quot;:&quot;package main  func main() {     var big [][]byte     for i := 0; i < 10; i++ {         big = append(big, make([]byte, 2*1024*1024)) // 2 MB each     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179199725?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c9e0e4-43d3-43c4-8cc9-daf4a0e78183_1113x281.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  func main() {     var big [][]byte     for i := 0; i < 10; i++ {         big = append(big, make([]byte, 2*1024*1024)) // 2 MB each     } }" title="package main  func main() {     var big [][]byte     for i := 0; i < 10; i++ {         big = append(big, make([]byte, 2*1024*1024)) // 2 MB each     } }" srcset="https://substackcdn.com/image/fetch/$s_!rEBh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c9e0e4-43d3-43c4-8cc9-daf4a0e78183_1113x281.png 424w, https://substackcdn.com/image/fetch/$s_!rEBh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c9e0e4-43d3-43c4-8cc9-daf4a0e78183_1113x281.png 848w, https://substackcdn.com/image/fetch/$s_!rEBh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c9e0e4-43d3-43c4-8cc9-daf4a0e78183_1113x281.png 1272w, https://substackcdn.com/image/fetch/$s_!rEBh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1c9e0e4-43d3-43c4-8cc9-daf4a0e78183_1113x281.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Each slice takes one or more entire spans. When those spans are later freed, the runtime can return their pages to the general heap, split them into spans for smaller size classes, or reuse them for other large objects. Fragmentation still shows up when large, long-lived allocations pin spans so that only part of the overall span space is reusable at any moment.</p><h4>Practical Example</h4><p>Servers that juggle short request buffers and heavier long-lived allocations bring every piece of this system into play. Temporary allocations recycle well, but cache objects or background data structures stay around and stop spans from being fully freed. Large objects add further pressure by demanding contiguous spans.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_1gy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfda385c-b3a5-4656-a0bc-bec8d9828a52_1111x700.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_1gy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfda385c-b3a5-4656-a0bc-bec8d9828a52_1111x700.png 424w, https://substackcdn.com/image/fetch/$s_!_1gy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfda385c-b3a5-4656-a0bc-bec8d9828a52_1111x700.png 848w, https://substackcdn.com/image/fetch/$s_!_1gy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfda385c-b3a5-4656-a0bc-bec8d9828a52_1111x700.png 1272w, https://substackcdn.com/image/fetch/$s_!_1gy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfda385c-b3a5-4656-a0bc-bec8d9828a52_1111x700.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_1gy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfda385c-b3a5-4656-a0bc-bec8d9828a52_1111x700.png" width="1111" height="700" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dfda385c-b3a5-4656-a0bc-bec8d9828a52_1111x700.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:700,&quot;width&quot;:1111,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:98839,&quot;alt&quot;:&quot;package main  import \&quot;time\&quot;  func main() {     var cache [][]byte     for round := 0; round < 500; round++ {         // Short buffers for requests         for i := 0; i < 2000; i++ {             _ = make([]byte, 256)         }          // Cache entries stick around         if round%20 == 0 {             cache = append(cache, make([]byte, 128*1024))         }          time.Sleep(2 * time.Millisecond)     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179199725?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfda385c-b3a5-4656-a0bc-bec8d9828a52_1111x700.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;time&quot;  func main() {     var cache [][]byte     for round := 0; round < 500; round++ {         // Short buffers for requests         for i := 0; i < 2000; i++ {             _ = make([]byte, 256)         }          // Cache entries stick around         if round%20 == 0 {             cache = append(cache, make([]byte, 128*1024))         }          time.Sleep(2 * time.Millisecond)     } }" title="package main  import &quot;time&quot;  func main() {     var cache [][]byte     for round := 0; round < 500; round++ {         // Short buffers for requests         for i := 0; i < 2000; i++ {             _ = make([]byte, 256)         }          // Cache entries stick around         if round%20 == 0 {             cache = append(cache, make([]byte, 128*1024))         }          time.Sleep(2 * time.Millisecond)     } }" srcset="https://substackcdn.com/image/fetch/$s_!_1gy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfda385c-b3a5-4656-a0bc-bec8d9828a52_1111x700.png 424w, https://substackcdn.com/image/fetch/$s_!_1gy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfda385c-b3a5-4656-a0bc-bec8d9828a52_1111x700.png 848w, https://substackcdn.com/image/fetch/$s_!_1gy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfda385c-b3a5-4656-a0bc-bec8d9828a52_1111x700.png 1272w, https://substackcdn.com/image/fetch/$s_!_1gy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfda385c-b3a5-4656-a0bc-bec8d9828a52_1111x700.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Over many rounds, spans fill with both recyclable short-lived slots and longer-lived cache slices. Fragmentation develops as some spans never empty completely, while others hold large objects that prevent compact reuse. The allocator manages to keep things moving, but the heap reflects a patchwork of reused and stranded spans.</p><h3>Conclusion</h3><p>Fragmentation in Go comes from the way spans, pages, and size classes interact with live and dead objects over time. The allocator reduces waste by recycling spans within the same size class, returning empty spans to the operating system, and working with the garbage collector to clear whole spans. At the same time, large allocations that need contiguous spans and the lack of full compaction leave gaps scattered across the heap. These mechanics explain why long-running services can see memory footprints grow in patterns that aren&#8217;t tied to leaks but to how allocation, reuse, and reclamation play out inside the runtime.</p><ol><li><p><em><a href="https://go.dev/ref/mem">Go Memory Management Overview</a></em></p></li><li><p><em><a href="https://pkg.go.dev/runtime">Go Runtime Package</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Go Binary Size Reduction]]></title><description><![CDATA[Go produces a self-contained executable that includes the Go runtime, your code, and required standard-library parts.]]></description><link>https://alexanderobregon.substack.com/p/go-binary-size-reduction</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/go-binary-size-reduction</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Sun, 23 Nov 2025 18:08:35 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/03f5e102-2237-4ca8-a199-44cafade7ca2_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bjxS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e8e65e6-757d-478e-8b50-559366d64f09_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bjxS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e8e65e6-757d-478e-8b50-559366d64f09_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!bjxS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e8e65e6-757d-478e-8b50-559366d64f09_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!bjxS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e8e65e6-757d-478e-8b50-559366d64f09_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!bjxS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e8e65e6-757d-478e-8b50-559366d64f09_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bjxS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e8e65e6-757d-478e-8b50-559366d64f09_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8e8e65e6-757d-478e-8b50-559366d64f09_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bjxS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e8e65e6-757d-478e-8b50-559366d64f09_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!bjxS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e8e65e6-757d-478e-8b50-559366d64f09_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!bjxS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e8e65e6-757d-478e-8b50-559366d64f09_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!bjxS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e8e65e6-757d-478e-8b50-559366d64f09_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>Go produces a self-contained executable that includes the Go runtime, your code, and required standard-library parts. On Linux with cgo disabled the result is fully static. With cgo enabled or on platforms like macOS, the binary links to system libraries. This makes delivery easy but it also leads to larger binaries than some expect. The toolchain always prunes unreachable code while symbol and DWARF data stay in by default unless you pass <code>-ldflags &#8220;-s -w&#8221;</code>. Compiler and linker flags give more control over how much of the executable is kept or removed.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>Mechanics of Symbol Stripping and Code Pruning</h3><p>Go binaries don&#8217;t keep every piece of information that goes into a build. The compiler and linker are always asking what needs to stay and what can be discarded. Stripping symbols reduces extra data used for debugging and stack traces, while dead code elimination trims unused functions and imports. Reflection then complicates things by forcing the toolchain to keep more information intact.</p><h4>How Go Handles Symbols</h4><p>Symbols are names tied to functions, variables, and methods that the runtime or external tools may need. They provide the map that allows debuggers to resolve memory addresses back to function names or variable references. If you&#8217;ve ever seen a stack trace with function names instead of raw addresses, that&#8217;s made possible by the symbol table. The Go toolchain decides whether this symbol information remains inside the final binary. By default, it&#8217;s included so debugging tools and stack traces work smoothly. Panic stack traces still show function names and file:line while <code>-s</code> drops the OS symbol table and <code>-w</code> drops DWARF, but Go&#8217;s own tables used for tracebacks remain.</p><p>Sometimes symbol stripping alone can shrink a binary by several megabytes. The difference is more pronounced in projects that rely on many packages or runtime features. It&#8217;s worth noting that stripping doesn&#8217;t remove logic or code, only metadata tied to debugging and symbol resolution.</p><h4>Dead Code Elimination</h4><p>Unused code doesn&#8217;t make it into the final binary. The Go compiler marks functions, variables, and even entire packages as reachable or unreachable. If nothing in the application references a piece of code, it&#8217;s discarded during linking. This is called dead code elimination, and it works quietly without any input from the developer.</p><p>Consider a file that imports the <code>math</code> package but never calls anything from it. The compiler recognizes that no functions from <code>math</code> are reachable and tells the linker not to include them.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UHhw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff212b028-48da-4b2d-bc8c-5561cc36b9a7_1111x348.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UHhw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff212b028-48da-4b2d-bc8c-5561cc36b9a7_1111x348.png 424w, https://substackcdn.com/image/fetch/$s_!UHhw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff212b028-48da-4b2d-bc8c-5561cc36b9a7_1111x348.png 848w, https://substackcdn.com/image/fetch/$s_!UHhw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff212b028-48da-4b2d-bc8c-5561cc36b9a7_1111x348.png 1272w, https://substackcdn.com/image/fetch/$s_!UHhw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff212b028-48da-4b2d-bc8c-5561cc36b9a7_1111x348.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UHhw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff212b028-48da-4b2d-bc8c-5561cc36b9a7_1111x348.png" width="1111" height="348" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f212b028-48da-4b2d-bc8c-5561cc36b9a7_1111x348.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:348,&quot;width&quot;:1111,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:31868,&quot;alt&quot;:&quot;package main  import (     \&quot;fmt\&quot;     \&quot;math\&quot; // imported but unused )  func main() {     fmt.Println(\&quot;Hello\&quot;) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179198238?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff212b028-48da-4b2d-bc8c-5561cc36b9a7_1111x348.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (     &quot;fmt&quot;     &quot;math&quot; // imported but unused )  func main() {     fmt.Println(&quot;Hello&quot;) }" title="package main  import (     &quot;fmt&quot;     &quot;math&quot; // imported but unused )  func main() {     fmt.Println(&quot;Hello&quot;) }" srcset="https://substackcdn.com/image/fetch/$s_!UHhw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff212b028-48da-4b2d-bc8c-5561cc36b9a7_1111x348.png 424w, https://substackcdn.com/image/fetch/$s_!UHhw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff212b028-48da-4b2d-bc8c-5561cc36b9a7_1111x348.png 848w, https://substackcdn.com/image/fetch/$s_!UHhw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff212b028-48da-4b2d-bc8c-5561cc36b9a7_1111x348.png 1272w, https://substackcdn.com/image/fetch/$s_!UHhw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff212b028-48da-4b2d-bc8c-5561cc36b9a7_1111x348.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>That code won&#8217;t even compile unless <code>math</code> is used, because Go enforces import usage at build time. If it did, the unused <code>math</code> symbols would be stripped away and the final binary wouldn&#8217;t carry them.</p><p>A more realistic case is partial use of a package. Suppose a developer calls <code>strings.ToUpper</code> but doesn&#8217;t touch other parts of the <code>strings</code> package. Only the code required for <code>ToUpper</code> and its dependencies is retained.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4xbA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b4fbcd-85ff-41f5-a028-e6926456fa21_1104x420.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4xbA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b4fbcd-85ff-41f5-a028-e6926456fa21_1104x420.png 424w, https://substackcdn.com/image/fetch/$s_!4xbA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b4fbcd-85ff-41f5-a028-e6926456fa21_1104x420.png 848w, https://substackcdn.com/image/fetch/$s_!4xbA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b4fbcd-85ff-41f5-a028-e6926456fa21_1104x420.png 1272w, https://substackcdn.com/image/fetch/$s_!4xbA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b4fbcd-85ff-41f5-a028-e6926456fa21_1104x420.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4xbA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b4fbcd-85ff-41f5-a028-e6926456fa21_1104x420.png" width="1104" height="420" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/71b4fbcd-85ff-41f5-a028-e6926456fa21_1104x420.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:420,&quot;width&quot;:1104,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:38897,&quot;alt&quot;:&quot;package main  import (     \&quot;fmt\&quot;     \&quot;strings\&quot; )  func main() {     input := \&quot;welcome\&quot;     output := strings.ToUpper(input)     fmt.Println(output) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179198238?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b4fbcd-85ff-41f5-a028-e6926456fa21_1104x420.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (     &quot;fmt&quot;     &quot;strings&quot; )  func main() {     input := &quot;welcome&quot;     output := strings.ToUpper(input)     fmt.Println(output) }" title="package main  import (     &quot;fmt&quot;     &quot;strings&quot; )  func main() {     input := &quot;welcome&quot;     output := strings.ToUpper(input)     fmt.Println(output) }" srcset="https://substackcdn.com/image/fetch/$s_!4xbA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b4fbcd-85ff-41f5-a028-e6926456fa21_1104x420.png 424w, https://substackcdn.com/image/fetch/$s_!4xbA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b4fbcd-85ff-41f5-a028-e6926456fa21_1104x420.png 848w, https://substackcdn.com/image/fetch/$s_!4xbA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b4fbcd-85ff-41f5-a028-e6926456fa21_1104x420.png 1272w, https://substackcdn.com/image/fetch/$s_!4xbA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71b4fbcd-85ff-41f5-a028-e6926456fa21_1104x420.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Although <code>strings</code> has dozens of functions, the linker discards the unused ones. The pruning happens automatically and applies across all dependencies. This aggressive trimming is one of the reasons Go binaries are smaller than many fully static executables in other languages.</p><h4>Reflection and Retained Code</h4><p>Reflection complicates pruning because the compiler can&#8217;t predict what the application will ask for at runtime. Reflection lets a program inspect types, values, and struct tags dynamically. That means some metadata has to be kept even if it looks unused. A classic example is JSON encoding with struct tags. The compiler can&#8217;t discard type information for a struct that gets passed to <code>json.Marshal</code>, because the encoder reads the tags and field names at runtime.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YbgT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29d512ba-cd2d-41fb-8179-456f9f628ca8_985x598.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YbgT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29d512ba-cd2d-41fb-8179-456f9f628ca8_985x598.png 424w, https://substackcdn.com/image/fetch/$s_!YbgT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29d512ba-cd2d-41fb-8179-456f9f628ca8_985x598.png 848w, https://substackcdn.com/image/fetch/$s_!YbgT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29d512ba-cd2d-41fb-8179-456f9f628ca8_985x598.png 1272w, https://substackcdn.com/image/fetch/$s_!YbgT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29d512ba-cd2d-41fb-8179-456f9f628ca8_985x598.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YbgT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29d512ba-cd2d-41fb-8179-456f9f628ca8_985x598.png" width="985" height="598" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/29d512ba-cd2d-41fb-8179-456f9f628ca8_985x598.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:598,&quot;width&quot;:985,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:66296,&quot;alt&quot;:&quot;package main  import (     \&quot;encoding/json\&quot;     \&quot;fmt\&quot; )  type User struct {     ID    int    `json:\&quot;id\&quot;`     Email string `json:\&quot;email\&quot;` }  func main() {     u := User{ID: 10, Email: \&quot;test@example.com\&quot;}     data, _ := json.Marshal(u)     fmt.Println(string(data)) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179198238?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29d512ba-cd2d-41fb-8179-456f9f628ca8_985x598.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (     &quot;encoding/json&quot;     &quot;fmt&quot; )  type User struct {     ID    int    `json:&quot;id&quot;`     Email string `json:&quot;email&quot;` }  func main() {     u := User{ID: 10, Email: &quot;test@example.com&quot;}     data, _ := json.Marshal(u)     fmt.Println(string(data)) }" title="package main  import (     &quot;encoding/json&quot;     &quot;fmt&quot; )  type User struct {     ID    int    `json:&quot;id&quot;`     Email string `json:&quot;email&quot;` }  func main() {     u := User{ID: 10, Email: &quot;test@example.com&quot;}     data, _ := json.Marshal(u)     fmt.Println(string(data)) }" srcset="https://substackcdn.com/image/fetch/$s_!YbgT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29d512ba-cd2d-41fb-8179-456f9f628ca8_985x598.png 424w, https://substackcdn.com/image/fetch/$s_!YbgT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29d512ba-cd2d-41fb-8179-456f9f628ca8_985x598.png 848w, https://substackcdn.com/image/fetch/$s_!YbgT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29d512ba-cd2d-41fb-8179-456f9f628ca8_985x598.png 1272w, https://substackcdn.com/image/fetch/$s_!YbgT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29d512ba-cd2d-41fb-8179-456f9f628ca8_985x598.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>That simple example forces the toolchain to keep more information about <code>User</code> than it otherwise would. The struct&#8217;s field names and tags must be preserved for <code>json.Marshal</code> to work, even though they aren&#8217;t directly referenced in code.</p><p>Reflection also affects functions tied to interfaces. If a method is only called through reflection, the compiler can&#8217;t mark it as unused, so it survives pruning. This explains why binaries that lean heavily on serialization, dynamic routing, or reflection-driven frameworks tend to be larger.</p><p>Consider another case with <code>reflect.TypeOf</code>:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OyN3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6550276-c568-4fe3-810d-f9c79fcb2d17_1111x666.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OyN3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6550276-c568-4fe3-810d-f9c79fcb2d17_1111x666.png 424w, https://substackcdn.com/image/fetch/$s_!OyN3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6550276-c568-4fe3-810d-f9c79fcb2d17_1111x666.png 848w, https://substackcdn.com/image/fetch/$s_!OyN3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6550276-c568-4fe3-810d-f9c79fcb2d17_1111x666.png 1272w, https://substackcdn.com/image/fetch/$s_!OyN3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6550276-c568-4fe3-810d-f9c79fcb2d17_1111x666.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OyN3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6550276-c568-4fe3-810d-f9c79fcb2d17_1111x666.png" width="1111" height="666" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e6550276-c568-4fe3-810d-f9c79fcb2d17_1111x666.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:666,&quot;width&quot;:1111,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:65078,&quot;alt&quot;:&quot;package main  import (     \&quot;fmt\&quot;     \&quot;reflect\&quot; )  type Report struct {     Name string     Size int }  func main() {     t := reflect.TypeOf(Report{})     for i := 0; i < t.NumField(); i++ {         field := t.Field(i)         fmt.Println(\&quot;Field:\&quot;, field.Name)     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179198238?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6550276-c568-4fe3-810d-f9c79fcb2d17_1111x666.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (     &quot;fmt&quot;     &quot;reflect&quot; )  type Report struct {     Name string     Size int }  func main() {     t := reflect.TypeOf(Report{})     for i := 0; i < t.NumField(); i++ {         field := t.Field(i)         fmt.Println(&quot;Field:&quot;, field.Name)     } }" title="package main  import (     &quot;fmt&quot;     &quot;reflect&quot; )  type Report struct {     Name string     Size int }  func main() {     t := reflect.TypeOf(Report{})     for i := 0; i < t.NumField(); i++ {         field := t.Field(i)         fmt.Println(&quot;Field:&quot;, field.Name)     } }" srcset="https://substackcdn.com/image/fetch/$s_!OyN3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6550276-c568-4fe3-810d-f9c79fcb2d17_1111x666.png 424w, https://substackcdn.com/image/fetch/$s_!OyN3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6550276-c568-4fe3-810d-f9c79fcb2d17_1111x666.png 848w, https://substackcdn.com/image/fetch/$s_!OyN3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6550276-c568-4fe3-810d-f9c79fcb2d17_1111x666.png 1272w, https://substackcdn.com/image/fetch/$s_!OyN3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6550276-c568-4fe3-810d-f9c79fcb2d17_1111x666.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The reflection call forces metadata about <code>Report</code>&#8217;s fields to remain inside the binary. Without reflection, most of that information could be stripped. This shows how runtime inspection shapes the size of the executable.</p><h3>Compiler and Linker Flags That Affect Size</h3><p>Go binaries are shaped not only by automatic pruning but also by the build flags that give developers direct control over what goes into the final file. The compiler makes the first cut, but the linker carries most of the responsibility for applying flags that adjust size. Each option influences different aspects of the build process, from the format of the binary to the presence of debug information.</p><h4>Build Mode Impact</h4><p>Go supports multiple build modes, and each mode changes the composition of the final output. A standard <code>go build</code> produces a self-contained executable that bundles the Go runtime and library code. On some systems it still relies on system libraries, which keeps distribution simple but can add to file size.</p><p><code>-buildmode=c-shared</code> produces a C-ABI shared library from a main package and still carries the Go runtime plus needed packages. It exists to embed Go in a C host, not as a general size-reduction path for Go apps.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6NIn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb87dc96-32a3-4acc-a03d-4f8dcb0b8bf5_1059x34.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6NIn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb87dc96-32a3-4acc-a03d-4f8dcb0b8bf5_1059x34.png 424w, https://substackcdn.com/image/fetch/$s_!6NIn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb87dc96-32a3-4acc-a03d-4f8dcb0b8bf5_1059x34.png 848w, https://substackcdn.com/image/fetch/$s_!6NIn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb87dc96-32a3-4acc-a03d-4f8dcb0b8bf5_1059x34.png 1272w, https://substackcdn.com/image/fetch/$s_!6NIn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb87dc96-32a3-4acc-a03d-4f8dcb0b8bf5_1059x34.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6NIn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb87dc96-32a3-4acc-a03d-4f8dcb0b8bf5_1059x34.png" width="727" height="23.34088762983947" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bb87dc96-32a3-4acc-a03d-4f8dcb0b8bf5_1059x34.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:34,&quot;width&quot;:1059,&quot;resizeWidth&quot;:727,&quot;bytes&quot;:12092,&quot;alt&quot;:&quot;go build -buildmode=c-shared -o libthing.so .&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179198238?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb87dc96-32a3-4acc-a03d-4f8dcb0b8bf5_1059x34.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="go build -buildmode=c-shared -o libthing.so ." title="go build -buildmode=c-shared -o libthing.so ." srcset="https://substackcdn.com/image/fetch/$s_!6NIn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb87dc96-32a3-4acc-a03d-4f8dcb0b8bf5_1059x34.png 424w, https://substackcdn.com/image/fetch/$s_!6NIn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb87dc96-32a3-4acc-a03d-4f8dcb0b8bf5_1059x34.png 848w, https://substackcdn.com/image/fetch/$s_!6NIn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb87dc96-32a3-4acc-a03d-4f8dcb0b8bf5_1059x34.png 1272w, https://substackcdn.com/image/fetch/$s_!6NIn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb87dc96-32a3-4acc-a03d-4f8dcb0b8bf5_1059x34.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>That command produces a <code>.so</code> library file that includes the Go runtime and the Go packages it depends on. The host program doesn&#8217;t supply a Go runtime. Loading multiple Go c-shared libraries in one process is restricted and can fail because each shared object assumes it is the only Go runtime in the process.</p><p>A plugin built with <code>-buildmode=plugin</code> relies on a Go host to load and run it. Size varies by what the plugin contains, and plugins are supported on Linux, FreeBSD, and macOS.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LGP4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06ecab37-39e0-4b51-a991-1465c7d90c18_1053x34.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LGP4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06ecab37-39e0-4b51-a991-1465c7d90c18_1053x34.png 424w, https://substackcdn.com/image/fetch/$s_!LGP4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06ecab37-39e0-4b51-a991-1465c7d90c18_1053x34.png 848w, https://substackcdn.com/image/fetch/$s_!LGP4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06ecab37-39e0-4b51-a991-1465c7d90c18_1053x34.png 1272w, https://substackcdn.com/image/fetch/$s_!LGP4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06ecab37-39e0-4b51-a991-1465c7d90c18_1053x34.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LGP4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06ecab37-39e0-4b51-a991-1465c7d90c18_1053x34.png" width="1053" height="34" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/06ecab37-39e0-4b51-a991-1465c7d90c18_1053x34.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:34,&quot;width&quot;:1053,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:14054,&quot;alt&quot;:&quot;go build -buildmode=plugin -o greeter.so greeter.go&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179198238?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06ecab37-39e0-4b51-a991-1465c7d90c18_1053x34.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="go build -buildmode=plugin -o greeter.so greeter.go" title="go build -buildmode=plugin -o greeter.so greeter.go" srcset="https://substackcdn.com/image/fetch/$s_!LGP4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06ecab37-39e0-4b51-a991-1465c7d90c18_1053x34.png 424w, https://substackcdn.com/image/fetch/$s_!LGP4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06ecab37-39e0-4b51-a991-1465c7d90c18_1053x34.png 848w, https://substackcdn.com/image/fetch/$s_!LGP4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06ecab37-39e0-4b51-a991-1465c7d90c18_1053x34.png 1272w, https://substackcdn.com/image/fetch/$s_!LGP4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06ecab37-39e0-4b51-a991-1465c7d90c18_1053x34.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Plugin binaries still carry Go&#8217;s runtime and imported packages, so file size stays close to other Go outputs, and they only work in contexts that support plugin loading. The choice of build mode is one of the biggest factors in how much code gets pulled into the binary.</p><h4>The Trimpath Option</h4><p>Go embeds build paths into binaries unless told not to. These paths point back to source files on the developer&#8217;s machine. While they don&#8217;t add a huge amount of weight, they can clutter a binary with machine-specific details that aren&#8217;t useful outside of debugging.</p><p>The <code>-trimpath</code> flag removes this metadata.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fH2s!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9623840f-33e3-4f1a-8584-445fc69aea50_1055x32.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fH2s!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9623840f-33e3-4f1a-8584-445fc69aea50_1055x32.png 424w, https://substackcdn.com/image/fetch/$s_!fH2s!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9623840f-33e3-4f1a-8584-445fc69aea50_1055x32.png 848w, https://substackcdn.com/image/fetch/$s_!fH2s!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9623840f-33e3-4f1a-8584-445fc69aea50_1055x32.png 1272w, https://substackcdn.com/image/fetch/$s_!fH2s!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9623840f-33e3-4f1a-8584-445fc69aea50_1055x32.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fH2s!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9623840f-33e3-4f1a-8584-445fc69aea50_1055x32.png" width="1055" height="32" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9623840f-33e3-4f1a-8584-445fc69aea50_1055x32.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:32,&quot;width&quot;:1055,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:7117,&quot;alt&quot;:&quot;go build -trimpath -o trimmed .&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179198238?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9623840f-33e3-4f1a-8584-445fc69aea50_1055x32.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="go build -trimpath -o trimmed ." title="go build -trimpath -o trimmed ." srcset="https://substackcdn.com/image/fetch/$s_!fH2s!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9623840f-33e3-4f1a-8584-445fc69aea50_1055x32.png 424w, https://substackcdn.com/image/fetch/$s_!fH2s!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9623840f-33e3-4f1a-8584-445fc69aea50_1055x32.png 848w, https://substackcdn.com/image/fetch/$s_!fH2s!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9623840f-33e3-4f1a-8584-445fc69aea50_1055x32.png 1272w, https://substackcdn.com/image/fetch/$s_!fH2s!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9623840f-33e3-4f1a-8584-445fc69aea50_1055x32.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The resulting file no longer contains the absolute source paths. This not only shaves off a little size but also helps reproducibility. Two builds from different directories will no longer differ in embedded paths, which is useful when generating checksums for distribution. Though the reduction isn&#8217;t dramatic, it&#8217;s part of the broader set of small adjustments that accumulate into measurable savings.</p><h4>Linker Options with Ldflags</h4><p>The linker accepts several options through the <code>-ldflags</code> parameter, and these have a more direct impact on file size than build modes. The most common are <code>-s</code> and <code>-w</code>, which strip the symbol table and DWARF data.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RpCf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed0357b7-5166-40c5-a626-cb234b0661c5_1060x39.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RpCf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed0357b7-5166-40c5-a626-cb234b0661c5_1060x39.png 424w, https://substackcdn.com/image/fetch/$s_!RpCf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed0357b7-5166-40c5-a626-cb234b0661c5_1060x39.png 848w, https://substackcdn.com/image/fetch/$s_!RpCf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed0357b7-5166-40c5-a626-cb234b0661c5_1060x39.png 1272w, https://substackcdn.com/image/fetch/$s_!RpCf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed0357b7-5166-40c5-a626-cb234b0661c5_1060x39.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RpCf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed0357b7-5166-40c5-a626-cb234b0661c5_1060x39.png" width="1060" height="39" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ed0357b7-5166-40c5-a626-cb234b0661c5_1060x39.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:39,&quot;width&quot;:1060,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:11086,&quot;alt&quot;:&quot;go build -ldflags=\&quot;-s -w\&quot; -o lean_binary .&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179198238?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed0357b7-5166-40c5-a626-cb234b0661c5_1060x39.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="go build -ldflags=&quot;-s -w&quot; -o lean_binary ." title="go build -ldflags=&quot;-s -w&quot; -o lean_binary ." srcset="https://substackcdn.com/image/fetch/$s_!RpCf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed0357b7-5166-40c5-a626-cb234b0661c5_1060x39.png 424w, https://substackcdn.com/image/fetch/$s_!RpCf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed0357b7-5166-40c5-a626-cb234b0661c5_1060x39.png 848w, https://substackcdn.com/image/fetch/$s_!RpCf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed0357b7-5166-40c5-a626-cb234b0661c5_1060x39.png 1272w, https://substackcdn.com/image/fetch/$s_!RpCf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed0357b7-5166-40c5-a626-cb234b0661c5_1060x39.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>That binary runs just like the unstripped version but lacks debugging metadata. Developers often combine these flags with other linker variables. The <code>-X</code> option allows setting values for string variables at build time.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_uH2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce3b7239-96b7-4dff-b7f1-85ef08237eb0_1048x34.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_uH2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce3b7239-96b7-4dff-b7f1-85ef08237eb0_1048x34.png 424w, https://substackcdn.com/image/fetch/$s_!_uH2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce3b7239-96b7-4dff-b7f1-85ef08237eb0_1048x34.png 848w, https://substackcdn.com/image/fetch/$s_!_uH2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce3b7239-96b7-4dff-b7f1-85ef08237eb0_1048x34.png 1272w, https://substackcdn.com/image/fetch/$s_!_uH2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce3b7239-96b7-4dff-b7f1-85ef08237eb0_1048x34.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_uH2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce3b7239-96b7-4dff-b7f1-85ef08237eb0_1048x34.png" width="1048" height="34" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ce3b7239-96b7-4dff-b7f1-85ef08237eb0_1048x34.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:34,&quot;width&quot;:1048,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:14252,&quot;alt&quot;:&quot;go build -ldflags=\&quot;-X main.version=1.4.7 -s -w\&quot; -o app .&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179198238?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce3b7239-96b7-4dff-b7f1-85ef08237eb0_1048x34.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="go build -ldflags=&quot;-X main.version=1.4.7 -s -w&quot; -o app ." title="go build -ldflags=&quot;-X main.version=1.4.7 -s -w&quot; -o app ." srcset="https://substackcdn.com/image/fetch/$s_!_uH2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce3b7239-96b7-4dff-b7f1-85ef08237eb0_1048x34.png 424w, https://substackcdn.com/image/fetch/$s_!_uH2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce3b7239-96b7-4dff-b7f1-85ef08237eb0_1048x34.png 848w, https://substackcdn.com/image/fetch/$s_!_uH2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce3b7239-96b7-4dff-b7f1-85ef08237eb0_1048x34.png 1272w, https://substackcdn.com/image/fetch/$s_!_uH2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce3b7239-96b7-4dff-b7f1-85ef08237eb0_1048x34.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The above embeds a version string into the binary while still stripping debug data. The tradeoff is that some extra bytes are added for the version, though usually the reduction from stripping outweighs the addition.</p><p>It&#8217;s also possible to embed build time information, commit hashes, or other markers with <code>-X</code>. While this increases size slightly, the impact is minor compared to the removal of debugging data. The linker applies these settings during the final stage, which makes them powerful tools for controlling size and content.</p><h4>External Linkmode</h4><p>Go defaults to internal linking, where the Go linker alone builds the final binary. With pure Go (no cgo) on Linux, that binary does not depend on external libc. With cgo or on platforms like macOS or Windows, the final file still links to system libraries and carries a dynamic header by default. Internal linking keeps control in the Go linker, while <code>-linkmode=external</code> hands the final step to the system linker.</p><p>With <code>-linkmode=external</code>, the Go toolchain defers linking to the system&#8217;s native linker. This shifts some responsibility to the operating system and its libraries.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!g2dE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652328fc-67c5-4718-9ee3-1517cbb04a04_1049x35.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g2dE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652328fc-67c5-4718-9ee3-1517cbb04a04_1049x35.png 424w, https://substackcdn.com/image/fetch/$s_!g2dE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652328fc-67c5-4718-9ee3-1517cbb04a04_1049x35.png 848w, https://substackcdn.com/image/fetch/$s_!g2dE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652328fc-67c5-4718-9ee3-1517cbb04a04_1049x35.png 1272w, https://substackcdn.com/image/fetch/$s_!g2dE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652328fc-67c5-4718-9ee3-1517cbb04a04_1049x35.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g2dE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652328fc-67c5-4718-9ee3-1517cbb04a04_1049x35.png" width="1049" height="35" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/652328fc-67c5-4718-9ee3-1517cbb04a04_1049x35.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:35,&quot;width&quot;:1049,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:16106,&quot;alt&quot;:&quot;go build -ldflags=\&quot;-linkmode=external\&quot; -o external_binary .&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179198238?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652328fc-67c5-4718-9ee3-1517cbb04a04_1049x35.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="go build -ldflags=&quot;-linkmode=external&quot; -o external_binary ." title="go build -ldflags=&quot;-linkmode=external&quot; -o external_binary ." srcset="https://substackcdn.com/image/fetch/$s_!g2dE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652328fc-67c5-4718-9ee3-1517cbb04a04_1049x35.png 424w, https://substackcdn.com/image/fetch/$s_!g2dE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652328fc-67c5-4718-9ee3-1517cbb04a04_1049x35.png 848w, https://substackcdn.com/image/fetch/$s_!g2dE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652328fc-67c5-4718-9ee3-1517cbb04a04_1049x35.png 1272w, https://substackcdn.com/image/fetch/$s_!g2dE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F652328fc-67c5-4718-9ee3-1517cbb04a04_1049x35.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>That command produces a binary that may rely on system libraries instead of embedding them. In some cases this reduces size, especially on systems where libraries are already present. However, portability is reduced because the binary now expects certain libraries to exist on the target machine.</p><p>A more specialized case is cgo integration. When Go code calls into C, external linking is sometimes required. This lets the system linker resolve references to C libraries without packaging them entirely inside the binary. The tradeoff is a leaner file at the cost of higher dependency on the environment where the binary runs.</p><h3>Conclusion</h3><p>Go&#8217;s toolchain works through a careful balance of pruning, stripping, and flag-driven control to decide what belongs in the final binary. Each step, from dead code elimination to linker decisions, has a mechanical reason behind it that shapes the size of the file. With an awareness of how symbols, reflection, build modes, and linker options interact, developers can read binary size not as an accident but as the product of deliberate steps in the build process.</p><ol><li><p><em><a href="https://go.dev/doc/cmd">Go Command Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/cmd/go#hdr-Compile_and_install_packages_and_dependencies">Go Build and Install Packages</a></em></p></li><li><p><em><a href="https://pkg.go.dev/cmd/link">Go Linker Flags Reference</a></em></p></li><li><p><em><a href="https://pkg.go.dev/reflect">Go Reflection Package</a></em></p></li><li><p><em><a href="https://pkg.go.dev/encoding/json">Go Encoding JSON Package</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Go String Concatenation Costs]]></title><description><![CDATA[Go&#8217;s channels are one of the language&#8217;s most defining features.]]></description><link>https://alexanderobregon.substack.com/p/go-string-concatenation-costs</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/go-string-concatenation-costs</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Fri, 21 Nov 2025 20:26:04 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/852bdb00-5cdd-4322-bcbb-2566bf83bfe0_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>Go String Concatenation Costs</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7-EN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e6301d-5377-4d6b-a57f-e0515457353f_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7-EN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e6301d-5377-4d6b-a57f-e0515457353f_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!7-EN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e6301d-5377-4d6b-a57f-e0515457353f_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!7-EN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e6301d-5377-4d6b-a57f-e0515457353f_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!7-EN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e6301d-5377-4d6b-a57f-e0515457353f_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7-EN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e6301d-5377-4d6b-a57f-e0515457353f_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/16e6301d-5377-4d6b-a57f-e0515457353f_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7-EN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e6301d-5377-4d6b-a57f-e0515457353f_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!7-EN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e6301d-5377-4d6b-a57f-e0515457353f_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!7-EN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e6301d-5377-4d6b-a57f-e0515457353f_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!7-EN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e6301d-5377-4d6b-a57f-e0515457353f_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>String handling shows up across nearly all Go projects, from web servers to command line utilities. Joining text is a basic operation in code, but the runtime has to put in real work to make it happen. Every concatenation can trigger a new memory allocation, a round of data copying, and compiler decisions that influence performance. To see the costs, we need to look at how Go represents strings, how the compiler translates concatenation into runtime calls, and what happens when many joins are chained one after another.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>Mechanics of Go String Joining</h3><p>Strings are immutable, which means every join allocates a fresh block of memory rather than altering an existing one. The details of how Go manages that process start with the string header itself, then extend to how the compiler handles concatenation and how the allocator provides space for the final result.</p><h4>How Go Represents Strings</h4><p>Go&#8217;s string type is a two-field structure: a pointer to a block of bytes and a length. The bytes themselves are immutable, meaning once a string is created its contents never change. What you manipulate in code is the header pointing to that data.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pf6Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f069887-fad4-4528-92bb-37ea654d57cf_1178x416.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pf6Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f069887-fad4-4528-92bb-37ea654d57cf_1178x416.png 424w, https://substackcdn.com/image/fetch/$s_!pf6Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f069887-fad4-4528-92bb-37ea654d57cf_1178x416.png 848w, https://substackcdn.com/image/fetch/$s_!pf6Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f069887-fad4-4528-92bb-37ea654d57cf_1178x416.png 1272w, https://substackcdn.com/image/fetch/$s_!pf6Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f069887-fad4-4528-92bb-37ea654d57cf_1178x416.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pf6Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f069887-fad4-4528-92bb-37ea654d57cf_1178x416.png" width="1178" height="416" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5f069887-fad4-4528-92bb-37ea654d57cf_1178x416.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:416,&quot;width&quot;:1178,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:48658,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179191053?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f069887-fad4-4528-92bb-37ea654d57cf_1178x416.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pf6Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f069887-fad4-4528-92bb-37ea654d57cf_1178x416.png 424w, https://substackcdn.com/image/fetch/$s_!pf6Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f069887-fad4-4528-92bb-37ea654d57cf_1178x416.png 848w, https://substackcdn.com/image/fetch/$s_!pf6Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f069887-fad4-4528-92bb-37ea654d57cf_1178x416.png 1272w, https://substackcdn.com/image/fetch/$s_!pf6Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f069887-fad4-4528-92bb-37ea654d57cf_1178x416.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>What&#8217;s measured in that call to <code>unsafe.Sizeof</code> is just the header, not the actual memory that holds the characters. String constants such as <code>&#8220;world&#8221;</code> live in read-only sections of the binary. Values created during runtime can be stack-allocated when they don&#8217;t escape or heap-allocated when they do and if they&#8217;re on the heap they&#8217;re managed by the garbage collector. Concatenation still creates a fresh block for the result rather than modifying an existing one.</p><h4>How Concatenation Works in the Compiler</h4><p>Go&#8217;s compiler handles string concatenation differently depending on what&#8217;s being combined. If everything is a constant, the compiler merges it into a single value during build time, so no runtime work is needed.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Viej!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff710c551-7be2-4d32-bc0f-d5cce49bdf43_1263x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Viej!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff710c551-7be2-4d32-bc0f-d5cce49bdf43_1263x283.png 424w, https://substackcdn.com/image/fetch/$s_!Viej!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff710c551-7be2-4d32-bc0f-d5cce49bdf43_1263x283.png 848w, https://substackcdn.com/image/fetch/$s_!Viej!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff710c551-7be2-4d32-bc0f-d5cce49bdf43_1263x283.png 1272w, https://substackcdn.com/image/fetch/$s_!Viej!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff710c551-7be2-4d32-bc0f-d5cce49bdf43_1263x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Viej!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff710c551-7be2-4d32-bc0f-d5cce49bdf43_1263x283.png" width="1263" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f710c551-7be2-4d32-bc0f-d5cce49bdf43_1263x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:1263,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:38002,&quot;alt&quot;:&quot;package main  import \&quot;fmt\&quot;  func main() {     s := \&quot;Go\&quot; + \&quot;Lang\&quot;     fmt.Println(s) // folded to the constant \&quot;GoLang\&quot;, no runtime allocation }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179191053?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff710c551-7be2-4d32-bc0f-d5cce49bdf43_1263x283.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;fmt&quot;  func main() {     s := &quot;Go&quot; + &quot;Lang&quot;     fmt.Println(s) // folded to the constant &quot;GoLang&quot;, no runtime allocation }" title="package main  import &quot;fmt&quot;  func main() {     s := &quot;Go&quot; + &quot;Lang&quot;     fmt.Println(s) // folded to the constant &quot;GoLang&quot;, no runtime allocation }" srcset="https://substackcdn.com/image/fetch/$s_!Viej!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff710c551-7be2-4d32-bc0f-d5cce49bdf43_1263x283.png 424w, https://substackcdn.com/image/fetch/$s_!Viej!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff710c551-7be2-4d32-bc0f-d5cce49bdf43_1263x283.png 848w, https://substackcdn.com/image/fetch/$s_!Viej!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff710c551-7be2-4d32-bc0f-d5cce49bdf43_1263x283.png 1272w, https://substackcdn.com/image/fetch/$s_!Viej!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff710c551-7be2-4d32-bc0f-d5cce49bdf43_1263x283.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>That statement compiles down to a single literal. Nothing is allocated while the program runs.</p><p>When at least one part comes from a variable, the compiler generates a call to <code>runtime.concatstrings</code> or a similar helper. That function calculates the final length, allocates enough memory for it, and then copies the data from each operand.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KuLV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F725b79a1-609d-47cc-9f9e-6756db5673c0_1116x350.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KuLV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F725b79a1-609d-47cc-9f9e-6756db5673c0_1116x350.png 424w, https://substackcdn.com/image/fetch/$s_!KuLV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F725b79a1-609d-47cc-9f9e-6756db5673c0_1116x350.png 848w, https://substackcdn.com/image/fetch/$s_!KuLV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F725b79a1-609d-47cc-9f9e-6756db5673c0_1116x350.png 1272w, https://substackcdn.com/image/fetch/$s_!KuLV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F725b79a1-609d-47cc-9f9e-6756db5673c0_1116x350.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KuLV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F725b79a1-609d-47cc-9f9e-6756db5673c0_1116x350.png" width="1116" height="350" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/725b79a1-609d-47cc-9f9e-6756db5673c0_1116x350.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:350,&quot;width&quot;:1116,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:37623,&quot;alt&quot;:&quot;package main  import \&quot;fmt\&quot;  func main() {     a := \&quot;Go\&quot;     b := \&quot;Lang\&quot;     c := a + b     fmt.Println(c) // handled by runtime.concatstrings }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179191053?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F725b79a1-609d-47cc-9f9e-6756db5673c0_1116x350.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;fmt&quot;  func main() {     a := &quot;Go&quot;     b := &quot;Lang&quot;     c := a + b     fmt.Println(c) // handled by runtime.concatstrings }" title="package main  import &quot;fmt&quot;  func main() {     a := &quot;Go&quot;     b := &quot;Lang&quot;     c := a + b     fmt.Println(c) // handled by runtime.concatstrings }" srcset="https://substackcdn.com/image/fetch/$s_!KuLV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F725b79a1-609d-47cc-9f9e-6756db5673c0_1116x350.png 424w, https://substackcdn.com/image/fetch/$s_!KuLV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F725b79a1-609d-47cc-9f9e-6756db5673c0_1116x350.png 848w, https://substackcdn.com/image/fetch/$s_!KuLV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F725b79a1-609d-47cc-9f9e-6756db5673c0_1116x350.png 1272w, https://substackcdn.com/image/fetch/$s_!KuLV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F725b79a1-609d-47cc-9f9e-6756db5673c0_1116x350.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Go&#8217;s compiler also collapses expressions with multiple terms written in one statement. So writing <code>a + b + c + d</code> leads to a single allocation, not a chain of smaller ones. But if concatenation is broken across separate statements or repeated in a loop, the compiler can&#8217;t merge them and multiple allocations occur.</p><h4>Memory Allocation During Concatenation</h4><p>Every concatenation at runtime creates a new string value backed by memory large enough to hold the final bytes. When that backing memory lives on the heap, the allocator reserves a block of the right size and the runtime copies bytes from all the parts into that space. Old values remain untouched and will eventually be reclaimed by the garbage collector if they&#8217;re not referenced anymore.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jo_w!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4933e79b-e4d3-49d4-a1b1-ca1dcf10a370_981x801.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jo_w!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4933e79b-e4d3-49d4-a1b1-ca1dcf10a370_981x801.png 424w, https://substackcdn.com/image/fetch/$s_!jo_w!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4933e79b-e4d3-49d4-a1b1-ca1dcf10a370_981x801.png 848w, https://substackcdn.com/image/fetch/$s_!jo_w!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4933e79b-e4d3-49d4-a1b1-ca1dcf10a370_981x801.png 1272w, https://substackcdn.com/image/fetch/$s_!jo_w!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4933e79b-e4d3-49d4-a1b1-ca1dcf10a370_981x801.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jo_w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4933e79b-e4d3-49d4-a1b1-ca1dcf10a370_981x801.png" width="981" height="801" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4933e79b-e4d3-49d4-a1b1-ca1dcf10a370_981x801.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:801,&quot;width&quot;:981,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83657,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179191053?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4933e79b-e4d3-49d4-a1b1-ca1dcf10a370_981x801.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jo_w!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4933e79b-e4d3-49d4-a1b1-ca1dcf10a370_981x801.png 424w, https://substackcdn.com/image/fetch/$s_!jo_w!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4933e79b-e4d3-49d4-a1b1-ca1dcf10a370_981x801.png 848w, https://substackcdn.com/image/fetch/$s_!jo_w!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4933e79b-e4d3-49d4-a1b1-ca1dcf10a370_981x801.png 1272w, https://substackcdn.com/image/fetch/$s_!jo_w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4933e79b-e4d3-49d4-a1b1-ca1dcf10a370_981x801.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Reading from <code>runtime.MemStats</code> makes it possible to watch allocations increase after a concatenation. The allocator organizes memory into classes by size, which keeps allocation performance stable. Very short strings are placed into small fixed blocks, while longer ones require larger chunks. Regardless of class, each concatenation still involves copying bytes into a new block.</p><p>Large concatenations amplify this effect because more bytes have to be moved before the result is ready. When repeated often, that copying dominates performance costs, and it becomes clear why Go provides alternative tools for heavy string building.</p><h3>What Happens With Repeated Concatenation</h3><p>Concatenating a single pair of strings is not very expensive on its own, but the cost starts to grow once the operation is repeated many times. When a string is extended step by step, the runtime allocates new space on every step and copies the existing content into the new block. That means the number of bytes moved across memory builds up faster than the final length might suggest.</p><h4>The Problem of Growing Strings in a Loop</h4><p>A loop that extends a string one character at a time creates an ever-increasing amount of work. Each iteration allocates a new block of memory and then copies the entire previous string into it, plus the new character. That process leads to quadratic growth in the number of bytes moved.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JdCG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14aa31d-0e49-42d5-9e4d-3552a19368c9_1111x383.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JdCG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14aa31d-0e49-42d5-9e4d-3552a19368c9_1111x383.png 424w, https://substackcdn.com/image/fetch/$s_!JdCG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14aa31d-0e49-42d5-9e4d-3552a19368c9_1111x383.png 848w, https://substackcdn.com/image/fetch/$s_!JdCG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14aa31d-0e49-42d5-9e4d-3552a19368c9_1111x383.png 1272w, https://substackcdn.com/image/fetch/$s_!JdCG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14aa31d-0e49-42d5-9e4d-3552a19368c9_1111x383.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JdCG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14aa31d-0e49-42d5-9e4d-3552a19368c9_1111x383.png" width="1111" height="383" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b14aa31d-0e49-42d5-9e4d-3552a19368c9_1111x383.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:383,&quot;width&quot;:1111,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:31833,&quot;alt&quot;:&quot;package main  import \&quot;fmt\&quot;  func main() {     var s string     for i := 0; i < 10; i++ {         s += \&quot;x\&quot;         fmt.Println(len(s))     } }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179191053?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14aa31d-0e49-42d5-9e4d-3552a19368c9_1111x383.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import &quot;fmt&quot;  func main() {     var s string     for i := 0; i < 10; i++ {         s += &quot;x&quot;         fmt.Println(len(s))     } }" title="package main  import &quot;fmt&quot;  func main() {     var s string     for i := 0; i < 10; i++ {         s += &quot;x&quot;         fmt.Println(len(s))     } }" srcset="https://substackcdn.com/image/fetch/$s_!JdCG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14aa31d-0e49-42d5-9e4d-3552a19368c9_1111x383.png 424w, https://substackcdn.com/image/fetch/$s_!JdCG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14aa31d-0e49-42d5-9e4d-3552a19368c9_1111x383.png 848w, https://substackcdn.com/image/fetch/$s_!JdCG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14aa31d-0e49-42d5-9e4d-3552a19368c9_1111x383.png 1272w, https://substackcdn.com/image/fetch/$s_!JdCG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb14aa31d-0e49-42d5-9e4d-3552a19368c9_1111x383.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>On every iteration of this example, Go allocates a block just large enough for the new string and then copies all of the existing characters into it. For 1000 iterations, the final string length is 1000, but the total amount of copying reaches roughly half a million characters.</p><p>That hidden cost often becomes visible in performance tests. A program may appear to work correctly, but execution time rises sharply as the loop size grows. The immutable nature of strings means there&#8217;s no way to extend the old buffer in place, so repeated concatenation quickly becomes inefficient.</p><h4>Why Builders are Faster</h4><p>Go provides <code>strings.Builder</code> to build text without paying the same penalty on every step. A builder wraps a growable byte slice and manages capacity internally. When the slice fills up, it allocates a larger block and copies the old data into it, growing capacity geometrically (policy is runtime-dependent) to keep the number of allocations small.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!br_g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a59338-a98b-4151-887a-1caea47e0caf_1115x521.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!br_g!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a59338-a98b-4151-887a-1caea47e0caf_1115x521.png 424w, https://substackcdn.com/image/fetch/$s_!br_g!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a59338-a98b-4151-887a-1caea47e0caf_1115x521.png 848w, https://substackcdn.com/image/fetch/$s_!br_g!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a59338-a98b-4151-887a-1caea47e0caf_1115x521.png 1272w, https://substackcdn.com/image/fetch/$s_!br_g!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a59338-a98b-4151-887a-1caea47e0caf_1115x521.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!br_g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a59338-a98b-4151-887a-1caea47e0caf_1115x521.png" width="1115" height="521" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/82a59338-a98b-4151-887a-1caea47e0caf_1115x521.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:521,&quot;width&quot;:1115,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:53494,&quot;alt&quot;:&quot;package main  import (     \&quot;fmt\&quot;     \&quot;strings\&quot; )  func main() {     var b strings.Builder     for i := 0; i < 10; i++ {         b.WriteString(\&quot;x\&quot;)     }     result := b.String()     fmt.Println(result) // prints \&quot;xxxxxxxxxx\&quot; }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179191053?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a59338-a98b-4151-887a-1caea47e0caf_1115x521.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (     &quot;fmt&quot;     &quot;strings&quot; )  func main() {     var b strings.Builder     for i := 0; i < 10; i++ {         b.WriteString(&quot;x&quot;)     }     result := b.String()     fmt.Println(result) // prints &quot;xxxxxxxxxx&quot; }" title="package main  import (     &quot;fmt&quot;     &quot;strings&quot; )  func main() {     var b strings.Builder     for i := 0; i < 10; i++ {         b.WriteString(&quot;x&quot;)     }     result := b.String()     fmt.Println(result) // prints &quot;xxxxxxxxxx&quot; }" srcset="https://substackcdn.com/image/fetch/$s_!br_g!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a59338-a98b-4151-887a-1caea47e0caf_1115x521.png 424w, https://substackcdn.com/image/fetch/$s_!br_g!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a59338-a98b-4151-887a-1caea47e0caf_1115x521.png 848w, https://substackcdn.com/image/fetch/$s_!br_g!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a59338-a98b-4151-887a-1caea47e0caf_1115x521.png 1272w, https://substackcdn.com/image/fetch/$s_!br_g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a59338-a98b-4151-887a-1caea47e0caf_1115x521.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This pattern reduces allocations from &#8220;one per iteration&#8221; down to only a handful, depending on how the slice grows. That difference becomes dramatic at larger scales.</p><p>Builders also support writing bytes directly, which is faster when appending single characters rather than strings.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pIlr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed74283-f8aa-4f71-a38d-bbc9b152d356_1008x175.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pIlr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed74283-f8aa-4f71-a38d-bbc9b152d356_1008x175.png 424w, https://substackcdn.com/image/fetch/$s_!pIlr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed74283-f8aa-4f71-a38d-bbc9b152d356_1008x175.png 848w, https://substackcdn.com/image/fetch/$s_!pIlr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed74283-f8aa-4f71-a38d-bbc9b152d356_1008x175.png 1272w, https://substackcdn.com/image/fetch/$s_!pIlr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed74283-f8aa-4f71-a38d-bbc9b152d356_1008x175.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pIlr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed74283-f8aa-4f71-a38d-bbc9b152d356_1008x175.png" width="1008" height="175" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5ed74283-f8aa-4f71-a38d-bbc9b152d356_1008x175.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:175,&quot;width&quot;:1008,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:23348,&quot;alt&quot;:&quot;b := strings.Builder{} for i := 0; i < 1000; i++ {     b.WriteByte('a') } final := b.String()&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179191053?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed74283-f8aa-4f71-a38d-bbc9b152d356_1008x175.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="b := strings.Builder{} for i := 0; i < 1000; i++ {     b.WriteByte('a') } final := b.String()" title="b := strings.Builder{} for i := 0; i < 1000; i++ {     b.WriteByte('a') } final := b.String()" srcset="https://substackcdn.com/image/fetch/$s_!pIlr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed74283-f8aa-4f71-a38d-bbc9b152d356_1008x175.png 424w, https://substackcdn.com/image/fetch/$s_!pIlr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed74283-f8aa-4f71-a38d-bbc9b152d356_1008x175.png 848w, https://substackcdn.com/image/fetch/$s_!pIlr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed74283-f8aa-4f71-a38d-bbc9b152d356_1008x175.png 1272w, https://substackcdn.com/image/fetch/$s_!pIlr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed74283-f8aa-4f71-a38d-bbc9b152d356_1008x175.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>That version avoids converting single characters into one-length strings and writes directly into the buffer. With this approach, building thousands of characters costs far less than repeatedly joining immutable strings.</p><h4>Compiler Optimizations for Concatenation</h4><p>The compiler can reduce overhead in some cases by flattening expressions. When multiple strings are joined in a single statement, the compiler calculates the total length once, allocates one buffer of that size, and copies everything in one pass.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XOyu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef4d959-16be-41d2-9ee9-07d6748b453c_1230x280.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XOyu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef4d959-16be-41d2-9ee9-07d6748b453c_1230x280.png 424w, https://substackcdn.com/image/fetch/$s_!XOyu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef4d959-16be-41d2-9ee9-07d6748b453c_1230x280.png 848w, https://substackcdn.com/image/fetch/$s_!XOyu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef4d959-16be-41d2-9ee9-07d6748b453c_1230x280.png 1272w, https://substackcdn.com/image/fetch/$s_!XOyu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef4d959-16be-41d2-9ee9-07d6748b453c_1230x280.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XOyu!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef4d959-16be-41d2-9ee9-07d6748b453c_1230x280.png" width="830" height="188.9430894308943" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9ef4d959-16be-41d2-9ee9-07d6748b453c_1230x280.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:280,&quot;width&quot;:1230,&quot;resizeWidth&quot;:830,&quot;bytes&quot;:37805,&quot;alt&quot;:&quot;package main  import \&quot;fmt\&quot;  func main() {     s := \&quot;A\&quot; + \&quot;B\&quot; + \&quot;C\&quot; + \&quot;D\&quot;     fmt.Println(s) // folded to the constant \&quot;ABCD\&quot;, no runtime allocation }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179191053?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef4d959-16be-41d2-9ee9-07d6748b453c_1230x280.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="package main  import &quot;fmt&quot;  func main() {     s := &quot;A&quot; + &quot;B&quot; + &quot;C&quot; + &quot;D&quot;     fmt.Println(s) // folded to the constant &quot;ABCD&quot;, no runtime allocation }" title="package main  import &quot;fmt&quot;  func main() {     s := &quot;A&quot; + &quot;B&quot; + &quot;C&quot; + &quot;D&quot;     fmt.Println(s) // folded to the constant &quot;ABCD&quot;, no runtime allocation }" srcset="https://substackcdn.com/image/fetch/$s_!XOyu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef4d959-16be-41d2-9ee9-07d6748b453c_1230x280.png 424w, https://substackcdn.com/image/fetch/$s_!XOyu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef4d959-16be-41d2-9ee9-07d6748b453c_1230x280.png 848w, https://substackcdn.com/image/fetch/$s_!XOyu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef4d959-16be-41d2-9ee9-07d6748b453c_1230x280.png 1272w, https://substackcdn.com/image/fetch/$s_!XOyu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ef4d959-16be-41d2-9ee9-07d6748b453c_1230x280.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The compiler collapses the constant operands into a single literal at build time, so no concatenation helper runs while the code executes. That still compares favorably to a version that created intermediate results such as <code>&#8220;A&#8221; + &#8220;B&#8221;</code> and then <code>+ &#8220;C&#8221;</code> and so on.</p><p>Variables also benefit from this optimization, but only if they&#8217;re joined in the same expression.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!szHO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced12df-2437-4178-9c7e-8db93371290c_1124x72.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!szHO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced12df-2437-4178-9c7e-8db93371290c_1124x72.png 424w, https://substackcdn.com/image/fetch/$s_!szHO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced12df-2437-4178-9c7e-8db93371290c_1124x72.png 848w, https://substackcdn.com/image/fetch/$s_!szHO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced12df-2437-4178-9c7e-8db93371290c_1124x72.png 1272w, https://substackcdn.com/image/fetch/$s_!szHO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced12df-2437-4178-9c7e-8db93371290c_1124x72.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!szHO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced12df-2437-4178-9c7e-8db93371290c_1124x72.png" width="1124" height="72" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ced12df-2437-4178-9c7e-8db93371290c_1124x72.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:72,&quot;width&quot;:1124,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:11328,&quot;alt&quot;:&quot;a, b, c := \&quot;foo\&quot;, \&quot;bar\&quot;, \&quot;baz\&quot; joined := a + b + c&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179191053?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced12df-2437-4178-9c7e-8db93371290c_1124x72.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="a, b, c := &quot;foo&quot;, &quot;bar&quot;, &quot;baz&quot; joined := a + b + c" title="a, b, c := &quot;foo&quot;, &quot;bar&quot;, &quot;baz&quot; joined := a + b + c" srcset="https://substackcdn.com/image/fetch/$s_!szHO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced12df-2437-4178-9c7e-8db93371290c_1124x72.png 424w, https://substackcdn.com/image/fetch/$s_!szHO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced12df-2437-4178-9c7e-8db93371290c_1124x72.png 848w, https://substackcdn.com/image/fetch/$s_!szHO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced12df-2437-4178-9c7e-8db93371290c_1124x72.png 1272w, https://substackcdn.com/image/fetch/$s_!szHO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ced12df-2437-4178-9c7e-8db93371290c_1124x72.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>This compiles to a single runtime call that performs one allocation sized for the entire result.</p><p>Breaking the work into multiple statements prevents this optimization.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cmnO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F702658f7-4250-433b-a627-b5647d6aba95_1130x71.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cmnO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F702658f7-4250-433b-a627-b5647d6aba95_1130x71.png 424w, https://substackcdn.com/image/fetch/$s_!cmnO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F702658f7-4250-433b-a627-b5647d6aba95_1130x71.png 848w, https://substackcdn.com/image/fetch/$s_!cmnO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F702658f7-4250-433b-a627-b5647d6aba95_1130x71.png 1272w, https://substackcdn.com/image/fetch/$s_!cmnO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F702658f7-4250-433b-a627-b5647d6aba95_1130x71.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cmnO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F702658f7-4250-433b-a627-b5647d6aba95_1130x71.png" width="1130" height="71" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/702658f7-4250-433b-a627-b5647d6aba95_1130x71.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:71,&quot;width&quot;:1130,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:8195,&quot;alt&quot;:&quot;part := a + b joined := part + c&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179191053?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F702658f7-4250-433b-a627-b5647d6aba95_1130x71.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="part := a + b joined := part + c" title="part := a + b joined := part + c" srcset="https://substackcdn.com/image/fetch/$s_!cmnO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F702658f7-4250-433b-a627-b5647d6aba95_1130x71.png 424w, https://substackcdn.com/image/fetch/$s_!cmnO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F702658f7-4250-433b-a627-b5647d6aba95_1130x71.png 848w, https://substackcdn.com/image/fetch/$s_!cmnO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F702658f7-4250-433b-a627-b5647d6aba95_1130x71.png 1272w, https://substackcdn.com/image/fetch/$s_!cmnO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F702658f7-4250-433b-a627-b5647d6aba95_1130x71.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>That version allocates twice, once for <code>part</code> and again for <code>joined</code>. So compiler help is limited by how the code is written.</p><h4>Garbage Collection Impact</h4><p>Each intermediate string created during concatenation has to live in memory until it&#8217;s no longer referenced. The garbage collector eventually reclaims those blocks, but while they exist they add to allocation pressure and collector work.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dcrY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bb4f0ee-a265-4328-bf7b-f82b5b52bff5_981x628.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dcrY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bb4f0ee-a265-4328-bf7b-f82b5b52bff5_981x628.png 424w, https://substackcdn.com/image/fetch/$s_!dcrY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bb4f0ee-a265-4328-bf7b-f82b5b52bff5_981x628.png 848w, https://substackcdn.com/image/fetch/$s_!dcrY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bb4f0ee-a265-4328-bf7b-f82b5b52bff5_981x628.png 1272w, https://substackcdn.com/image/fetch/$s_!dcrY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bb4f0ee-a265-4328-bf7b-f82b5b52bff5_981x628.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dcrY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bb4f0ee-a265-4328-bf7b-f82b5b52bff5_981x628.png" width="703" height="450.03465851172274" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3bb4f0ee-a265-4328-bf7b-f82b5b52bff5_981x628.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:628,&quot;width&quot;:981,&quot;resizeWidth&quot;:703,&quot;bytes&quot;:64336,&quot;alt&quot;:&quot;package main  import (     \&quot;fmt\&quot;     \&quot;runtime\&quot; )  func main() {     var s string     for i := 0; i < 5000; i++ {         s += \&quot;x\&quot;     }      var m runtime.MemStats     runtime.ReadMemStats(&amp;m)     fmt.Println(\&quot;HeapAlloc:\&quot;, m.HeapAlloc)     fmt.Println(\&quot;NumGC:\&quot;, m.NumGC) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179191053?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bb4f0ee-a265-4328-bf7b-f82b5b52bff5_981x628.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (     &quot;fmt&quot;     &quot;runtime&quot; )  func main() {     var s string     for i := 0; i < 5000; i++ {         s += &quot;x&quot;     }      var m runtime.MemStats     runtime.ReadMemStats(&amp;m)     fmt.Println(&quot;HeapAlloc:&quot;, m.HeapAlloc)     fmt.Println(&quot;NumGC:&quot;, m.NumGC) }" title="package main  import (     &quot;fmt&quot;     &quot;runtime&quot; )  func main() {     var s string     for i := 0; i < 5000; i++ {         s += &quot;x&quot;     }      var m runtime.MemStats     runtime.ReadMemStats(&amp;m)     fmt.Println(&quot;HeapAlloc:&quot;, m.HeapAlloc)     fmt.Println(&quot;NumGC:&quot;, m.NumGC) }" srcset="https://substackcdn.com/image/fetch/$s_!dcrY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bb4f0ee-a265-4328-bf7b-f82b5b52bff5_981x628.png 424w, https://substackcdn.com/image/fetch/$s_!dcrY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bb4f0ee-a265-4328-bf7b-f82b5b52bff5_981x628.png 848w, https://substackcdn.com/image/fetch/$s_!dcrY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bb4f0ee-a265-4328-bf7b-f82b5b52bff5_981x628.png 1272w, https://substackcdn.com/image/fetch/$s_!dcrY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3bb4f0ee-a265-4328-bf7b-f82b5b52bff5_981x628.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Running this example with different loop counts shows how heap use grows and how the number of garbage collections increases with it. Every intermediate string is a short-lived object that must be collected.</p><p>With builders, far fewer temporary objects are created, which reduces collector load and keeps allocation churn low. That doesn&#8217;t remove the work entirely, but it makes the collector&#8217;s job easier by limiting the number of short-lived strings that otherwise flood memory.</p><h3>Conclusion</h3><p>String concatenation in Go runs on simple code but carries deeper costs in the background. Each join creates a new allocation, the compiler sometimes folds operations into fewer steps, and repeated concatenation pushes more work onto both the allocator and the garbage collector. Builders give a more efficient path when text grows repeatedly, while compiler optimizations handle fixed expressions. With these mechanics in mind, it becomes easier to see why performance can vary so much depending on how text is combined.</p><ol><li><p><em><a href="https://pkg.go.dev/builtin#string">Go Strings Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/strings">Go Strings Package</a></em></p></li><li><p><em><a href="https://cs.opensource.google/go/go/+/refs/tags/go1.23.0:src/runtime/string.go;l=51">runtime.concatstrings Source</a></em></p></li><li><p><em><a href="https://pkg.go.dev/runtime#MemStats">runtime.MemStats</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Scheduler Queues in Go Runtime]]></title><description><![CDATA[Goroutines sit at the center of Go&#8217;s concurrency story, but the piece that decides how they actually run is the runtime scheduler.]]></description><link>https://alexanderobregon.substack.com/p/scheduler-queues-in-go-runtime</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/scheduler-queues-in-go-runtime</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Wed, 19 Nov 2025 18:12:19 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ece65820-da0c-47d9-adf4-52f33c09196e_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_zD2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdbbf5e-3949-497d-9d2c-1be17bf0caf9_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_zD2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdbbf5e-3949-497d-9d2c-1be17bf0caf9_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!_zD2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdbbf5e-3949-497d-9d2c-1be17bf0caf9_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!_zD2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdbbf5e-3949-497d-9d2c-1be17bf0caf9_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!_zD2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdbbf5e-3949-497d-9d2c-1be17bf0caf9_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_zD2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdbbf5e-3949-497d-9d2c-1be17bf0caf9_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3cdbbf5e-3949-497d-9d2c-1be17bf0caf9_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_zD2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdbbf5e-3949-497d-9d2c-1be17bf0caf9_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!_zD2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdbbf5e-3949-497d-9d2c-1be17bf0caf9_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!_zD2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdbbf5e-3949-497d-9d2c-1be17bf0caf9_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!_zD2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cdbbf5e-3949-497d-9d2c-1be17bf0caf9_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>Goroutines sit at the center of Go&#8217;s concurrency story, but the piece that decides how they actually run is the runtime scheduler. That scheduler relies on both global and local queues to keep work moving across threads and processors. Runnable goroutines wait in these queues until they&#8217;re picked up, and the way they&#8217;re managed is what lets Go scale from a single core to many cores without developers having to manage threads themselves.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>How Scheduler Queues Are Organized</h3><p>The Go scheduler doesn&#8217;t run goroutines randomly. It uses a system of queues that hold runnable goroutines until a processor is ready to execute them. These queues are carefully arranged to balance speed and fairness across cores. At a high level there are two types, global and local, and they work together to make sure goroutines get CPU time without constant bottlenecks.</p><h4>Global Queue</h4><p>The global queue is shared across the entire runtime. It&#8217;s the place where goroutines go when they can&#8217;t be placed into a processor&#8217;s local queue, or when the runtime decides to even out the distribution of work. Having this shared space makes it possible for idle processors to grab runnable goroutines instead of sitting without work.</p><p>A very simple way to imagine this is as a waiting room that every processor can visit. When a <code>P</code> runs out of local work it first checks the <code>global</code> queue to pull runnable goroutines. New goroutines are pushed to <code>global</code> mainly when a local run queue overflows or during specific handoffs. Without this structure, some processors would starve for work while others would sit overloaded.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LGTk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1b9ae5-263b-49b8-98f5-c2521f493c90_1101x629.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LGTk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1b9ae5-263b-49b8-98f5-c2521f493c90_1101x629.png 424w, https://substackcdn.com/image/fetch/$s_!LGTk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1b9ae5-263b-49b8-98f5-c2521f493c90_1101x629.png 848w, https://substackcdn.com/image/fetch/$s_!LGTk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1b9ae5-263b-49b8-98f5-c2521f493c90_1101x629.png 1272w, https://substackcdn.com/image/fetch/$s_!LGTk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1b9ae5-263b-49b8-98f5-c2521f493c90_1101x629.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LGTk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1b9ae5-263b-49b8-98f5-c2521f493c90_1101x629.png" width="1101" height="629" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bf1b9ae5-263b-49b8-98f5-c2521f493c90_1101x629.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:629,&quot;width&quot;:1101,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:72512,&quot;alt&quot;:&quot;package main  import (  \&quot;fmt\&quot;  \&quot;time\&quot; )  func task(name string) {  fmt.Println(\&quot;running:\&quot;, name)  time.Sleep(50 * time.Millisecond) }  func main() {  for i := 0; i < 100; i++ {   go task(fmt.Sprintf(\&quot;job-%d\&quot;, i))  }  time.Sleep(time.Second) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179189964?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1b9ae5-263b-49b8-98f5-c2521f493c90_1101x629.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (  &quot;fmt&quot;  &quot;time&quot; )  func task(name string) {  fmt.Println(&quot;running:&quot;, name)  time.Sleep(50 * time.Millisecond) }  func main() {  for i := 0; i < 100; i++ {   go task(fmt.Sprintf(&quot;job-%d&quot;, i))  }  time.Sleep(time.Second) }" title="package main  import (  &quot;fmt&quot;  &quot;time&quot; )  func task(name string) {  fmt.Println(&quot;running:&quot;, name)  time.Sleep(50 * time.Millisecond) }  func main() {  for i := 0; i < 100; i++ {   go task(fmt.Sprintf(&quot;job-%d&quot;, i))  }  time.Sleep(time.Second) }" srcset="https://substackcdn.com/image/fetch/$s_!LGTk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1b9ae5-263b-49b8-98f5-c2521f493c90_1101x629.png 424w, https://substackcdn.com/image/fetch/$s_!LGTk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1b9ae5-263b-49b8-98f5-c2521f493c90_1101x629.png 848w, https://substackcdn.com/image/fetch/$s_!LGTk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1b9ae5-263b-49b8-98f5-c2521f493c90_1101x629.png 1272w, https://substackcdn.com/image/fetch/$s_!LGTk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1b9ae5-263b-49b8-98f5-c2521f493c90_1101x629.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Launching a burst of goroutines like this tends to fill the local queue first, but many of them spill into the global queue. That global pool makes sure that no processor misses out on runnable work.</p><p>Processors don&#8217;t consult the <code>global</code> queue on every pick and instead they check it periodically, which keeps lock contention down. If processors were constantly fighting over the global queue, performance would suffer. Instead, the runtime balances between pulling from the global pool and focusing on local queues.</p><h4>Local Queues</h4><p>Each processor (P) maintains its own local queue, and this is where most goroutines spend their time before being scheduled. Local queues reduce contention because only the processor that owns the queue interacts with it most of the time. This means far fewer lock operations compared to having every goroutine pushed into a single global structure. When a goroutine is created, the runtime usually places it directly into the local queue of the processor running the creation code. This behavior keeps goroutines close to the thread that spawned them, which helps cache locality and reduces overhead.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!isnu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93c3f0df-46a3-48a3-b985-ef1651458312_1104x663.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!isnu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93c3f0df-46a3-48a3-b985-ef1651458312_1104x663.png 424w, https://substackcdn.com/image/fetch/$s_!isnu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93c3f0df-46a3-48a3-b985-ef1651458312_1104x663.png 848w, https://substackcdn.com/image/fetch/$s_!isnu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93c3f0df-46a3-48a3-b985-ef1651458312_1104x663.png 1272w, https://substackcdn.com/image/fetch/$s_!isnu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93c3f0df-46a3-48a3-b985-ef1651458312_1104x663.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!isnu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93c3f0df-46a3-48a3-b985-ef1651458312_1104x663.png" width="1104" height="663" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/93c3f0df-46a3-48a3-b985-ef1651458312_1104x663.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:663,&quot;width&quot;:1104,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:75437,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179189964?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93c3f0df-46a3-48a3-b985-ef1651458312_1104x663.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!isnu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93c3f0df-46a3-48a3-b985-ef1651458312_1104x663.png 424w, https://substackcdn.com/image/fetch/$s_!isnu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93c3f0df-46a3-48a3-b985-ef1651458312_1104x663.png 848w, https://substackcdn.com/image/fetch/$s_!isnu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93c3f0df-46a3-48a3-b985-ef1651458312_1104x663.png 1272w, https://substackcdn.com/image/fetch/$s_!isnu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93c3f0df-46a3-48a3-b985-ef1651458312_1104x663.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This code doesn&#8217;t create enough goroutines to stress the global queue, so most of them stay inside the local queue of the processor handling <code>main</code>. You can think of this as a fast track compared to the global pool.</p><p>There&#8217;s also an interesting detail in how local queues are managed, each queue is implemented as a fixed-size circular buffer. If it overflows, the overflowed goroutines are moved to the global queue, preventing the local buffer from expanding endlessly. This keeps memory use stable while still leaving the global queue as a backup.</p><p>A larger run can trigger both behaviors at once.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OFE-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e8af9a-0baf-4347-8e40-c8575be09448_1040x661.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OFE-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e8af9a-0baf-4347-8e40-c8575be09448_1040x661.png 424w, https://substackcdn.com/image/fetch/$s_!OFE-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e8af9a-0baf-4347-8e40-c8575be09448_1040x661.png 848w, https://substackcdn.com/image/fetch/$s_!OFE-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e8af9a-0baf-4347-8e40-c8575be09448_1040x661.png 1272w, https://substackcdn.com/image/fetch/$s_!OFE-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e8af9a-0baf-4347-8e40-c8575be09448_1040x661.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OFE-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e8af9a-0baf-4347-8e40-c8575be09448_1040x661.png" width="1040" height="661" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e8e8af9a-0baf-4347-8e40-c8575be09448_1040x661.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:661,&quot;width&quot;:1040,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:78269,&quot;alt&quot;:&quot;package main  import (  \&quot;fmt\&quot;  \&quot;time\&quot; )  func heavy(id int) {  fmt.Printf(\&quot;heavy %d start\\n\&quot;, id)  time.Sleep(200 * time.Millisecond)  fmt.Printf(\&quot;heavy %d done\\n\&quot;, id) }  func main() {  for i := 0; i < 200; i++ {   go heavy(i)  }  time.Sleep(3 * time.Second) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179189964?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e8af9a-0baf-4347-8e40-c8575be09448_1040x661.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (  &quot;fmt&quot;  &quot;time&quot; )  func heavy(id int) {  fmt.Printf(&quot;heavy %d start\n&quot;, id)  time.Sleep(200 * time.Millisecond)  fmt.Printf(&quot;heavy %d done\n&quot;, id) }  func main() {  for i := 0; i < 200; i++ {   go heavy(i)  }  time.Sleep(3 * time.Second) }" title="package main  import (  &quot;fmt&quot;  &quot;time&quot; )  func heavy(id int) {  fmt.Printf(&quot;heavy %d start\n&quot;, id)  time.Sleep(200 * time.Millisecond)  fmt.Printf(&quot;heavy %d done\n&quot;, id) }  func main() {  for i := 0; i < 200; i++ {   go heavy(i)  }  time.Sleep(3 * time.Second) }" srcset="https://substackcdn.com/image/fetch/$s_!OFE-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e8af9a-0baf-4347-8e40-c8575be09448_1040x661.png 424w, https://substackcdn.com/image/fetch/$s_!OFE-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e8af9a-0baf-4347-8e40-c8575be09448_1040x661.png 848w, https://substackcdn.com/image/fetch/$s_!OFE-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e8af9a-0baf-4347-8e40-c8575be09448_1040x661.png 1272w, https://substackcdn.com/image/fetch/$s_!OFE-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e8af9a-0baf-4347-8e40-c8575be09448_1040x661.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Here, hundreds of goroutines quickly overflow local queues, so many end up in the global queue. Processors then balance their local work with periodic checks of the shared pool, which keeps execution flowing across all cores.</p><h3>How Goroutines Move Through Queues</h3><p>Goroutines rarely stay in one place from the time they&#8217;re created until the time they finish. The scheduler constantly makes decisions about where to put them, which queue to use, and how to make sure they&#8217;re fairly distributed across processors. That flow depends on how they&#8217;re created, what they&#8217;re waiting on, and how they get woken back up.</p><h4>Goroutine Creation</h4><p>When a new goroutine is created with the <code>go</code> keyword, the runtime has to decide where to place it. Most of the time it goes straight into the local queue of the processor that made it. This keeps goroutines close to the thread that spawned them, reducing overhead. If the local queue is already full, some of the new goroutines spill into the global queue so other processors can pick them up.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8cJa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc58ee3f2-03e3-497e-9c31-9951d03a52c9_1105x664.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8cJa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc58ee3f2-03e3-497e-9c31-9951d03a52c9_1105x664.png 424w, https://substackcdn.com/image/fetch/$s_!8cJa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc58ee3f2-03e3-497e-9c31-9951d03a52c9_1105x664.png 848w, https://substackcdn.com/image/fetch/$s_!8cJa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc58ee3f2-03e3-497e-9c31-9951d03a52c9_1105x664.png 1272w, https://substackcdn.com/image/fetch/$s_!8cJa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc58ee3f2-03e3-497e-9c31-9951d03a52c9_1105x664.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8cJa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc58ee3f2-03e3-497e-9c31-9951d03a52c9_1105x664.png" width="1105" height="664" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c58ee3f2-03e3-497e-9c31-9951d03a52c9_1105x664.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:664,&quot;width&quot;:1105,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:75813,&quot;alt&quot;:&quot;package main  import (  \&quot;fmt\&quot;  \&quot;time\&quot; )  func worker(n int) {  fmt.Println(\&quot;worker\&quot;, n, \&quot;started\&quot;)  time.Sleep(100 * time.Millisecond)  fmt.Println(\&quot;worker\&quot;, n, \&quot;finished\&quot;) }  func main() {  for i := 0; i < 20; i++ {   go worker(i)  }  time.Sleep(2 * time.Second) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179189964?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc58ee3f2-03e3-497e-9c31-9951d03a52c9_1105x664.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (  &quot;fmt&quot;  &quot;time&quot; )  func worker(n int) {  fmt.Println(&quot;worker&quot;, n, &quot;started&quot;)  time.Sleep(100 * time.Millisecond)  fmt.Println(&quot;worker&quot;, n, &quot;finished&quot;) }  func main() {  for i := 0; i < 20; i++ {   go worker(i)  }  time.Sleep(2 * time.Second) }" title="package main  import (  &quot;fmt&quot;  &quot;time&quot; )  func worker(n int) {  fmt.Println(&quot;worker&quot;, n, &quot;started&quot;)  time.Sleep(100 * time.Millisecond)  fmt.Println(&quot;worker&quot;, n, &quot;finished&quot;) }  func main() {  for i := 0; i < 20; i++ {   go worker(i)  }  time.Sleep(2 * time.Second) }" srcset="https://substackcdn.com/image/fetch/$s_!8cJa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc58ee3f2-03e3-497e-9c31-9951d03a52c9_1105x664.png 424w, https://substackcdn.com/image/fetch/$s_!8cJa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc58ee3f2-03e3-497e-9c31-9951d03a52c9_1105x664.png 848w, https://substackcdn.com/image/fetch/$s_!8cJa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc58ee3f2-03e3-497e-9c31-9951d03a52c9_1105x664.png 1272w, https://substackcdn.com/image/fetch/$s_!8cJa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc58ee3f2-03e3-497e-9c31-9951d03a52c9_1105x664.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>A loop like this floods the scheduler with goroutines quickly.</p><p>A second way goroutines enter queues is through chained spawns. One goroutine can create another, and the runtime applies the same logic, keeping new goroutines local whenever possible and falling back to the global queue when space runs out.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4ZN1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1417f64b-de11-4baf-96f4-875f74f8390f_1103x701.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4ZN1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1417f64b-de11-4baf-96f4-875f74f8390f_1103x701.png 424w, https://substackcdn.com/image/fetch/$s_!4ZN1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1417f64b-de11-4baf-96f4-875f74f8390f_1103x701.png 848w, https://substackcdn.com/image/fetch/$s_!4ZN1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1417f64b-de11-4baf-96f4-875f74f8390f_1103x701.png 1272w, https://substackcdn.com/image/fetch/$s_!4ZN1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1417f64b-de11-4baf-96f4-875f74f8390f_1103x701.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4ZN1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1417f64b-de11-4baf-96f4-875f74f8390f_1103x701.png" width="1103" height="701" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1417f64b-de11-4baf-96f4-875f74f8390f_1103x701.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:701,&quot;width&quot;:1103,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:72016,&quot;alt&quot;:&quot;package main  import (  \&quot;fmt\&quot;  \&quot;time\&quot; )  func chain(level int) {  if level > 3 {   return  }  fmt.Println(\&quot;chain level\&quot;, level)  go chain(level + 1)  time.Sleep(50 * time.Millisecond) }  func main() {  go chain(1)  time.Sleep(500 * time.Millisecond) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179189964?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1417f64b-de11-4baf-96f4-875f74f8390f_1103x701.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (  &quot;fmt&quot;  &quot;time&quot; )  func chain(level int) {  if level > 3 {   return  }  fmt.Println(&quot;chain level&quot;, level)  go chain(level + 1)  time.Sleep(50 * time.Millisecond) }  func main() {  go chain(1)  time.Sleep(500 * time.Millisecond) }" title="package main  import (  &quot;fmt&quot;  &quot;time&quot; )  func chain(level int) {  if level > 3 {   return  }  fmt.Println(&quot;chain level&quot;, level)  go chain(level + 1)  time.Sleep(50 * time.Millisecond) }  func main() {  go chain(1)  time.Sleep(500 * time.Millisecond) }" srcset="https://substackcdn.com/image/fetch/$s_!4ZN1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1417f64b-de11-4baf-96f4-875f74f8390f_1103x701.png 424w, https://substackcdn.com/image/fetch/$s_!4ZN1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1417f64b-de11-4baf-96f4-875f74f8390f_1103x701.png 848w, https://substackcdn.com/image/fetch/$s_!4ZN1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1417f64b-de11-4baf-96f4-875f74f8390f_1103x701.png 1272w, https://substackcdn.com/image/fetch/$s_!4ZN1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1417f64b-de11-4baf-96f4-875f74f8390f_1103x701.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This nested spawning keeps work tied to the processor where the chain began, but the overflow path still helps keep fairness across processors.</p><h4>Work Stealing</h4><p>Local queues are fast, but they can run dry. When that happens, the processor doesn&#8217;t just sit idle. It first checks the global queue to see if there&#8217;s any work waiting there. If the global queue is empty, it tries to steal work from another processor&#8217;s local queue. The runtime picks another processor and, if it has goroutines in its queue, about half of them are transferred over. That keeps the system balanced. Without this mechanism, some processors would stall while others stay busy.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!i09O!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fdc840-9f81-4c07-85a5-d12a419be519_1045x802.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!i09O!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fdc840-9f81-4c07-85a5-d12a419be519_1045x802.png 424w, https://substackcdn.com/image/fetch/$s_!i09O!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fdc840-9f81-4c07-85a5-d12a419be519_1045x802.png 848w, https://substackcdn.com/image/fetch/$s_!i09O!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fdc840-9f81-4c07-85a5-d12a419be519_1045x802.png 1272w, https://substackcdn.com/image/fetch/$s_!i09O!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fdc840-9f81-4c07-85a5-d12a419be519_1045x802.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!i09O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fdc840-9f81-4c07-85a5-d12a419be519_1045x802.png" width="1045" height="802" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/40fdc840-9f81-4c07-85a5-d12a419be519_1045x802.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:802,&quot;width&quot;:1045,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:92535,&quot;alt&quot;:&quot;package main  import (  \&quot;fmt\&quot;  \&quot;runtime\&quot;  \&quot;time\&quot; )  func heavyJob(id int) {  start := time.Now()  for time.Since(start) < 200*time.Millisecond {   _ = id * id  }  fmt.Println(\&quot;finished heavy job\&quot;, id) }  func main() {  runtime.GOMAXPROCS(4)  for i := 0; i < 100; i++ {   go heavyJob(i)  }  time.Sleep(2 * time.Second) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179189964?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fdc840-9f81-4c07-85a5-d12a419be519_1045x802.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (  &quot;fmt&quot;  &quot;runtime&quot;  &quot;time&quot; )  func heavyJob(id int) {  start := time.Now()  for time.Since(start) < 200*time.Millisecond {   _ = id * id  }  fmt.Println(&quot;finished heavy job&quot;, id) }  func main() {  runtime.GOMAXPROCS(4)  for i := 0; i < 100; i++ {   go heavyJob(i)  }  time.Sleep(2 * time.Second) }" title="package main  import (  &quot;fmt&quot;  &quot;runtime&quot;  &quot;time&quot; )  func heavyJob(id int) {  start := time.Now()  for time.Since(start) < 200*time.Millisecond {   _ = id * id  }  fmt.Println(&quot;finished heavy job&quot;, id) }  func main() {  runtime.GOMAXPROCS(4)  for i := 0; i < 100; i++ {   go heavyJob(i)  }  time.Sleep(2 * time.Second) }" srcset="https://substackcdn.com/image/fetch/$s_!i09O!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fdc840-9f81-4c07-85a5-d12a419be519_1045x802.png 424w, https://substackcdn.com/image/fetch/$s_!i09O!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fdc840-9f81-4c07-85a5-d12a419be519_1045x802.png 848w, https://substackcdn.com/image/fetch/$s_!i09O!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fdc840-9f81-4c07-85a5-d12a419be519_1045x802.png 1272w, https://substackcdn.com/image/fetch/$s_!i09O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40fdc840-9f81-4c07-85a5-d12a419be519_1045x802.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Running this with multiple processors often triggers work stealing. Local queues empty and refill as goroutines get borrowed across processors, keeping all cores active.</p><h4>Goroutines Blocked in System Calls</h4><p>Not all goroutines spend their life in pure user code. Many block on system calls, like file reads or network operations. When that happens, the thread handling the goroutine can&#8217;t continue scheduling. To avoid wasting a processor, the runtime detaches the processor from that thread and hands it to another thread so scheduling continues. When the system call finishes, the goroutine that was blocked is placed back into a queue to run again.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oA2v!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9e0395-6022-4dfe-a8e7-c347da2bd6b9_848x783.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oA2v!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9e0395-6022-4dfe-a8e7-c347da2bd6b9_848x783.png 424w, https://substackcdn.com/image/fetch/$s_!oA2v!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9e0395-6022-4dfe-a8e7-c347da2bd6b9_848x783.png 848w, https://substackcdn.com/image/fetch/$s_!oA2v!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9e0395-6022-4dfe-a8e7-c347da2bd6b9_848x783.png 1272w, https://substackcdn.com/image/fetch/$s_!oA2v!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9e0395-6022-4dfe-a8e7-c347da2bd6b9_848x783.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oA2v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9e0395-6022-4dfe-a8e7-c347da2bd6b9_848x783.png" width="848" height="783" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ff9e0395-6022-4dfe-a8e7-c347da2bd6b9_848x783.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:783,&quot;width&quot;:848,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:74888,&quot;alt&quot;:&quot;package main  import (  \&quot;fmt\&quot;  \&quot;net/http\&quot;  \&quot;time\&quot; )  func fetch(url string) {  _, err := http.Get(url)  if err != nil {   fmt.Println(\&quot;error fetching\&quot;, url, err)   return  }  fmt.Println(\&quot;done fetching\&quot;, url) }  func main() {  urls := []string{   \&quot;https://golang.org\&quot;,   \&quot;https://pkg.go.dev\&quot;,   \&quot;https://go.dev\&quot;,  }  for _, u := range urls {   go fetch(u)  }  time.Sleep(2 * time.Second) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179189964?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9e0395-6022-4dfe-a8e7-c347da2bd6b9_848x783.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (  &quot;fmt&quot;  &quot;net/http&quot;  &quot;time&quot; )  func fetch(url string) {  _, err := http.Get(url)  if err != nil {   fmt.Println(&quot;error fetching&quot;, url, err)   return  }  fmt.Println(&quot;done fetching&quot;, url) }  func main() {  urls := []string{   &quot;https://golang.org&quot;,   &quot;https://pkg.go.dev&quot;,   &quot;https://go.dev&quot;,  }  for _, u := range urls {   go fetch(u)  }  time.Sleep(2 * time.Second) }" title="package main  import (  &quot;fmt&quot;  &quot;net/http&quot;  &quot;time&quot; )  func fetch(url string) {  _, err := http.Get(url)  if err != nil {   fmt.Println(&quot;error fetching&quot;, url, err)   return  }  fmt.Println(&quot;done fetching&quot;, url) }  func main() {  urls := []string{   &quot;https://golang.org&quot;,   &quot;https://pkg.go.dev&quot;,   &quot;https://go.dev&quot;,  }  for _, u := range urls {   go fetch(u)  }  time.Sleep(2 * time.Second) }" srcset="https://substackcdn.com/image/fetch/$s_!oA2v!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9e0395-6022-4dfe-a8e7-c347da2bd6b9_848x783.png 424w, https://substackcdn.com/image/fetch/$s_!oA2v!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9e0395-6022-4dfe-a8e7-c347da2bd6b9_848x783.png 848w, https://substackcdn.com/image/fetch/$s_!oA2v!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9e0395-6022-4dfe-a8e7-c347da2bd6b9_848x783.png 1272w, https://substackcdn.com/image/fetch/$s_!oA2v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fff9e0395-6022-4dfe-a8e7-c347da2bd6b9_848x783.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Each goroutine calling <code>http.Get</code> blocks on a system call to the operating system. During that time the processor that started them doesn&#8217;t stall, because it&#8217;s moved over to another thread that can continue scheduling other goroutines.</p><p>This separation between blocking system calls and active scheduling is what lets Go scale in server environments where blocking I/O happens all the time.</p><h4>Wakeups and Timeouts</h4><p>Many goroutines aren&#8217;t blocked forever. They wait on timers, channels, or synchronization events, and when those conditions are met they&#8217;re woken up. At that moment, the runtime places them back into a queue so they can run again. Sometimes they go back to the local queue where they originated, and other times they&#8217;re pushed into the global queue depending on capacity and load balancing.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!58om!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b02e63-8420-4da1-a404-ed2d0edbce30_1104x630.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!58om!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b02e63-8420-4da1-a404-ed2d0edbce30_1104x630.png 424w, https://substackcdn.com/image/fetch/$s_!58om!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b02e63-8420-4da1-a404-ed2d0edbce30_1104x630.png 848w, https://substackcdn.com/image/fetch/$s_!58om!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b02e63-8420-4da1-a404-ed2d0edbce30_1104x630.png 1272w, https://substackcdn.com/image/fetch/$s_!58om!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b02e63-8420-4da1-a404-ed2d0edbce30_1104x630.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!58om!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b02e63-8420-4da1-a404-ed2d0edbce30_1104x630.png" width="1104" height="630" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b3b02e63-8420-4da1-a404-ed2d0edbce30_1104x630.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:630,&quot;width&quot;:1104,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:93485,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179189964?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b02e63-8420-4da1-a404-ed2d0edbce30_1104x630.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!58om!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b02e63-8420-4da1-a404-ed2d0edbce30_1104x630.png 424w, https://substackcdn.com/image/fetch/$s_!58om!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b02e63-8420-4da1-a404-ed2d0edbce30_1104x630.png 848w, https://substackcdn.com/image/fetch/$s_!58om!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b02e63-8420-4da1-a404-ed2d0edbce30_1104x630.png 1272w, https://substackcdn.com/image/fetch/$s_!58om!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3b02e63-8420-4da1-a404-ed2d0edbce30_1104x630.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Each goroutine here waits on a timer before waking up. When the timer fires, the goroutine is placed back into a runnable queue to finish its work.</p><p>Wakeups can also come from channel operations. A goroutine waiting to receive will block until another goroutine sends. When the send happens, the waiting goroutine is reactivated and added back into a queue.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2u_6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faabf9900-2e59-4c08-8f8f-ad76ceb591a7_989x661.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2u_6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faabf9900-2e59-4c08-8f8f-ad76ceb591a7_989x661.png 424w, https://substackcdn.com/image/fetch/$s_!2u_6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faabf9900-2e59-4c08-8f8f-ad76ceb591a7_989x661.png 848w, https://substackcdn.com/image/fetch/$s_!2u_6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faabf9900-2e59-4c08-8f8f-ad76ceb591a7_989x661.png 1272w, https://substackcdn.com/image/fetch/$s_!2u_6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faabf9900-2e59-4c08-8f8f-ad76ceb591a7_989x661.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2u_6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faabf9900-2e59-4c08-8f8f-ad76ceb591a7_989x661.png" width="989" height="661" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aabf9900-2e59-4c08-8f8f-ad76ceb591a7_989x661.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:661,&quot;width&quot;:989,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:74198,&quot;alt&quot;:&quot;package main  import (  \&quot;fmt\&quot;  \&quot;time\&quot; )  func receiver(ch <-chan int) {  v := <-ch  fmt.Println(\&quot;received\&quot;, v) }  func main() {  ch := make(chan int)  go receiver(ch)  time.Sleep(100 * time.Millisecond)  ch <- 99  time.Sleep(200 * time.Millisecond) }&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/179189964?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faabf9900-2e59-4c08-8f8f-ad76ceb591a7_989x661.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="package main  import (  &quot;fmt&quot;  &quot;time&quot; )  func receiver(ch <-chan int) {  v := <-ch  fmt.Println(&quot;received&quot;, v) }  func main() {  ch := make(chan int)  go receiver(ch)  time.Sleep(100 * time.Millisecond)  ch <- 99  time.Sleep(200 * time.Millisecond) }" title="package main  import (  &quot;fmt&quot;  &quot;time&quot; )  func receiver(ch <-chan int) {  v := <-ch  fmt.Println(&quot;received&quot;, v) }  func main() {  ch := make(chan int)  go receiver(ch)  time.Sleep(100 * time.Millisecond)  ch <- 99  time.Sleep(200 * time.Millisecond) }" srcset="https://substackcdn.com/image/fetch/$s_!2u_6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faabf9900-2e59-4c08-8f8f-ad76ceb591a7_989x661.png 424w, https://substackcdn.com/image/fetch/$s_!2u_6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faabf9900-2e59-4c08-8f8f-ad76ceb591a7_989x661.png 848w, https://substackcdn.com/image/fetch/$s_!2u_6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faabf9900-2e59-4c08-8f8f-ad76ceb591a7_989x661.png 1272w, https://substackcdn.com/image/fetch/$s_!2u_6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faabf9900-2e59-4c08-8f8f-ad76ceb591a7_989x661.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The blocked receiver is dormant until the channel gets a value. At that point the runtime wakes it and returns it to a queue, letting it continue execution.</p><h3>Conclusion</h3><p>Scheduler queues are the machinery that keep goroutines moving through the runtime without interruption. Local queues give processors fast access to work, the global queue acts as a shared pool when balance is needed, and the handoffs between them keep execution smooth across many cores. Creation, blocking, wakeups, and stealing all rely on these queues, and together they explain how Go keeps thousands of goroutines active without direct thread management from the developer.</p><ol><li><p><em><a href="https://golang.org/s/go11sched">Go Scheduler Design Document</a></em></p></li><li><p><em><a href="https://pkg.go.dev/runtime">runtime Package Docs</a></em></p></li><li><p><em><a href="https://golang.org/ref/mem">Go Memory Model</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Browse My Go Articles by Topic]]></title><description><![CDATA[A collection of all my Go articles covering everyday coding habits, concurrency, and runtime details, organized by topic for easier reading.]]></description><link>https://alexanderobregon.substack.com/p/browse-my-go-articles-by-topic</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/browse-my-go-articles-by-topic</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Thu, 06 Nov 2025 00:37:51 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/744a1ea3-49a8-47c5-a5a6-06e6aa95a08b_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I&#8217;ve published over 100 Go articles so far that range from everyday coding habits to deep runtime details. This page pulls them into one place so you can browse by topic instead of scrolling the full archive. Each section groups related articles so it&#8217;s easier to follow how Go behaves across its language features, concurrency model, and runtime internals.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>Go Fundamentals</h3><p>These articles build a foundation for Go&#8217;s behavior and structure.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;c2a3dbfd-b739-4691-bf26-a1ec36b48ae1&quot;,&quot;caption&quot;:&quot;A lot of people choose Go because it already comes with the building blocks you reach for during algorithm work. You see that in heaps for priority queues, generic helpers for slices and maps, and concurrency tools that make coordination part of the language. Today we are going to walk through some algorithm families that fit Go particularly&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Algorithms That Work Well with Go's Mechanics&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-02-20T19:04:46.121Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/65f2a1bc-28cc-46ba-851f-a61c0130c876_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/algorithms-that-work-well-with-gos&quot;,&quot;section_name&quot;:&quot;Golang&quot;,&quot;video_upload_id&quot;:null,&quot;id&quot;:188446457,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;c9c74358-44bb-4970-a34c-4c04f4917a01&quot;,&quot;caption&quot;:&quot;Go handles errors in its own way. Instead of throwing exceptions or relying on try-catch, it treats errors as values that you pass around and check yourself. That means you&#8217;re expected to stop and handle the problem right where it happens. You can tell what could go wrong just by looking at the return types, and the language doesn&#8217;t hide tha&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Returning Errors the Go Way&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-07-26T00:45:22.275Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/39f1940b-1849-4efd-aede-562988aa67bd_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/returning-errors-the-go-way&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:169273782,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;258fa029-d795-4db4-b1eb-9daf91ba215b&quot;,&quot;caption&quot;:&quot;Testing comes with the language, and you don&#8217;t have to bring in anything extra to get real tests working. The testing package lets you check your logic, compare results, and keep things from breaking as the code changes. You can write unit tests that track how things behave, run through different inputs, and see exactly what passed or failed&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Writing Tests in Go Without Extra Tools&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-07-29T23:43:16.741Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eb63b074-09cc-4b30-a018-d1f6f246933a_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/writing-tests-in-go-without-extra&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:169617163,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;9940acdb-31a7-4b8b-8c0b-713eff2f554f&quot;,&quot;caption&quot;:&quot;Performance testing in Go has a dedicated place in the language through its built-in benchmarking tools. These tools are designed to measure how long certain operations take and how much memory they use, all from inside the same testing framework used for unit tests. Instead of manually writing timers and logging results, developers can writ&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Go Testing Benchmarks and How They Are Measured&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-08-10T04:26:17.467Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a146b05e-6048-4164-a433-24e55c9ebe34_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/go-testing-benchmarks-and-how-they&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:170577100,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;e598a9b3-4635-4fa0-b90e-8ae9c4e5f5d3&quot;,&quot;caption&quot;:&quot;Go doesn&#8217;t jump straight into main first thing. Before that function is touched, the runtime goes through every imported package, sets up their variables, and runs any init functions they define. The order comes from the import dependency graph, not the textual order of import statements. Seeing how this process works makes it clear why cert&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Package Initialization and Import Order in Go&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-08-23T19:23:44.149Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a5ffb97f-c440-4174-93ba-890a40633b9b_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/package-initialization-and-import&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:171520979,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;ad1440a4-c3cc-481f-b0d5-31d83de8d88a&quot;,&quot;caption&quot;:&quot;Every range loop runs with behavior tied to the type you&#8217;re looping through. Arrays, slices, maps, and channels all support range, but what they hand back at each step isn&#8217;t the same. How those values are created, copied, or passed around affects what your code actually works with. You could change a value and nothing happens. You could appe&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;What Go Ranges Actually Return Inside Loops&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-08-07T22:57:09.175Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7775a247-b719-49e4-a0e4-d280135c1546_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/what-go-ranges-actually-return-inside&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:170403843,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:2,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p><strong>Medium articles:</strong></p><ul><li><p><a href="https://medium.com/@AlexanderObregon/constants-in-go-and-compile-time-behavior-4e27eeaebef5">Constants in Go and Compile Time Behavior</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/zero-values-in-go-and-why-they-matter-33b6bdb53211">Zero Values in Go and Why They Matter</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/what-go-does-with-the-blank-identifier-a9e3ab5e478f">What Go Does with the Blank Identifier</a></p></li></ul><h3>Language Mechanics and Behavior</h3><p>Covers how Go handles memory, slices, interfaces, and type systems behind the scenes.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;7a5ba95c-1a63-489d-b3dc-22990d547432&quot;,&quot;caption&quot;:&quot;Go slices give you a way to work with collections that can grow and shrink without handling arrays by hand. They&#8217;re lightweight, but there&#8217;s more going on behind the scenes than just changing size. Slices are connected to fixed-length arrays, and how they grow, share memory, or shift to new storage changes how your data behaves. Some bugs sh&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Behind the Scenes of Go Slices and Backing Arrays&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-08-07T22:30:54.254Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e2ec07c8-c25e-40aa-950c-1c093900c7e0_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/behind-the-scenes-of-go-slices-and&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:170402223,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;d00e0cc1-b221-4624-8059-c4a03f845b0e&quot;,&quot;caption&quot;:&quot;Working with maps in Go starts off feeling direct. You set one up, assign some values, and pull them out by key. That part makes sense, but when you drop in structs or slices, things start behaving in ways that don&#8217;t match what you had in mind. You write a few lines that look fine, and suddenly updates aren&#8217;t sticking, or values aren&#8217;t what &#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Go Maps and the Hidden Cost of Assignment&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-07-29T23:10:29.067Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b5b74391-959e-47e5-b31c-ca0b67a0cce8_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/go-maps-and-the-hidden-cost-of-assignment&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:169615538,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;49ec83e9-566a-4479-a83c-6bd2afe44d64&quot;,&quot;caption&quot;:&quot;Generics became part of Go with version 1.18, changing how developers write reusable and type-safe code. Many introductions stop at showing how to declare or call generic functions and types, but the real value comes from seeing how the compiler works with type parameters. That path runs through Go&#8217;s hybrid of GC-shape stenciling and diction&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Go Type Parameters and Runtime Behavior&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-09-09T20:52:24.738Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cfdadd29-a2fa-47f1-9234-995f259b537e_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/go-type-parameters-and-runtime-behavior&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:173218009,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;d103164b-07fc-4c61-879b-6d6735231694&quot;,&quot;caption&quot;:&quot;A common area of confusion in Go comes from how interfaces behave with nil. Many developers expect an interface set to nil to act the same as a plain nil pointer, but that assumption doesn&#8217;t hold. The reason lies in the way Go stores both type and value information inside an interface.&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Interface Nil Checks in Go&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-10-01T17:20:23.154Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8065b76c-e648-40d1-ab4d-60aa9fae8291_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/interface-nil-checks-in-go&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:174971492,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;91ca5ed7-6699-45c2-9bdb-1122ba8c05dc&quot;,&quot;caption&quot;:&quot;Pointer conversions with Go&#8217;s unsafe package sit right at the edge of what the compiler guards and what developers can stretch. The language was built with strong memory safety rules, but unsafe opens a narrow door to direct pointer manipulation. That door allows tricks that sidestep normal typing checks, though it always comes with a trade-&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Unsafe Pointer Conversions in Go&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-09-05T17:05:20.805Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/87017f10-badb-49a0-9153-13f5ec7bfb2f_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/unsafe-pointer-conversions-in-go&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:172615810,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;40a33cf7-a961-4b12-8131-4ca8782d3339&quot;,&quot;caption&quot;:&quot;Go String Concatenation Costs&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Go String Concatenation Costs&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-11-21T20:26:04.310Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/852bdb00-5cdd-4322-bcbb-2566bf83bfe0_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/go-string-concatenation-costs&quot;,&quot;section_name&quot;:&quot;Golang&quot;,&quot;video_upload_id&quot;:null,&quot;id&quot;:179191053,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p><strong>Medium articles:</strong></p><ul><li><p><a href="https://medium.com/@AlexanderObregon/go-slice-copy-mechanics-4e7472f4f730">Go Slice Copy Mechanics</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/go-defer-allocation-costs-459b6025da7e">Go Defer Allocation Costs</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/go-map-iteration-behavior-e33dee785cb4">Go Map Iteration Behavior</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/go-map-load-factor-3df1defc6c76">Go Map Load Factor</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/go-map-internals-and-why-ordering-isnt-stable-69551a7582c8">Go Map Internals and Why Ordering Isn&#8217;t Stable</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/map-growth-behavior-in-go-7d2a02e579a7">Go Map Growth Behavior in Go</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/rune-vs-byte-in-go-string-operations-780c0f2dd92c">Rune vs Byte in Go String Operations</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/passing-values-and-pointers-in-go-functions-f450f57a36d8">Passing Values and Pointers in Go Functions</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/go-pointer-arithmetic-you-can-and-cannot-do-bcb7d555c7ea">Go Pointer Arithmetic You Can and Cannot Do</a></p></li><li><p><a href="https://medium.com/codex/struct-embedding-in-go-fa9fd9d223ca">Struct Embedding in Go</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/memory-alignment-and-padding-in-go-structs-14836f47a6e0">Memory Alignment and Padding in Go Structs</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/why-go-structs-dont-always-copy-what-you-expect-baf014712b2b">Why Go Structs Don&#8217;t Always Copy What You Expect</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/breaking-down-gos-interface-and-type-switches-bf588a62b017">Breaking Down Go&#8217;s Interface{} and Type Switches</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/embedding-interfaces-in-go-ff85fd875be1">Embedding Interfaces in Go</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/go-variable-shadowing-and-how-it-happens-bbfdd00483e7">Go Variable Shadowing and How It Happens</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/map-deletion-process-in-go-2cd51ea0a49a">Map Deletion Process in Go</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/golangs-make-vs-new-explained-with-slices-maps-and-channels-cfdc5e234d90">Golang&#8217;s Make vs New Explained with Slices, Maps, and Channels</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/making-go-struct-tags-work-with-json-and-databases-7c698095b73a">Making Go Struct Tags Work with JSON and Databases</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/go-interfaces-behind-the-scenes-f8812706f2c5">Go Interfaces Behind the Scenes<br></a></p></li></ul><h3>Concurrency and Scheduling</h3><p>These focus on how Go&#8217;s runtime handles concurrent work and scheduling.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;a929fb53-cea9-424f-8bd0-20a4c12b68d4&quot;,&quot;caption&quot;:&quot;Concurrency in Go runs on goroutines, which are far lighter than operating system threads. What makes this possible is how their stacks are handled. Instead of reserving a large stack up front like a thread, a goroutine begins with a very small one that grows as the workload demands more space. The Go runtime expands it automatically, moving&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Goroutine Stacks in Go&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-08-29T17:23:15.354Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1c84d35b-5a7f-4704-ab17-b6dddd30db18_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/goroutine-stacks-in-go&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:171949941,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;5d4961cd-8401-463a-83c8-c142d7107fce&quot;,&quot;caption&quot;:&quot;Spawning a goroutine in Go with the go keyword looks effortless from a developer&#8217;s perspective, but the runtime does a surprising amount of work in the background to make that function call run independently. Today, we are going to take a look at the process from the moment a go statement appears, to how the runtime allocates stack memory, a&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Goroutine Creation Path in Go&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-12-02T18:21:38.890Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8908408d-c95c-49b2-a056-b90624260863_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/goroutine-creation-path-in-go&quot;,&quot;section_name&quot;:&quot;Golang&quot;,&quot;video_upload_id&quot;:null,&quot;id&quot;:180450298,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;c352faa1-06bb-4b43-beb5-5a1cd66d2d71&quot;,&quot;caption&quot;:&quot;Tracing the Go scheduler provides a clear view into how goroutines are created, scheduled, and executed by the runtime. Go programs often depend on thousands of goroutines, and the runtime scheduler decides how they run across available operating system threads. When tracing the scheduler, developers gain direct access to events such as goro&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Scheduler Tracing in Go Runtime&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-09-19T17:30:34.921Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/254a5635-c3ee-4b2a-a88a-14307d922f97_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/scheduler-tracing-in-go-runtime&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:173798841,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;18821830-1b98-44ab-801b-07090b598fae&quot;,&quot;caption&quot;:&quot;Most Go applications depend on goroutines to run work in parallel. A scheduler manages when each goroutine gets time on available threads, making sure they don&#8217;t all compete at once. The delay involved in handing control from one goroutine to another, or in responding when a goroutine becomes ready to run, is known as scheduler latency. That&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Scheduler Latency in Go Runtime&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-09-24T17:23:26.154Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/81c362b9-90fc-4976-9d0b-e5bf5f45447d_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/scheduler-latency-in-go-runtime&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:174383863,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;a087168a-9b9d-4814-b8c1-f30cd1143ae8&quot;,&quot;caption&quot;:&quot;Scheduling is what lets Go handle concurrency without forcing developers to manage threads directly. Instead of tying every goroutine to a single operating system thread, Go runs them on top of its own scheduler. That scheduler decides when a goroutine should run and moves it across threads as needed. This makes it possible to scale from a s&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Scheduler Hand Offs in Go&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-10-04T17:09:21.452Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/00eaaf34-790f-4262-ad1b-e9b6f28cb60c_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/scheduler-hand-offs-in-go&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:174974233,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;be0acaa9-9e2a-4a23-86b2-2faed45d6a52&quot;,&quot;caption&quot;:&quot;Goroutines sit at the center of Go&#8217;s concurrency story, but the piece that decides how they actually run is the runtime scheduler. That scheduler relies on both global and local queues to keep work moving across threads and processors. Runnable goroutines wait in these queues until they&#8217;re picked up, and the way they&#8217;re managed is what lets &#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Scheduler Queues in Go Runtime&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-11-19T18:12:19.034Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ece65820-da0c-47d9-adf4-52f33c09196e_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/scheduler-queues-in-go-runtime&quot;,&quot;section_name&quot;:&quot;Golang&quot;,&quot;video_upload_id&quot;:null,&quot;id&quot;:179189964,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;683d6880-6d51-4ba8-8613-72853d3b3312&quot;,&quot;caption&quot;:&quot;Go&#8217;s channels are one of the language&#8217;s most defining features. They let goroutines share data safely without any manual locking, but there&#8217;s more happening beneath that simple send operation than most realize. When several goroutines try to send to the same channel at the same time, the runtime carefully coordinates them through per-channel queues and FIFO pairing of senders and receivers that keeps everything running smoothly and fairly.&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Go Write Combining in Channels&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-10-11T02:20:42.512Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/272c4552-730e-43e8-8a35-dd14ee1581b7_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/go-write-combining-in-channels&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:175851640,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;b09f1c7c-2986-41fe-8a4d-9dfdbad687d0&quot;,&quot;caption&quot;:&quot;Channels in Go let goroutines pass data back and forth without locking. They form a foundation for concurrency because they give a structured way for values to move between different routines while keeping synchronization handled by the language. Capacity has a bigger effect than many realize. It changes how the runtime schedules work, how b&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Channel Capacity Limits in Go&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-09-26T17:16:17.500Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cb17a3bc-95e2-449c-b7d0-7e6a1ddf8df4_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/channel-capacity-limits-in-go&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:174384912,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;72562aee-1cbb-4c2b-8890-a3e25a7daa11&quot;,&quot;caption&quot;:&quot;How the Sysmon Thread Works in Go&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Sysmon Thread in Go Runtime&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-11-27T18:17:04.107Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2afb78a6-535f-433d-b22d-cfcbf71d8a4e_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/sysmon-thread-in-go-runtime&quot;,&quot;section_name&quot;:&quot;Golang&quot;,&quot;video_upload_id&quot;:null,&quot;id&quot;:180061529,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p><strong>Medium articles:</strong></p><ul><li><p><a href="https://medium.com/@AlexanderObregon/writing-concurrent-code-with-go-channels-and-select-8a32eb24b137">Writing Concurrent Code with Go Channels and Select</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/go-buffered-vs-unbuffered-channels-in-real-use-521bb682f6b0">Go Buffered vs Unbuffered Channels in Real Use</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/for-range-over-channels-in-go-and-what-it-does-f6847e10438c">For Range Over Channels in Go and What It Does</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/channel-direction-types-in-go-6467de14ca88">Channel Direction Types in Go</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/atomic-value-in-go-concurrency-d82dd187e73b">Atomic Value in Go Concurrency</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/memory-barriers-in-go-concurrency-6259919c7b6a">Memory Barriers in Go Concurrency</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/deadlock-scenarios-in-go-concurrency-2f628d5e4d15">Deadlock Scenarios in Go Concurrency</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/waitgroups-in-go-and-the-sync-process-fe0437333f0c">WaitGroups in Go and the Sync Process</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/goroutine-leaks-in-go-ece4824df9a1">Goroutine Leaks in Go</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/goroutine-preemption-in-go-0343e94e0e81">Goroutine Preemption in Go</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/goroutine-wakeups-in-go-scheduler-d82ead64ebcf">Goroutine Wakeups in Go Scheduler</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/goroutine-parking-logic-in-go-5d533e9e67fd">Goroutine Parking Logic in Go</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/scheduler-and-goroutine-time-slicing-in-go-120e49e0643a">Scheduler and Goroutine Time Slicing in Go</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/what-go-does-when-you-close-a-channel-7a02ef356635">What Go Does When You Close a Channel</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/scheduler-work-queues-in-go-0897c26087e9">Scheduler Work Queues in Go</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/what-happens-when-go-goroutines-outlive-main-3cbcd434294d">What Happens When Go Goroutines Outlive main()</a></p></li></ul><h3>Error and Panic Handling</h3><p>Explains how Go manages exceptions, recover behavior, and runtime stability.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;ecdbdf23-7095-45ad-b8b0-9f36c689e747&quot;,&quot;caption&quot;:&quot;Go has its own way of handling errors through panics, deferred calls, and the recover function. A panic stops normal flow when something unexpected happens, while deferred calls are instructions set aside to run as a function finishes. Recover works in this process by letting the function take back control after a panic is raised. All of the&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Deferred Recover in Go Panic Handling&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-09-17T17:05:07.487Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a91550d1-0cf6-46d0-b797-9ad5c843ee92_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/deferred-recover-in-go-panic-handling&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:173795459,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;c5a53cfb-deb5-48a6-8a75-e1189c024240&quot;,&quot;caption&quot;:&quot;Go&#8217;s defer keyword is a built-in part of the language, and the way it behaves follows a specific order that doesn't leave anything up to chance. Every time a function defers something, Go adds that call to a stack. When the function ends, those deferred calls run in the reverse order they were added. That last-in-first-out pattern isn't rand&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Why Go's Defer Statements Run Backward&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-08-02T22:50:33.050Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/abce2e89-d378-4695-bb00-880240913260_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/why-gos-defer-statements-run-backward&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:169956491,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:2,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p><strong>Medium articles:</strong></p><ul><li><p><a href="https://medium.com/@AlexanderObregon/panic-chaining-in-go-errors-65a8d82cd371">Panic Chaining in Go Errors</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/stack-traces-in-go-panics-4898073e47f5">Stack Traces in Go Panics</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/error-values-vs-sentinel-errors-in-go-a377c3d831d1">Error Values vs Sentinel Errors in Go</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/error-wrapping-with-gos-standard-library-0a345eeea019">Error Wrapping with Go&#8217;s Standard Library</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/defer-with-function-arguments-and-timing-in-go-a3859c58d95c">Defer with Function Arguments and Timing in Go</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/why-go-panics-are-different-from-exceptions-bdf43a3957c0">Why Go Panics Are Different From Exceptions</a></p></li></ul><h3>Networking and Runtime Internals</h3><p>Touches on Go&#8217;s deeper runtime behavior and how its networking stack works behind the scenes.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;4ed91908-5ca5-4b3c-b1a8-83445c1ba7b1&quot;,&quot;caption&quot;:&quot;Handling HTTP requests in Go means more than dropping a handler into http.HandleFunc. Behind that call, the standard library runs through a chain of steps that move raw bytes from a network connection into a structured request for your handler, then carry the response back to the client. That whole chain is why you see things like status cod&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Go HTTP Handlers and Connection Lifecycle&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-08-15T17:04:53.982Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5e4945c4-92b9-4d48-8cc4-377a2f279eb8_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/go-http-handlers-and-connection-lifecycle&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:170929026,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;08d05c2e-7c4d-45bb-b1b0-3d9fe5a21ac6&quot;,&quot;caption&quot;:&quot;Go handles large numbers of connections by leaning on its runtime. Beneath the surface of goroutines and channels runs a system that talks directly with the operating system&#8217;s event notification features. At the center is the netpoller, which parks goroutines when I/O would block and resumes them when the OS reports readiness or completion f&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Go Netpoller and Runtime Behavior&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-09-11T17:51:21.089Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/61a2296e-bf37-4add-90b3-330bebf8033b_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/go-netpoller-and-runtime-behavior&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:173219951,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;72c9711b-7145-4f45-8865-fd5b114bfbd0&quot;,&quot;caption&quot;:&quot;Secure communication across the internet depends on protocols that keep data private and confirm that both sides are who they claim to be. Transport Layer Security, or TLS, is one of the most largely adopted protocols for that purpose. In the Go language, the&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Go TLS Handshake Mechanics&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-10-03T17:43:17.234Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9798384e-8f9d-4b25-97b8-b92f3531e506_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/go-tls-handshake-mechanics&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:174972862,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;b5da20a6-d31f-42c7-ba92-8e192f2cca3a&quot;,&quot;caption&quot;:&quot;Timers in Go run behind the scenes to make features like time.After, time.NewTimer, and time.Ticker work. They give the impression of being just a simple wait followed by a signal or callback, but what actually happens is more structured. The Go runtime keeps all timers in a heap structure that lets it check for expirations quickly and keep &#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Timers and Heap Buckets in Go Runtime&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-09-06T17:39:11.421Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ffeaaef5-e9cc-44c5-8de2-eb75e3303cb1_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/timers-and-heap-buckets-in-go-runtime&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:172618149,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;fa7ddd57-5f57-450e-9398-9e8930f75bd2&quot;,&quot;caption&quot;:&quot;Behavior of file descriptors in Go affects how every open file, socket, or pipe moves through a process, from the moment the operating system assigns a small integer handle until that handle returns to the pool or stops working because the process has reached its limit. Go ties these descriptors to objects in the standard library so they can&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;File Descriptor Lifecycle in Go&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-01-15T18:29:26.102Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/da145f15-e56e-4edc-95c8-4ed010f6b62c_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/file-descriptor-lifecycle-in-go&quot;,&quot;section_name&quot;:&quot;Golang&quot;,&quot;video_upload_id&quot;:null,&quot;id&quot;:183857597,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p><strong>Medium articles:</strong></p><ul><li><p><a href="https://medium.com/@AlexanderObregon/go-context-package-and-how-it-cancels-work-cfe6f960df12">Go Context Package and How it Cancels Work</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/context-deadlines-in-go-8dabce6e89ed">Context Deadlines in Go</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/go-time-package-mechanics-for-scheduling-4284fc0c72af">Go Time Package Mechanics for Scheduling</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/signal-handling-in-go-applications-b96eb61ecb69">Signal Handling in Go Applications</a></p></li></ul><h3>Memory Management and Garbage Collection</h3><p>Focuses on how Go allocates, tracks, and reclaims memory.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;cafbbc3d-89ef-43cc-aa17-8b3808c2e5f9&quot;,&quot;caption&quot;:&quot;Memory management in Go balances speed, predictability, and efficiency. Programs built in Go often run for long stretches, sometimes as servers handling millions of requests. Over time, memory can become fragmented, and the allocator along with the garbage collector are responsible for dealing with that. Fragmentation shows up when memory is&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Memory Fragmentation in Go&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-11-25T18:29:18.711Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fd7965e0-1e16-4ca8-9293-6db2f3e3d6c2_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/memory-fragmentation-in-go&quot;,&quot;section_name&quot;:&quot;Golang&quot;,&quot;video_upload_id&quot;:null,&quot;id&quot;:179199725,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;093f3b47-ded2-402e-856a-70f811c51779&quot;,&quot;caption&quot;:&quot;Memory safety in Go relies on strict rules that control how memory is wiped before code reads from it. The language defines how every type starts at a well defined zero state, and the runtime allocator follows that contract for fresh allocations and for memory that gets recycled, so bytes from old values are not exposed to new ones. That beh&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Go Memory Zeroing&nbsp;Rules&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-01-06T18:07:31.052Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4a14bff0-10b7-494d-a955-9a0a4112940f_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/go-memory-zeroing-rules&quot;,&quot;section_name&quot;:&quot;Golang&quot;,&quot;video_upload_id&quot;:null,&quot;id&quot;:182814268,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:2,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p><strong>Medium articles:</strong></p><ul><li><p><a href="https://medium.com/@AlexanderObregon/memory-arenas-in-go-runtime-b9acc418d135">Memory Arenas in Go Runtime</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/memory-spans-in-go-allocator-cf47230b7522">Memory Spans in Go Allocator</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/memory-scavenger-in-go-runtime-b517147c0928">Memory Scavenger in Go Runtime</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/memory-quotas-in-go-runtime-b8793bf12610">Memory Quotas in Go Runtime</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/go-heap-growth-strategy-5f26ba100e82">Go Heap Growth Strategy</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/writing-barriers-in-go-garbage-collection-baf72a4ee088">Writing Barriers in Go Garbage Collection</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/page-reclamation-in-go-garbage-collector-3eb5a60f324f">Page Reclamation in Go Garbage Collector</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/stack-spans-in-go-runtime-ede06af77f0e">Stack Spans in Go Runtime</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/go-stack-vs-heap-memory-in-practice-db20da522da6">Go Stack vs Heap Memory in Practice</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/finalizers-in-go-garbage-collection-3aa887d55504">Finalizers in Go Garbage Collection</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/how-go-starts-garbage-collection-ade7cf32e0e9">How Go Starts Garbage Collection</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/memory-allocation-in-go-explained-7c4830b683ff">Memory Allocation in Go Explained</a></p></li></ul><h3>Compilation and Build Mechanics</h3><p>Covers Go&#8217;s build system, compiler, and toolchain behavior.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;863eb1b6-82b7-4b54-ac8a-22530e31ff68&quot;,&quot;caption&quot;:&quot;Go produces a self-contained executable that includes the Go runtime, your code, and required standard-library parts. On Linux with cgo disabled the result is fully static. With cgo enabled or on platforms like macOS, the binary links to system libraries. This makes delivery easy but it also leads to larger binaries than some expect. The too&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Go Binary Size Reduction&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-11-23T18:08:35.331Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/03f5e102-2237-4ca8-a199-44cafade7ca2_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/go-binary-size-reduction&quot;,&quot;section_name&quot;:&quot;Golang&quot;,&quot;video_upload_id&quot;:null,&quot;id&quot;:179198238,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;784128d2-1ec1-44cb-b980-85a3c92be488&quot;,&quot;caption&quot;:&quot;Modern software needs to be compiled in a way that produces the same binary across different machines and environments. This process is called a reproducible build. In the Go language, the build system supports this through a feature known as the build ID. The build ID serves as a hash that marks the fingerprint of a binary. Looking at how i&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Go Build ID and Reproducibility&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-11-26T21:02:07.016Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b4e7f87b-f794-4dab-ae0c-b06365eaa852_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/go-build-id-and-reproducibility&quot;,&quot;section_name&quot;:&quot;Golang&quot;,&quot;video_upload_id&quot;:null,&quot;id&quot;:180057240,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;8cf93427-fd70-4df1-814f-5a62bb0c1133&quot;,&quot;caption&quot;:&quot;Code that never runs in Go builds still takes space in binaries and can make long term maintenance harder. Go toolchain runs several stages that track reachability of functions and variables, remove work that has no effect on results, and trim data no part of the executable ever reads. Dead code elimination starts at the compiler, which turn&#8230;&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Dead Code Elimination in Go Builds&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:185785576,&quot;name&quot;:&quot;Alexander Obregon&quot;,&quot;bio&quot;:&quot;I publish daily on Medium and use Substack to share recaps, exclusive content, and give readers a way to support the programming-focused writing I do every day.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8905d669-ef92-4534-9c0c-f486ad372c94_1905x1905.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-01-10T18:30:31.559Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/76e83518-1d4f-4dfd-b8fa-61f2c58e93f0_882x449.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://alexanderobregon.substack.com/p/dead-code-elimination-in-go-builds&quot;,&quot;section_name&quot;:&quot;Golang&quot;,&quot;video_upload_id&quot;:null,&quot;id&quot;:182731877,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:4719466,&quot;publication_name&quot;:&quot;Alexander Obregon's Substack&quot;,&quot;publication_logo_url&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p><strong>Medium articles:</strong></p><ul><li><p><a href="https://medium.com/@AlexanderObregon/go-build-cache-mechanics-6ada202c0502">Go Build Cache Mechanics</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/how-to-build-constraints-in-go-toolchain-5502cc6741f7">How to Build Constraints in Go Toolchain</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/package-initialization-order-in-go-modules-8624a8732fa1">Package Initialization Order in Go Modules</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/go-constant-folding-in-compilation-9b1ad28bed53">Go Constant Folding in Compilation</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/go-build-flags-that-change-program-behavior-e8ec0548b667">Go Build Flags That Change Program Behavior</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/go-modules-without-the-confusion-6a663228879b">Go Modules Without the Confusion</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/what-go-developers-should-know-about-init-d03af922d464">What Go Developers Should Know About init()</a></p></li></ul><h3>Advanced Runtime and Escape Analysis</h3><p>This is all about how Go&#8217;s runtime evaluates variable lifetimes, escapes, and code optimization.</p><p><strong>Medium articles:</strong></p><ul><li><p><a href="https://medium.com/@AlexanderObregon/escape-paths-in-go-closures-2eeba4bf119e">Escape Paths in Go Closures</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/escape-paths-in-go-generics-cb4984d6fb20">Escape Paths in Go Generics</a></p></li><li><p><a href="https://medium.com/@AlexanderObregon/what-go-closures-keep-and-what-they-dont-85ab8fa95402">What Go Closures Keep and What They Don&#8217;t</a></p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Alexander Obregon's Substack</span></a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!j0dv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!j0dv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!j0dv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!j0dv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!j0dv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!j0dv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!j0dv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!j0dv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!j0dv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!j0dv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div>]]></content:encoded></item><item><title><![CDATA[Go Write Combining in Channels]]></title><description><![CDATA[Go&#8217;s channels are one of the language&#8217;s most defining features.]]></description><link>https://alexanderobregon.substack.com/p/go-write-combining-in-channels</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/go-write-combining-in-channels</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Sat, 11 Oct 2025 02:20:42 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/272c4552-730e-43e8-8a35-dd14ee1581b7_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!j0dv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!j0dv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!j0dv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!j0dv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!j0dv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!j0dv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!j0dv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!j0dv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!j0dv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!j0dv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F256c9150-e1f8-4438-b83d-98b28a4ec0b4_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>Go&#8217;s channels are one of the language&#8217;s most defining features. They let goroutines share data safely without any manual locking, but there&#8217;s more happening beneath that simple send operation than most realize. When several goroutines try to send to the same channel at the same time, the runtime carefully coordinates them through per-channel queues and FIFO pairing of senders and receivers that keeps everything running smoothly and fairly.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>How Channels Queue Multiple Sends</h3><p>Channels in Go handle far more than only moving data between goroutines. Every time a value is sent, the runtime makes decisions about where that value should go, how it should be stored, and which waiting goroutine should resume next. When multiple sends arrive almost at once, those decisions stack up fast, and the runtime manages them through well-structured queues and careful synchronization inside the <code>hchan</code> structure. Each channel keeps a record of its state, including a buffer, read and write indexes, and linked lists of waiting senders and receivers.</p>
      <p>
          <a href="https://alexanderobregon.substack.com/p/go-write-combining-in-channels">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Scheduler Hand Offs in Go]]></title><description><![CDATA[Scheduling is what lets Go handle concurrency without forcing developers to manage threads directly.]]></description><link>https://alexanderobregon.substack.com/p/scheduler-hand-offs-in-go</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/scheduler-hand-offs-in-go</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Sat, 04 Oct 2025 17:09:21 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/00eaaf34-790f-4262-ad1b-e9b6f28cb60c_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iZH8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5fb0a2f-df1a-4232-81b4-c98a85f5c9f6_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iZH8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5fb0a2f-df1a-4232-81b4-c98a85f5c9f6_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!iZH8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5fb0a2f-df1a-4232-81b4-c98a85f5c9f6_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!iZH8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5fb0a2f-df1a-4232-81b4-c98a85f5c9f6_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!iZH8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5fb0a2f-df1a-4232-81b4-c98a85f5c9f6_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iZH8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5fb0a2f-df1a-4232-81b4-c98a85f5c9f6_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d5fb0a2f-df1a-4232-81b4-c98a85f5c9f6_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iZH8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5fb0a2f-df1a-4232-81b4-c98a85f5c9f6_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!iZH8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5fb0a2f-df1a-4232-81b4-c98a85f5c9f6_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!iZH8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5fb0a2f-df1a-4232-81b4-c98a85f5c9f6_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!iZH8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5fb0a2f-df1a-4232-81b4-c98a85f5c9f6_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>Scheduling is what lets Go handle concurrency without forcing developers to manage threads directly. Instead of tying every goroutine to a single operating system thread, Go runs them on top of its own scheduler. That scheduler decides when a goroutine should run and moves it across threads as needed. This makes it possible to scale from a small handful of work all the way up to hundreds of thousands running side by side. At the center of that process is the hand off, where goroutines shift between threads as the scheduler responds to blocking calls, heavy load, and contention.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>How the Scheduler Coordinates Execution</h3><p>The Go scheduler creates the illusion that goroutines run in parallel across many threads, even though the number of actual operating system threads is usually far lower. Instead of giving each goroutine its own thread, Go builds a system where lightweight goroutines can be scheduled onto a limited pool of worker threads. This approach reduces memory overhead and lets far more concurrent units run than what the operating system could normally handle. To make this possible, the runtime follows a model based on three components that work in tandem: the goroutine itself, the thread that executes machine instructions, and the processor context that manages queues.</p><h4>The Model of G M P</h4><p>At the lowest level, a goroutine is just a structure in memory that stores its stack, program counter, and metadata about its state. It&#8217;s referred to as G in scheduler documentation. An M represents an operating system thread, which is where instructions actually execute on the CPU. The P, short for processor, is not a hardware core but an internal construct that ties things together. It maintains a run queue and holds resources required for scheduling decisions.</p><p>When an M wants to run a goroutine, it must acquire a P. Without that link, the goroutine can&#8217;t make forward progress. If an M blocks in a system call, its P is detached and paired with another M so runnable goroutines keep moving. If an M is idle with no work to do, the P can be picked up by another M that has work waiting. This model gives Go its flexibility to scale workloads without requiring the programmer to think about thread affinity or operating system scheduling policies.</p><p>A small example can give a feel for how goroutines flow through the system.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0DkO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca157368-6866-457b-a92a-38d3c40ab56f_972x626.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0DkO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca157368-6866-457b-a92a-38d3c40ab56f_972x626.png 424w, https://substackcdn.com/image/fetch/$s_!0DkO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca157368-6866-457b-a92a-38d3c40ab56f_972x626.png 848w, https://substackcdn.com/image/fetch/$s_!0DkO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca157368-6866-457b-a92a-38d3c40ab56f_972x626.png 1272w, https://substackcdn.com/image/fetch/$s_!0DkO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca157368-6866-457b-a92a-38d3c40ab56f_972x626.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0DkO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca157368-6866-457b-a92a-38d3c40ab56f_972x626.png" width="588" height="378.69135802469134" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ca157368-6866-457b-a92a-38d3c40ab56f_972x626.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:626,&quot;width&quot;:972,&quot;resizeWidth&quot;:588,&quot;bytes&quot;:72959,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174974233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca157368-6866-457b-a92a-38d3c40ab56f_972x626.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0DkO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca157368-6866-457b-a92a-38d3c40ab56f_972x626.png 424w, https://substackcdn.com/image/fetch/$s_!0DkO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca157368-6866-457b-a92a-38d3c40ab56f_972x626.png 848w, https://substackcdn.com/image/fetch/$s_!0DkO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca157368-6866-457b-a92a-38d3c40ab56f_972x626.png 1272w, https://substackcdn.com/image/fetch/$s_!0DkO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca157368-6866-457b-a92a-38d3c40ab56f_972x626.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Three goroutines are launched in quick succession. Behind the scenes, each G is placed in a P&#8217;s run queue. The M executing on the CPU pulls goroutines from that queue and runs them. When a goroutine calls <code>time.Sleep</code>, that goroutine is paused while its M keeps running other runnable goroutines on the same P. The P isn&#8217;t handed off just because of sleep. To the developer it feels seamless, but the scheduler is doing the hand offs in the background.</p><h4>Hand Off During Blocking Operations</h4><p>One of the most common times a hand off occurs is when a goroutine blocks on a system call. That might be a file read, a network socket waiting for data, or a timer. If the scheduler kept the P tied to that blocked M, no other goroutines on that P could run until the system call finished. Instead, Go detaches the P from the blocked M and attaches it to another available M, or spawns a fresh M if no threads are free. This way, goroutines waiting in the queue don&#8217;t have to stall just because one of their peers is blocked.</p><p>This becomes easier to appreciate with a short server code example.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ihaG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8d8d15d-bf02-4765-a178-539800996325_1220x594.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ihaG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8d8d15d-bf02-4765-a178-539800996325_1220x594.png 424w, https://substackcdn.com/image/fetch/$s_!ihaG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8d8d15d-bf02-4765-a178-539800996325_1220x594.png 848w, https://substackcdn.com/image/fetch/$s_!ihaG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8d8d15d-bf02-4765-a178-539800996325_1220x594.png 1272w, https://substackcdn.com/image/fetch/$s_!ihaG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8d8d15d-bf02-4765-a178-539800996325_1220x594.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ihaG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8d8d15d-bf02-4765-a178-539800996325_1220x594.png" width="1220" height="594" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e8d8d15d-bf02-4765-a178-539800996325_1220x594.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:594,&quot;width&quot;:1220,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83470,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174974233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8d8d15d-bf02-4765-a178-539800996325_1220x594.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ihaG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8d8d15d-bf02-4765-a178-539800996325_1220x594.png 424w, https://substackcdn.com/image/fetch/$s_!ihaG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8d8d15d-bf02-4765-a178-539800996325_1220x594.png 848w, https://substackcdn.com/image/fetch/$s_!ihaG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8d8d15d-bf02-4765-a178-539800996325_1220x594.png 1272w, https://substackcdn.com/image/fetch/$s_!ihaG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8d8d15d-bf02-4765-a178-539800996325_1220x594.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Each incoming request runs in its own goroutine. A call to <code>time.Sleep</code> pauses that goroutine without blocking the thread, so the M keeps its P and continues with other work. When a goroutine blocks in a system call, the runtime detaches the P from that M and gives it to another M so other requests don&#8217;t stall.</p><p>To push this idea further, consider combining blocking with concurrent computation.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WkEy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b729f74-1815-44a3-a41b-deedb484320b_1148x728.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WkEy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b729f74-1815-44a3-a41b-deedb484320b_1148x728.png 424w, https://substackcdn.com/image/fetch/$s_!WkEy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b729f74-1815-44a3-a41b-deedb484320b_1148x728.png 848w, https://substackcdn.com/image/fetch/$s_!WkEy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b729f74-1815-44a3-a41b-deedb484320b_1148x728.png 1272w, https://substackcdn.com/image/fetch/$s_!WkEy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b729f74-1815-44a3-a41b-deedb484320b_1148x728.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WkEy!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b729f74-1815-44a3-a41b-deedb484320b_1148x728.png" width="826" height="523.8048780487804" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5b729f74-1815-44a3-a41b-deedb484320b_1148x728.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:728,&quot;width&quot;:1148,&quot;resizeWidth&quot;:826,&quot;bytes&quot;:75517,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174974233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b729f74-1815-44a3-a41b-deedb484320b_1148x728.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WkEy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b729f74-1815-44a3-a41b-deedb484320b_1148x728.png 424w, https://substackcdn.com/image/fetch/$s_!WkEy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b729f74-1815-44a3-a41b-deedb484320b_1148x728.png 848w, https://substackcdn.com/image/fetch/$s_!WkEy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b729f74-1815-44a3-a41b-deedb484320b_1148x728.png 1272w, https://substackcdn.com/image/fetch/$s_!WkEy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b729f74-1815-44a3-a41b-deedb484320b_1148x728.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>While one goroutine blocks on file I/O, the other keeps running. That&#8217;s possible because the P is handed off to another M that continues executing ready goroutines. Without that behavior, the calculation would stall until the file read completed.</p><h4>Work Stealing</h4><p>Goroutines are placed in local run queues that belong to each P. Most of the time, an M pulls work from its own P&#8217;s queue. But sometimes the queue empties out while other Ps have more goroutines than they can handle. To keep execution balanced, Go uses work stealing. An idle P can take a batch of goroutines from the tail of another P&#8217;s queue and run them on its own thread. This prevents scenarios where one P is overloaded while others sit idle.</p><p>The runtime makes stealing efficient by transferring half the work at a time. That way, a single P doesn&#8217;t repeatedly raid another P&#8217;s queue, and both can continue executing with a balanced load.</p><p>A small workload distribution visual can help make this concept a bit more tangible.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ifUv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3af03e24-c4b4-4adb-8547-60042784372d_974x800.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ifUv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3af03e24-c4b4-4adb-8547-60042784372d_974x800.png 424w, https://substackcdn.com/image/fetch/$s_!ifUv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3af03e24-c4b4-4adb-8547-60042784372d_974x800.png 848w, https://substackcdn.com/image/fetch/$s_!ifUv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3af03e24-c4b4-4adb-8547-60042784372d_974x800.png 1272w, https://substackcdn.com/image/fetch/$s_!ifUv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3af03e24-c4b4-4adb-8547-60042784372d_974x800.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ifUv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3af03e24-c4b4-4adb-8547-60042784372d_974x800.png" width="629" height="516.6324435318276" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3af03e24-c4b4-4adb-8547-60042784372d_974x800.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:974,&quot;resizeWidth&quot;:629,&quot;bytes&quot;:80014,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174974233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3af03e24-c4b4-4adb-8547-60042784372d_974x800.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ifUv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3af03e24-c4b4-4adb-8547-60042784372d_974x800.png 424w, https://substackcdn.com/image/fetch/$s_!ifUv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3af03e24-c4b4-4adb-8547-60042784372d_974x800.png 848w, https://substackcdn.com/image/fetch/$s_!ifUv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3af03e24-c4b4-4adb-8547-60042784372d_974x800.png 1272w, https://substackcdn.com/image/fetch/$s_!ifUv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3af03e24-c4b4-4adb-8547-60042784372d_974x800.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>With two Ps available, six goroutines are distributed across them. As soon as one queue becomes lighter than the other, work stealing occurs to even things out. The developer doesn&#8217;t see the transfers, but they keep execution balanced and prevent idle time.</p><p>Work stealing becomes more pronounced with highly uneven loads.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZQtV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9793fc89-1031-4342-82fe-f6331823c325_964x783.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZQtV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9793fc89-1031-4342-82fe-f6331823c325_964x783.png 424w, https://substackcdn.com/image/fetch/$s_!ZQtV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9793fc89-1031-4342-82fe-f6331823c325_964x783.png 848w, https://substackcdn.com/image/fetch/$s_!ZQtV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9793fc89-1031-4342-82fe-f6331823c325_964x783.png 1272w, https://substackcdn.com/image/fetch/$s_!ZQtV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9793fc89-1031-4342-82fe-f6331823c325_964x783.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZQtV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9793fc89-1031-4342-82fe-f6331823c325_964x783.png" width="964" height="783" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9793fc89-1031-4342-82fe-f6331823c325_964x783.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:783,&quot;width&quot;:964,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:77772,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174974233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9793fc89-1031-4342-82fe-f6331823c325_964x783.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZQtV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9793fc89-1031-4342-82fe-f6331823c325_964x783.png 424w, https://substackcdn.com/image/fetch/$s_!ZQtV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9793fc89-1031-4342-82fe-f6331823c325_964x783.png 848w, https://substackcdn.com/image/fetch/$s_!ZQtV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9793fc89-1031-4342-82fe-f6331823c325_964x783.png 1272w, https://substackcdn.com/image/fetch/$s_!ZQtV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9793fc89-1031-4342-82fe-f6331823c325_964x783.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Two short goroutines finish almost instantly. Without stealing, the Ps tied to them would become idle while the long goroutines ran to completion on a single P. Instead, the runtime balances the load so that long-running work doesn&#8217;t pile up on one thread.</p><h4>Goroutine Shifting</h4><p>Goroutines shift between threads in ways that aren&#8217;t always obvious, since the runtime handles the details. They can move during blocking calls, when the scheduler preempts them, or when Ps are reattached to new Ms. The important part is that goroutines don&#8217;t remain permanently tied to one thread.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!atJH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7042a416-4e93-418d-b917-6968acedb8cb_1102x697.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!atJH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7042a416-4e93-418d-b917-6968acedb8cb_1102x697.png 424w, https://substackcdn.com/image/fetch/$s_!atJH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7042a416-4e93-418d-b917-6968acedb8cb_1102x697.png 848w, https://substackcdn.com/image/fetch/$s_!atJH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7042a416-4e93-418d-b917-6968acedb8cb_1102x697.png 1272w, https://substackcdn.com/image/fetch/$s_!atJH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7042a416-4e93-418d-b917-6968acedb8cb_1102x697.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!atJH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7042a416-4e93-418d-b917-6968acedb8cb_1102x697.png" width="674" height="426.29582577132487" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7042a416-4e93-418d-b917-6968acedb8cb_1102x697.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:697,&quot;width&quot;:1102,&quot;resizeWidth&quot;:674,&quot;bytes&quot;:75043,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174974233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7042a416-4e93-418d-b917-6968acedb8cb_1102x697.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!atJH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7042a416-4e93-418d-b917-6968acedb8cb_1102x697.png 424w, https://substackcdn.com/image/fetch/$s_!atJH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7042a416-4e93-418d-b917-6968acedb8cb_1102x697.png 848w, https://substackcdn.com/image/fetch/$s_!atJH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7042a416-4e93-418d-b917-6968acedb8cb_1102x697.png 1272w, https://substackcdn.com/image/fetch/$s_!atJH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7042a416-4e93-418d-b917-6968acedb8cb_1102x697.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The output will often interleave across workers in unpredictable ways. That&#8217;s because goroutines are being shifted between threads as the scheduler responds to sleeps and hand offs. The same goroutine may start on one M and later resume on another, but this is transparent to the code.</p><h3>What Happens During Heavy Contention</h3><p>When many goroutines try to use the same resources, the scheduler has to manage how they wait and resume without letting threads waste time. This is where the parking mechanism, spinning, and preemption all come into play. Heavy contention can happen with channels, mutexes, or other synchronization tools, and the runtime has strategies to keep things balanced.</p><h4>Contention With Goroutine Parking</h4><p>When a goroutine cannot move forward because another one holds a lock or a channel is full, the runtime places it into a parked state. Parking removes it from the active queue so that other goroutines can run on the same thread. When the resource becomes available, the goroutine is marked as runnable again and the scheduler can place it back onto a P&#8217;s queue.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vJak!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d24d96e-68e9-4823-8191-3ef9b16ed5e6_1223x804.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vJak!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d24d96e-68e9-4823-8191-3ef9b16ed5e6_1223x804.png 424w, https://substackcdn.com/image/fetch/$s_!vJak!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d24d96e-68e9-4823-8191-3ef9b16ed5e6_1223x804.png 848w, https://substackcdn.com/image/fetch/$s_!vJak!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d24d96e-68e9-4823-8191-3ef9b16ed5e6_1223x804.png 1272w, https://substackcdn.com/image/fetch/$s_!vJak!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d24d96e-68e9-4823-8191-3ef9b16ed5e6_1223x804.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vJak!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d24d96e-68e9-4823-8191-3ef9b16ed5e6_1223x804.png" width="1223" height="804" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6d24d96e-68e9-4823-8191-3ef9b16ed5e6_1223x804.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:804,&quot;width&quot;:1223,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:111557,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174974233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d24d96e-68e9-4823-8191-3ef9b16ed5e6_1223x804.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vJak!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d24d96e-68e9-4823-8191-3ef9b16ed5e6_1223x804.png 424w, https://substackcdn.com/image/fetch/$s_!vJak!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d24d96e-68e9-4823-8191-3ef9b16ed5e6_1223x804.png 848w, https://substackcdn.com/image/fetch/$s_!vJak!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d24d96e-68e9-4823-8191-3ef9b16ed5e6_1223x804.png 1272w, https://substackcdn.com/image/fetch/$s_!vJak!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d24d96e-68e9-4823-8191-3ef9b16ed5e6_1223x804.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Each worker tries to acquire the mutex. Only one can succeed at a time, and the others are parked by the scheduler until the lock is released. This avoids having multiple threads sit idle waiting on the same lock.</p><p>Another common case is with buffered channels.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!azja!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F038eb0d7-d9d2-49b2-832c-7d7f6e99ac6d_755x784.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!azja!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F038eb0d7-d9d2-49b2-832c-7d7f6e99ac6d_755x784.png 424w, https://substackcdn.com/image/fetch/$s_!azja!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F038eb0d7-d9d2-49b2-832c-7d7f6e99ac6d_755x784.png 848w, https://substackcdn.com/image/fetch/$s_!azja!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F038eb0d7-d9d2-49b2-832c-7d7f6e99ac6d_755x784.png 1272w, https://substackcdn.com/image/fetch/$s_!azja!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F038eb0d7-d9d2-49b2-832c-7d7f6e99ac6d_755x784.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!azja!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F038eb0d7-d9d2-49b2-832c-7d7f6e99ac6d_755x784.png" width="586" height="608.5086092715231" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/038eb0d7-d9d2-49b2-832c-7d7f6e99ac6d_755x784.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:784,&quot;width&quot;:755,&quot;resizeWidth&quot;:586,&quot;bytes&quot;:84165,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174974233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F038eb0d7-d9d2-49b2-832c-7d7f6e99ac6d_755x784.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!azja!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F038eb0d7-d9d2-49b2-832c-7d7f6e99ac6d_755x784.png 424w, https://substackcdn.com/image/fetch/$s_!azja!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F038eb0d7-d9d2-49b2-832c-7d7f6e99ac6d_755x784.png 848w, https://substackcdn.com/image/fetch/$s_!azja!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F038eb0d7-d9d2-49b2-832c-7d7f6e99ac6d_755x784.png 1272w, https://substackcdn.com/image/fetch/$s_!azja!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F038eb0d7-d9d2-49b2-832c-7d7f6e99ac6d_755x784.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The producer goroutine blocks when the channel buffer is full. At that moment, it&#8217;s parked until the consumer frees up space. The scheduler can hand the thread to other work instead of letting it stall.</p><h4>Spinning Before Parking In Mutexes</h4><p>The Go runtime doesn&#8217;t always park a goroutine immediately when it runs into contention. For mutexes in particular, the goroutine may spin briefly to see if the lock becomes free. Spinning avoids the overhead of a full park and unpark if the lock is only held for a tiny window of time. If the lock doesn&#8217;t open quickly, the goroutine is then parked.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XBEC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae19e502-3183-4575-8670-7f77639d2ec3_1005x769.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XBEC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae19e502-3183-4575-8670-7f77639d2ec3_1005x769.png 424w, https://substackcdn.com/image/fetch/$s_!XBEC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae19e502-3183-4575-8670-7f77639d2ec3_1005x769.png 848w, https://substackcdn.com/image/fetch/$s_!XBEC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae19e502-3183-4575-8670-7f77639d2ec3_1005x769.png 1272w, https://substackcdn.com/image/fetch/$s_!XBEC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae19e502-3183-4575-8670-7f77639d2ec3_1005x769.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XBEC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae19e502-3183-4575-8670-7f77639d2ec3_1005x769.png" width="650" height="497.363184079602" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ae19e502-3183-4575-8670-7f77639d2ec3_1005x769.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:769,&quot;width&quot;:1005,&quot;resizeWidth&quot;:650,&quot;bytes&quot;:91130,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174974233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae19e502-3183-4575-8670-7f77639d2ec3_1005x769.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XBEC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae19e502-3183-4575-8670-7f77639d2ec3_1005x769.png 424w, https://substackcdn.com/image/fetch/$s_!XBEC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae19e502-3183-4575-8670-7f77639d2ec3_1005x769.png 848w, https://substackcdn.com/image/fetch/$s_!XBEC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae19e502-3183-4575-8670-7f77639d2ec3_1005x769.png 1272w, https://substackcdn.com/image/fetch/$s_!XBEC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae19e502-3183-4575-8670-7f77639d2ec3_1005x769.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Each goroutine holds the lock for only a short time. The ones that don&#8217;t acquire it immediately spin briefly, and in most cases that&#8217;s enough for them to grab it as soon as it opens. The effect is lower overhead than full parking cycles.</p><p>If contention lasts longer, the spinning strategy transitions into proper parking. That happens often when goroutines perform longer operations while holding a lock.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DYlV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ed7284-e76a-44cc-9e37-ee1f7a0e69e8_1018x805.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DYlV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ed7284-e76a-44cc-9e37-ee1f7a0e69e8_1018x805.png 424w, https://substackcdn.com/image/fetch/$s_!DYlV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ed7284-e76a-44cc-9e37-ee1f7a0e69e8_1018x805.png 848w, https://substackcdn.com/image/fetch/$s_!DYlV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ed7284-e76a-44cc-9e37-ee1f7a0e69e8_1018x805.png 1272w, https://substackcdn.com/image/fetch/$s_!DYlV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ed7284-e76a-44cc-9e37-ee1f7a0e69e8_1018x805.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DYlV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ed7284-e76a-44cc-9e37-ee1f7a0e69e8_1018x805.png" width="620" height="490.27504911591353" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/57ed7284-e76a-44cc-9e37-ee1f7a0e69e8_1018x805.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:805,&quot;width&quot;:1018,&quot;resizeWidth&quot;:620,&quot;bytes&quot;:103855,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174974233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ed7284-e76a-44cc-9e37-ee1f7a0e69e8_1018x805.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DYlV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ed7284-e76a-44cc-9e37-ee1f7a0e69e8_1018x805.png 424w, https://substackcdn.com/image/fetch/$s_!DYlV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ed7284-e76a-44cc-9e37-ee1f7a0e69e8_1018x805.png 848w, https://substackcdn.com/image/fetch/$s_!DYlV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ed7284-e76a-44cc-9e37-ee1f7a0e69e8_1018x805.png 1272w, https://substackcdn.com/image/fetch/$s_!DYlV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ed7284-e76a-44cc-9e37-ee1f7a0e69e8_1018x805.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In this case spinning isn&#8217;t enough, so goroutines that can&#8217;t grab the lock park until the scheduler wakes them later.</p><h4>Scheduler Fairness</h4><p>Without preemption, a long-running goroutine could monopolize the CPU and starve others waiting to run. Starting with Go 1.14, the scheduler added preemption points that allow the runtime to interrupt long goroutines and give others a turn. These preemption points are inserted at safe locations, such as during function calls or certain loops, so that goroutines don&#8217;t run unchecked for too long.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L4F_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F213d8888-f84a-4c77-af8d-3c09196c4cb6_1098x843.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L4F_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F213d8888-f84a-4c77-af8d-3c09196c4cb6_1098x843.png 424w, https://substackcdn.com/image/fetch/$s_!L4F_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F213d8888-f84a-4c77-af8d-3c09196c4cb6_1098x843.png 848w, https://substackcdn.com/image/fetch/$s_!L4F_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F213d8888-f84a-4c77-af8d-3c09196c4cb6_1098x843.png 1272w, https://substackcdn.com/image/fetch/$s_!L4F_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F213d8888-f84a-4c77-af8d-3c09196c4cb6_1098x843.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L4F_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F213d8888-f84a-4c77-af8d-3c09196c4cb6_1098x843.png" width="618" height="474.4754098360656" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/213d8888-f84a-4c77-af8d-3c09196c4cb6_1098x843.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:843,&quot;width&quot;:1098,&quot;resizeWidth&quot;:618,&quot;bytes&quot;:90995,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174974233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F213d8888-f84a-4c77-af8d-3c09196c4cb6_1098x843.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!L4F_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F213d8888-f84a-4c77-af8d-3c09196c4cb6_1098x843.png 424w, https://substackcdn.com/image/fetch/$s_!L4F_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F213d8888-f84a-4c77-af8d-3c09196c4cb6_1098x843.png 848w, https://substackcdn.com/image/fetch/$s_!L4F_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F213d8888-f84a-4c77-af8d-3c09196c4cb6_1098x843.png 1272w, https://substackcdn.com/image/fetch/$s_!L4F_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F213d8888-f84a-4c77-af8d-3c09196c4cb6_1098x843.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>With a single processor allowed, one goroutine could take over without preemption. Instead, Go interrupts long loops and yields execution so that other goroutines make progress. This change keeps concurrency fair even under heavy load.</p><h4>Contention Example</h4><p>A combined case can help bring the mechanics together. Multiple goroutines attempt to increment a shared counter while preemption, spinning, and parking all come into play</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FcMn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcac2767-001e-44e4-8336-050789c849bd_1058x841.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FcMn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcac2767-001e-44e4-8336-050789c849bd_1058x841.png 424w, https://substackcdn.com/image/fetch/$s_!FcMn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcac2767-001e-44e4-8336-050789c849bd_1058x841.png 848w, https://substackcdn.com/image/fetch/$s_!FcMn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcac2767-001e-44e4-8336-050789c849bd_1058x841.png 1272w, https://substackcdn.com/image/fetch/$s_!FcMn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcac2767-001e-44e4-8336-050789c849bd_1058x841.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FcMn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcac2767-001e-44e4-8336-050789c849bd_1058x841.png" width="1058" height="841" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dcac2767-001e-44e4-8336-050789c849bd_1058x841.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:841,&quot;width&quot;:1058,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:86678,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174974233?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcac2767-001e-44e4-8336-050789c849bd_1058x841.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FcMn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcac2767-001e-44e4-8336-050789c849bd_1058x841.png 424w, https://substackcdn.com/image/fetch/$s_!FcMn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcac2767-001e-44e4-8336-050789c849bd_1058x841.png 848w, https://substackcdn.com/image/fetch/$s_!FcMn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcac2767-001e-44e4-8336-050789c849bd_1058x841.png 1272w, https://substackcdn.com/image/fetch/$s_!FcMn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcac2767-001e-44e4-8336-050789c849bd_1058x841.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Each goroutine competes for the mutex, and the scheduler parks those that can&#8217;t acquire it. Spinning gives short contenders a chance to grab it quickly, while longer lock holds lead to parked goroutines. If one goroutine were to run too long without yielding, preemption would step in.</p><h3>Conclusion</h3><p>Go&#8217;s scheduler keeps goroutines moving through a small pool of threads, handing work off when calls block, queues empty, or a long runner needs to yield. G M P gives the runtime the knobs to detach and reattach execution without user code getting tangled in threads. Work stealing balances queues, parking keeps lock waiters out of the way, and preemption stops a single loop from hogging the CPU. Put together, these mechanics let you think in goroutines while the runtime handles the hand offs that make large workloads feel smooth.</p><ol><li><p><em><a href="https://golang.org/doc/faq#goroutines">Go Scheduler Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/runtime">Go Runtime Package Reference</a></em></p></li><li><p><em><a href="https://golang.org/ref/mem">Go Memory Model</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Go TLS Handshake Mechanics]]></title><description><![CDATA[Secure communication across the internet depends on protocols that keep data private and confirm that both sides are who they claim to be.]]></description><link>https://alexanderobregon.substack.com/p/go-tls-handshake-mechanics</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/go-tls-handshake-mechanics</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Fri, 03 Oct 2025 17:43:17 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/9798384e-8f9d-4b25-97b8-b92f3531e506_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tVZR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e3edf6-189f-4817-be87-cbaf91f72d61_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tVZR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e3edf6-189f-4817-be87-cbaf91f72d61_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!tVZR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e3edf6-189f-4817-be87-cbaf91f72d61_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!tVZR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e3edf6-189f-4817-be87-cbaf91f72d61_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!tVZR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e3edf6-189f-4817-be87-cbaf91f72d61_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tVZR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e3edf6-189f-4817-be87-cbaf91f72d61_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d9e3edf6-189f-4817-be87-cbaf91f72d61_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tVZR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e3edf6-189f-4817-be87-cbaf91f72d61_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!tVZR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e3edf6-189f-4817-be87-cbaf91f72d61_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!tVZR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e3edf6-189f-4817-be87-cbaf91f72d61_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!tVZR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e3edf6-189f-4817-be87-cbaf91f72d61_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>Secure communication across the internet depends on protocols that keep data private and confirm that both sides are who they claim to be. Transport Layer Security, or TLS, is one of the most largely adopted protocols for that purpose. In the Go language, the <code>crypto/tls</code> package gives developers a way to set up secure connections between clients and servers. At the center of this process is the TLS handshake, which lets both ends agree on encryption methods, confirm identities, and establish shared secrets before any application data is exchanged.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>How a TLS Handshake Starts in Go</h3><p>Before two systems can exchange encrypted messages, they first need to agree on the details of how the encryption will work. This early phase sets the stage for everything that follows in the handshake. Go&#8217;s <code>crypto/tls</code> package handles this exchange automatically, but looking closer at how it starts makes it easier to understand why things are arranged the way they are.</p><h4>Initiating a Secure Connection</h4><p>A client begins the process by asking for a secure channel, and in Go there are a few different ways to do that. A common method is to call <code>tls.Dial</code>, which not only opens a TCP connection but also wraps it in a TLS handshake right away. Developers can also create a raw TCP connection through the <code>net</code> package and then upgrade it by wrapping it with <code>tls.Client</code>. Both options eventually trigger the same handshake process.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!T31o!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a55b10-93bd-4ccf-a0d9-ec0714588886_1290x665.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!T31o!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a55b10-93bd-4ccf-a0d9-ec0714588886_1290x665.png 424w, https://substackcdn.com/image/fetch/$s_!T31o!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a55b10-93bd-4ccf-a0d9-ec0714588886_1290x665.png 848w, https://substackcdn.com/image/fetch/$s_!T31o!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a55b10-93bd-4ccf-a0d9-ec0714588886_1290x665.png 1272w, https://substackcdn.com/image/fetch/$s_!T31o!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a55b10-93bd-4ccf-a0d9-ec0714588886_1290x665.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!T31o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a55b10-93bd-4ccf-a0d9-ec0714588886_1290x665.png" width="1290" height="665" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/81a55b10-93bd-4ccf-a0d9-ec0714588886_1290x665.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:665,&quot;width&quot;:1290,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:93550,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174972862?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a55b10-93bd-4ccf-a0d9-ec0714588886_1290x665.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!T31o!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a55b10-93bd-4ccf-a0d9-ec0714588886_1290x665.png 424w, https://substackcdn.com/image/fetch/$s_!T31o!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a55b10-93bd-4ccf-a0d9-ec0714588886_1290x665.png 848w, https://substackcdn.com/image/fetch/$s_!T31o!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a55b10-93bd-4ccf-a0d9-ec0714588886_1290x665.png 1272w, https://substackcdn.com/image/fetch/$s_!T31o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81a55b10-93bd-4ccf-a0d9-ec0714588886_1290x665.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This short client code dials a server on port 443 and negotiates TLS 1.3. The <code>ServerName</code> field tells the client which hostname it expects, which is important for certificate validation.</p><p>On the server side, things start when a <code>tls.Listener</code> accepts an incoming connection. That listener is usually created by wrapping a regular TCP listener. From there, the server either accepts connections directly or hands them off to goroutines for handling.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rwPg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3e28433-7b9a-471d-a294-4a01fc308147_1117x453.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rwPg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3e28433-7b9a-471d-a294-4a01fc308147_1117x453.png 424w, https://substackcdn.com/image/fetch/$s_!rwPg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3e28433-7b9a-471d-a294-4a01fc308147_1117x453.png 848w, https://substackcdn.com/image/fetch/$s_!rwPg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3e28433-7b9a-471d-a294-4a01fc308147_1117x453.png 1272w, https://substackcdn.com/image/fetch/$s_!rwPg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3e28433-7b9a-471d-a294-4a01fc308147_1117x453.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rwPg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3e28433-7b9a-471d-a294-4a01fc308147_1117x453.png" width="1117" height="453" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b3e28433-7b9a-471d-a294-4a01fc308147_1117x453.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:453,&quot;width&quot;:1117,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:56315,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174972862?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3e28433-7b9a-471d-a294-4a01fc308147_1117x453.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rwPg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3e28433-7b9a-471d-a294-4a01fc308147_1117x453.png 424w, https://substackcdn.com/image/fetch/$s_!rwPg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3e28433-7b9a-471d-a294-4a01fc308147_1117x453.png 848w, https://substackcdn.com/image/fetch/$s_!rwPg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3e28433-7b9a-471d-a294-4a01fc308147_1117x453.png 1272w, https://substackcdn.com/image/fetch/$s_!rwPg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb3e28433-7b9a-471d-a294-4a01fc308147_1117x453.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The moment a client connects, the server prepares to respond with its own part of the handshake.</p><h4>Server Response and Negotiation</h4><p>After receiving a client hello message, the server answers with its own hello. This response signals which protocol version and cipher suite will be used, selected from the client&#8217;s list of preferences. Go developers don&#8217;t directly write this exchange. The <code>crypto/tls</code> package handles it internally, but the configuration provided through <code>tls.Config</code> has a strong influence on the outcome.</p><p>For example, a server can restrict supported cipher suites to match security requirements:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KVUj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca3f79d-49b7-4abb-998e-0f619a0300f3_1101x313.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KVUj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca3f79d-49b7-4abb-998e-0f619a0300f3_1101x313.png 424w, https://substackcdn.com/image/fetch/$s_!KVUj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca3f79d-49b7-4abb-998e-0f619a0300f3_1101x313.png 848w, https://substackcdn.com/image/fetch/$s_!KVUj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca3f79d-49b7-4abb-998e-0f619a0300f3_1101x313.png 1272w, https://substackcdn.com/image/fetch/$s_!KVUj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca3f79d-49b7-4abb-998e-0f619a0300f3_1101x313.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KVUj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca3f79d-49b7-4abb-998e-0f619a0300f3_1101x313.png" width="1101" height="313" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6ca3f79d-49b7-4abb-998e-0f619a0300f3_1101x313.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:313,&quot;width&quot;:1101,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:66852,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174972862?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca3f79d-49b7-4abb-998e-0f619a0300f3_1101x313.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!KVUj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca3f79d-49b7-4abb-998e-0f619a0300f3_1101x313.png 424w, https://substackcdn.com/image/fetch/$s_!KVUj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca3f79d-49b7-4abb-998e-0f619a0300f3_1101x313.png 848w, https://substackcdn.com/image/fetch/$s_!KVUj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca3f79d-49b7-4abb-998e-0f619a0300f3_1101x313.png 1272w, https://substackcdn.com/image/fetch/$s_!KVUj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ca3f79d-49b7-4abb-998e-0f619a0300f3_1101x313.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This configuration only allows TLS 1.2 and 1.3. The <code>CipherSuites</code> list applies to TLS 1.2 only. TLS 1.3 cipher suites aren&#8217;t configurable in Go, so the field has no effect for TLS 1.3 connections. The final choice for TLS 1.2 comes from the overlap between client and server.</p><p>Beyond cipher suites, the server can also negotiate additional features. One option is Application Layer Protocol Negotiation, or ALPN, which lets the client and server agree on which protocol will run on top of TLS. This matters when the same port can serve both HTTP/1.1 and HTTP/2.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vZOt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e3517a1-b287-4834-909e-f53b21b981ca_1125x33.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vZOt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e3517a1-b287-4834-909e-f53b21b981ca_1125x33.png 424w, https://substackcdn.com/image/fetch/$s_!vZOt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e3517a1-b287-4834-909e-f53b21b981ca_1125x33.png 848w, https://substackcdn.com/image/fetch/$s_!vZOt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e3517a1-b287-4834-909e-f53b21b981ca_1125x33.png 1272w, https://substackcdn.com/image/fetch/$s_!vZOt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e3517a1-b287-4834-909e-f53b21b981ca_1125x33.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vZOt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e3517a1-b287-4834-909e-f53b21b981ca_1125x33.png" width="1125" height="33" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0e3517a1-b287-4834-909e-f53b21b981ca_1125x33.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:33,&quot;width&quot;:1125,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:13325,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174972862?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e3517a1-b287-4834-909e-f53b21b981ca_1125x33.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vZOt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e3517a1-b287-4834-909e-f53b21b981ca_1125x33.png 424w, https://substackcdn.com/image/fetch/$s_!vZOt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e3517a1-b287-4834-909e-f53b21b981ca_1125x33.png 848w, https://substackcdn.com/image/fetch/$s_!vZOt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e3517a1-b287-4834-909e-f53b21b981ca_1125x33.png 1272w, https://substackcdn.com/image/fetch/$s_!vZOt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e3517a1-b287-4834-909e-f53b21b981ca_1125x33.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>With that line added, the server signals it&#8217;s willing to use HTTP/2 or HTTP/1.1, and the client&#8217;s preferences decide the final outcome.</p><p>Certificates are part of the server&#8217;s reply as well. When a server is configured with <code>Certificates</code>, it sends its public certificate chain to the client. The client validates this chain against its trusted certificate authorities, checking that the names match and the signatures are valid. If the validation fails, the connection is dropped before any sensitive data is exchanged.</p><p>The negotiation phase might sound abstract, but it boils down to the client asking, &#8220;Here&#8217;s what I can do,&#8221; and the server answering, &#8220;Here&#8217;s what we&#8217;ll use together.&#8221; When both sides are satisfied, they move on to the cryptographic steps that produce the keys used for encryption.</p><h3>Steps Inside the Handshake</h3><p>After the initial exchange of hello messages, the handshake moves into the deeper work that makes TLS secure. This part is where math and cryptography shape how the session will be protected. Each stage builds on the previous one, and Go&#8217;s <code>crypto/tls</code> package makes sure the steps happen in the right order without the developer needing to manage them directly.</p><h4>Key Exchange and Shared Secrets</h4><p>The process of agreeing on shared secrets happens through a key exchange method. Modern Go versions prioritize ephemeral Diffie&#8211;Hellman over older algorithms because it provides forward secrecy. That means even if long-term private keys were somehow exposed later, past conversations would remain protected.</p><p>The handshake involves the client and server trading public values, which are then combined with each side&#8217;s private value to produce the same secret independently. This shared secret is never transmitted across the network. Go&#8217;s library automates the use of elliptic curve Diffie&#8211;Hellman ephemeral (ECDHE), which is the default for TLS 1.3 and common in TLS 1.2 as well.</p><p>Here&#8217;s a trimmed-down example that shows how you could specify preferred curves when configuring a server:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5TUh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a5b976-69da-4fe9-b932-47e5da641f8e_1105x244.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5TUh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a5b976-69da-4fe9-b932-47e5da641f8e_1105x244.png 424w, https://substackcdn.com/image/fetch/$s_!5TUh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a5b976-69da-4fe9-b932-47e5da641f8e_1105x244.png 848w, https://substackcdn.com/image/fetch/$s_!5TUh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a5b976-69da-4fe9-b932-47e5da641f8e_1105x244.png 1272w, https://substackcdn.com/image/fetch/$s_!5TUh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a5b976-69da-4fe9-b932-47e5da641f8e_1105x244.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5TUh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a5b976-69da-4fe9-b932-47e5da641f8e_1105x244.png" width="690" height="152.36199095022624" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/51a5b976-69da-4fe9-b932-47e5da641f8e_1105x244.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:244,&quot;width&quot;:1105,&quot;resizeWidth&quot;:690,&quot;bytes&quot;:37172,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174972862?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a5b976-69da-4fe9-b932-47e5da641f8e_1105x244.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5TUh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a5b976-69da-4fe9-b932-47e5da641f8e_1105x244.png 424w, https://substackcdn.com/image/fetch/$s_!5TUh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a5b976-69da-4fe9-b932-47e5da641f8e_1105x244.png 848w, https://substackcdn.com/image/fetch/$s_!5TUh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a5b976-69da-4fe9-b932-47e5da641f8e_1105x244.png 1272w, https://substackcdn.com/image/fetch/$s_!5TUh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51a5b976-69da-4fe9-b932-47e5da641f8e_1105x244.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>This limits the advertised groups to X25519 and P-256. In TLS 1.2, the list drives what the server offers. In TLS 1.3, Go uses it as an allow-list and chooses key shares internally, with X25519 commonly selected on modern stacks.</p><p>You don&#8217;t usually need to handle the math yourself, but Go&#8217;s standard library also provides access to the raw primitives if you want to explore them directly. Such as, you could use the <code>crypto/elliptic</code> package to generate a private-public pair and derive a shared secret manually.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zZ9w!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb89587f-69ef-45ef-b69d-64f617614d06_1299x173.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zZ9w!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb89587f-69ef-45ef-b69d-64f617614d06_1299x173.png 424w, https://substackcdn.com/image/fetch/$s_!zZ9w!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb89587f-69ef-45ef-b69d-64f617614d06_1299x173.png 848w, https://substackcdn.com/image/fetch/$s_!zZ9w!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb89587f-69ef-45ef-b69d-64f617614d06_1299x173.png 1272w, https://substackcdn.com/image/fetch/$s_!zZ9w!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb89587f-69ef-45ef-b69d-64f617614d06_1299x173.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zZ9w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb89587f-69ef-45ef-b69d-64f617614d06_1299x173.png" width="1299" height="173" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/db89587f-69ef-45ef-b69d-64f617614d06_1299x173.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:173,&quot;width&quot;:1299,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:38828,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174972862?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb89587f-69ef-45ef-b69d-64f617614d06_1299x173.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zZ9w!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb89587f-69ef-45ef-b69d-64f617614d06_1299x173.png 424w, https://substackcdn.com/image/fetch/$s_!zZ9w!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb89587f-69ef-45ef-b69d-64f617614d06_1299x173.png 848w, https://substackcdn.com/image/fetch/$s_!zZ9w!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb89587f-69ef-45ef-b69d-64f617614d06_1299x173.png 1272w, https://substackcdn.com/image/fetch/$s_!zZ9w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb89587f-69ef-45ef-b69d-64f617614d06_1299x173.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Although this example runs outside the handshake, it helps make sense of what the TLS engine is doing under the covers while it establishes a secure channel.</p><h4>Certificate Verification and Authentication</h4><p>After key exchange, the next stage is identity verification. The server typically sends its certificate chain to prove who it is. Clients rely on their set of trusted certificate authorities to confirm that the server&#8217;s certificate is genuine. If the certificate fails validation, the connection closes immediately. In Go, validation is handled internally, but developers can provide custom logic through the <code>VerifyPeerCertificate</code> callback. That hook can enforce stricter checks, log certificate details, or reject certificates that don&#8217;t meet specific rules.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Q4IB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc961cf2-a2bd-42c8-9cd5-31f32dffa9d8_1278x395.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Q4IB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc961cf2-a2bd-42c8-9cd5-31f32dffa9d8_1278x395.png 424w, https://substackcdn.com/image/fetch/$s_!Q4IB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc961cf2-a2bd-42c8-9cd5-31f32dffa9d8_1278x395.png 848w, https://substackcdn.com/image/fetch/$s_!Q4IB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc961cf2-a2bd-42c8-9cd5-31f32dffa9d8_1278x395.png 1272w, https://substackcdn.com/image/fetch/$s_!Q4IB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc961cf2-a2bd-42c8-9cd5-31f32dffa9d8_1278x395.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Q4IB!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc961cf2-a2bd-42c8-9cd5-31f32dffa9d8_1278x395.png" width="962" height="297.3317683881064" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bc961cf2-a2bd-42c8-9cd5-31f32dffa9d8_1278x395.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:395,&quot;width&quot;:1278,&quot;resizeWidth&quot;:962,&quot;bytes&quot;:96407,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174972862?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc961cf2-a2bd-42c8-9cd5-31f32dffa9d8_1278x395.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Q4IB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc961cf2-a2bd-42c8-9cd5-31f32dffa9d8_1278x395.png 424w, https://substackcdn.com/image/fetch/$s_!Q4IB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc961cf2-a2bd-42c8-9cd5-31f32dffa9d8_1278x395.png 848w, https://substackcdn.com/image/fetch/$s_!Q4IB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc961cf2-a2bd-42c8-9cd5-31f32dffa9d8_1278x395.png 1272w, https://substackcdn.com/image/fetch/$s_!Q4IB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc961cf2-a2bd-42c8-9cd5-31f32dffa9d8_1278x395.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This server configuration both requires client certificates and attaches a custom verifier. It means that in addition to the default chain checks, you can add your own rules, such as checking certificate extensions or matching an organization unit.</p><p>Mutual TLS extends this process by asking the client to present its own certificate. This is common in enterprise systems where both sides need to prove their identity. On the client side, configuration involves loading a certificate and private key into <code>tls.Config.Certificates</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VT_Z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf96ae43-e127-46a8-8e58-f5e4cd4c97d0_1102x312.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VT_Z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf96ae43-e127-46a8-8e58-f5e4cd4c97d0_1102x312.png 424w, https://substackcdn.com/image/fetch/$s_!VT_Z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf96ae43-e127-46a8-8e58-f5e4cd4c97d0_1102x312.png 848w, https://substackcdn.com/image/fetch/$s_!VT_Z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf96ae43-e127-46a8-8e58-f5e4cd4c97d0_1102x312.png 1272w, https://substackcdn.com/image/fetch/$s_!VT_Z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf96ae43-e127-46a8-8e58-f5e4cd4c97d0_1102x312.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VT_Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf96ae43-e127-46a8-8e58-f5e4cd4c97d0_1102x312.png" width="678" height="191.95644283121598" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bf96ae43-e127-46a8-8e58-f5e4cd4c97d0_1102x312.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:312,&quot;width&quot;:1102,&quot;resizeWidth&quot;:678,&quot;bytes&quot;:45618,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174972862?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf96ae43-e127-46a8-8e58-f5e4cd4c97d0_1102x312.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VT_Z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf96ae43-e127-46a8-8e58-f5e4cd4c97d0_1102x312.png 424w, https://substackcdn.com/image/fetch/$s_!VT_Z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf96ae43-e127-46a8-8e58-f5e4cd4c97d0_1102x312.png 848w, https://substackcdn.com/image/fetch/$s_!VT_Z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf96ae43-e127-46a8-8e58-f5e4cd4c97d0_1102x312.png 1272w, https://substackcdn.com/image/fetch/$s_!VT_Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf96ae43-e127-46a8-8e58-f5e4cd4c97d0_1102x312.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>When set, the client responds with its certificate when prompted, proving it controls the associated private key. That step prevents an attacker from impersonating a legitimate user of the system.</p><h4>Handshake Completion and Session Keys</h4><p>The final stage is where everything comes together into usable session keys. From the shared secret produced earlier, a pseudo-random function expands the value into several independent keys. These include encryption keys for both directions and integrity keys that allow each side to check the authenticity of received messages.</p><p>After the session keys are derived, both sides send a finished message. Each finished message is an encrypted hash of the entire handshake up to that point. If the hash matches, it confirms that no tampering occurred during negotiation. Go exposes the resulting state through the <code>ConnectionState</code> method on a TLS connection. Developers can check what protocol version and cipher suite were agreed upon, along with whether the handshake completed successfully.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eP5g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ac8ceb-4498-4a88-aac8-b8c9e38826ad_1154x55.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eP5g!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ac8ceb-4498-4a88-aac8-b8c9e38826ad_1154x55.png 424w, https://substackcdn.com/image/fetch/$s_!eP5g!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ac8ceb-4498-4a88-aac8-b8c9e38826ad_1154x55.png 848w, https://substackcdn.com/image/fetch/$s_!eP5g!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ac8ceb-4498-4a88-aac8-b8c9e38826ad_1154x55.png 1272w, https://substackcdn.com/image/fetch/$s_!eP5g!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ac8ceb-4498-4a88-aac8-b8c9e38826ad_1154x55.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eP5g!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ac8ceb-4498-4a88-aac8-b8c9e38826ad_1154x55.png" width="902" height="42.9896013864818" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/67ac8ceb-4498-4a88-aac8-b8c9e38826ad_1154x55.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:55,&quot;width&quot;:1154,&quot;resizeWidth&quot;:902,&quot;bytes&quot;:21012,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174972862?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ac8ceb-4498-4a88-aac8-b8c9e38826ad_1154x55.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eP5g!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ac8ceb-4498-4a88-aac8-b8c9e38826ad_1154x55.png 424w, https://substackcdn.com/image/fetch/$s_!eP5g!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ac8ceb-4498-4a88-aac8-b8c9e38826ad_1154x55.png 848w, https://substackcdn.com/image/fetch/$s_!eP5g!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ac8ceb-4498-4a88-aac8-b8c9e38826ad_1154x55.png 1272w, https://substackcdn.com/image/fetch/$s_!eP5g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ac8ceb-4498-4a88-aac8-b8c9e38826ad_1154x55.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>At this point, the channel is ready for application data. Every message sent is encrypted with the negotiated keys, and every message received is checked for integrity. From the perspective of a developer writing Go code, the connection now behaves like a normal network connection, except that confidentiality and authenticity are guaranteed by the mechanics just completed.</p><h3>Conclusion</h3><p>A TLS handshake in Go is a carefully ordered sequence where negotiation, cryptographic exchange, and certificate checks build a foundation for trust. Each step narrows the gap between two sides until they share session keys that drive encryption and integrity protection. When the handshake finishes, what began as a simple request for a secure channel has turned into a working connection managed by Go&#8217;s <code>crypto/tls</code> package, with the mechanics providing both privacy and authenticity throughout the conversation.</p><ol><li><p><em><a href="https://pkg.go.dev/crypto/tls">Go </a></em><code>crypto/tls</code><em><a href="https://pkg.go.dev/crypto/tls"> Package Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/crypto/x509">Go </a></em><code>crypto/x509</code><em><a href="https://pkg.go.dev/crypto/x509"> Package Documentation</a></em></p></li><li><p><em><a href="https://datatracker.ietf.org/doc/html/rfc8446">RFC 8446 TLS 1.3 Pecification</a></em></p></li><li><p><em><a href="https://pkg.go.dev/crypto/tls#Conn.Handshake">Go TLS Handshake State Reference</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Interface Nil Checks in Go]]></title><description><![CDATA[A common area of confusion in Go comes from how interfaces behave with nil. Many developers expect an interface set to nil to act the same as a plain nil pointer, but that assumption doesn&#8217;t hold.]]></description><link>https://alexanderobregon.substack.com/p/interface-nil-checks-in-go</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/interface-nil-checks-in-go</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Wed, 01 Oct 2025 17:20:23 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/8065b76c-e648-40d1-ab4d-60aa9fae8291_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BDcr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7efa6c8c-68f1-4d29-90fc-dacbbb983d1b_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BDcr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7efa6c8c-68f1-4d29-90fc-dacbbb983d1b_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!BDcr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7efa6c8c-68f1-4d29-90fc-dacbbb983d1b_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!BDcr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7efa6c8c-68f1-4d29-90fc-dacbbb983d1b_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!BDcr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7efa6c8c-68f1-4d29-90fc-dacbbb983d1b_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BDcr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7efa6c8c-68f1-4d29-90fc-dacbbb983d1b_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7efa6c8c-68f1-4d29-90fc-dacbbb983d1b_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BDcr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7efa6c8c-68f1-4d29-90fc-dacbbb983d1b_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!BDcr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7efa6c8c-68f1-4d29-90fc-dacbbb983d1b_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!BDcr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7efa6c8c-68f1-4d29-90fc-dacbbb983d1b_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!BDcr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7efa6c8c-68f1-4d29-90fc-dacbbb983d1b_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>A common area of confusion in Go comes from how interfaces behave with <code>nil</code>. Many developers expect an interface set to <code>nil</code> to act the same as a plain <code>nil</code> pointer, but that assumption doesn&#8217;t hold. The reason lies in the way Go stores both type and value information inside an interface.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>Mechanics of Interface Nil Checks</h3><p>Interfaces in Go are more than a placeholder for values. They keep track of two pieces of information at the same time: the type of the stored value and the value itself. This structure explains why comparing an interface to <code>nil</code> sometimes gives results that surprise developers. To see why, it helps to look at how the Go runtime arranges the pieces that make up an interface.</p><h4>How Interfaces Are Stored in Memory</h4><p>Internally, an interface has two fields. One is a reference to a type descriptor that tells the runtime what kind of value is inside. The other is a pointer to the actual data. Only when both are unset is the interface equal to <code>nil</code>. If the type descriptor has a value but the pointer does not, then the interface is still considered non-nil because it carries type information.</p><p>This can be pictured like a small structure, even though it&#8217;s hidden inside the runtime:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BRF9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa2e749b-9d76-41ca-b756-c409aa07d537_1101x141.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BRF9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa2e749b-9d76-41ca-b756-c409aa07d537_1101x141.png 424w, https://substackcdn.com/image/fetch/$s_!BRF9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa2e749b-9d76-41ca-b756-c409aa07d537_1101x141.png 848w, https://substackcdn.com/image/fetch/$s_!BRF9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa2e749b-9d76-41ca-b756-c409aa07d537_1101x141.png 1272w, https://substackcdn.com/image/fetch/$s_!BRF9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa2e749b-9d76-41ca-b756-c409aa07d537_1101x141.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BRF9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa2e749b-9d76-41ca-b756-c409aa07d537_1101x141.png" width="694" height="88.87738419618529" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aa2e749b-9d76-41ca-b756-c409aa07d537_1101x141.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:141,&quot;width&quot;:1101,&quot;resizeWidth&quot;:694,&quot;bytes&quot;:16114,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174971492?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa2e749b-9d76-41ca-b756-c409aa07d537_1101x141.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BRF9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa2e749b-9d76-41ca-b756-c409aa07d537_1101x141.png 424w, https://substackcdn.com/image/fetch/$s_!BRF9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa2e749b-9d76-41ca-b756-c409aa07d537_1101x141.png 848w, https://substackcdn.com/image/fetch/$s_!BRF9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa2e749b-9d76-41ca-b756-c409aa07d537_1101x141.png 1272w, https://substackcdn.com/image/fetch/$s_!BRF9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa2e749b-9d76-41ca-b756-c409aa07d537_1101x141.png 1456w" sizes="100vw"></picture><div></div></div></a></figure></div><p>A quick test with code shows how this works:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OlRn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffc86a30-df46-402f-a87c-425f4da6e66b_1230x348.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OlRn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffc86a30-df46-402f-a87c-425f4da6e66b_1230x348.png 424w, https://substackcdn.com/image/fetch/$s_!OlRn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffc86a30-df46-402f-a87c-425f4da6e66b_1230x348.png 848w, https://substackcdn.com/image/fetch/$s_!OlRn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffc86a30-df46-402f-a87c-425f4da6e66b_1230x348.png 1272w, https://substackcdn.com/image/fetch/$s_!OlRn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffc86a30-df46-402f-a87c-425f4da6e66b_1230x348.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OlRn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffc86a30-df46-402f-a87c-425f4da6e66b_1230x348.png" width="1230" height="348" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ffc86a30-df46-402f-a87c-425f4da6e66b_1230x348.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:348,&quot;width&quot;:1230,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:57550,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174971492?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffc86a30-df46-402f-a87c-425f4da6e66b_1230x348.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OlRn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffc86a30-df46-402f-a87c-425f4da6e66b_1230x348.png 424w, https://substackcdn.com/image/fetch/$s_!OlRn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffc86a30-df46-402f-a87c-425f4da6e66b_1230x348.png 848w, https://substackcdn.com/image/fetch/$s_!OlRn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffc86a30-df46-402f-a87c-425f4da6e66b_1230x348.png 1272w, https://substackcdn.com/image/fetch/$s_!OlRn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffc86a30-df46-402f-a87c-425f4da6e66b_1230x348.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The last print statement returns <code>false</code> because the type <code>*string</code> is stored in the interface even though the actual value is nil.</p><p>You can also print the type held inside the interface with <code>%T</code> to see what Go has stored.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cGuO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F931eece7-669f-471d-a261-0519828786fc_1126x32.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cGuO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F931eece7-669f-471d-a261-0519828786fc_1126x32.png 424w, https://substackcdn.com/image/fetch/$s_!cGuO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F931eece7-669f-471d-a261-0519828786fc_1126x32.png 848w, https://substackcdn.com/image/fetch/$s_!cGuO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F931eece7-669f-471d-a261-0519828786fc_1126x32.png 1272w, https://substackcdn.com/image/fetch/$s_!cGuO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F931eece7-669f-471d-a261-0519828786fc_1126x32.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cGuO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F931eece7-669f-471d-a261-0519828786fc_1126x32.png" width="1126" height="32" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/931eece7-669f-471d-a261-0519828786fc_1126x32.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:32,&quot;width&quot;:1126,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:9677,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174971492?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F931eece7-669f-471d-a261-0519828786fc_1126x32.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cGuO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F931eece7-669f-471d-a261-0519828786fc_1126x32.png 424w, https://substackcdn.com/image/fetch/$s_!cGuO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F931eece7-669f-471d-a261-0519828786fc_1126x32.png 848w, https://substackcdn.com/image/fetch/$s_!cGuO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F931eece7-669f-471d-a261-0519828786fc_1126x32.png 1272w, https://substackcdn.com/image/fetch/$s_!cGuO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F931eece7-669f-471d-a261-0519828786fc_1126x32.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The output confirms that <code>i</code> has a <code>*string</code> type attached. That type information is why the interface doesn&#8217;t behave like a plain <code>nil</code>.</p><h4>Why Nil Inside an Interface Is Not Always Nil</h4><p>It&#8217;s common to store a typed <code>nil</code> inside an interface and then expect a comparison to succeed. Because the type is still attached, the interface won&#8217;t evaluate as <code>nil</code>. This is one of the main ways developers run into unexpected results.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JMXH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc281e1bb-5955-49f5-a556-03923974e7d4_1108x592.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JMXH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc281e1bb-5955-49f5-a556-03923974e7d4_1108x592.png 424w, https://substackcdn.com/image/fetch/$s_!JMXH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc281e1bb-5955-49f5-a556-03923974e7d4_1108x592.png 848w, https://substackcdn.com/image/fetch/$s_!JMXH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc281e1bb-5955-49f5-a556-03923974e7d4_1108x592.png 1272w, https://substackcdn.com/image/fetch/$s_!JMXH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc281e1bb-5955-49f5-a556-03923974e7d4_1108x592.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JMXH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc281e1bb-5955-49f5-a556-03923974e7d4_1108x592.png" width="625" height="333.93501805054154" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c281e1bb-5955-49f5-a556-03923974e7d4_1108x592.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:592,&quot;width&quot;:1108,&quot;resizeWidth&quot;:625,&quot;bytes&quot;:62132,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174971492?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc281e1bb-5955-49f5-a556-03923974e7d4_1108x592.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JMXH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc281e1bb-5955-49f5-a556-03923974e7d4_1108x592.png 424w, https://substackcdn.com/image/fetch/$s_!JMXH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc281e1bb-5955-49f5-a556-03923974e7d4_1108x592.png 848w, https://substackcdn.com/image/fetch/$s_!JMXH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc281e1bb-5955-49f5-a556-03923974e7d4_1108x592.png 1272w, https://substackcdn.com/image/fetch/$s_!JMXH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc281e1bb-5955-49f5-a556-03923974e7d4_1108x592.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This prints &#8220;interface is not nil.&#8221; The function handed back a <code>nil</code> pointer of type <code>*Node</code>, but the interface holds that type, so the check fails.</p><p>The same behavior appears when returning values that are expected to be interfaces. A function may return a <code>nil</code> pointer wrapped in an interface, and the caller won&#8217;t see it as empty.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yo3s!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F318d2cd3-3016-461e-9ca3-8cb779e539ed_1110x316.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yo3s!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F318d2cd3-3016-461e-9ca3-8cb779e539ed_1110x316.png 424w, https://substackcdn.com/image/fetch/$s_!yo3s!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F318d2cd3-3016-461e-9ca3-8cb779e539ed_1110x316.png 848w, https://substackcdn.com/image/fetch/$s_!yo3s!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F318d2cd3-3016-461e-9ca3-8cb779e539ed_1110x316.png 1272w, https://substackcdn.com/image/fetch/$s_!yo3s!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F318d2cd3-3016-461e-9ca3-8cb779e539ed_1110x316.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yo3s!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F318d2cd3-3016-461e-9ca3-8cb779e539ed_1110x316.png" width="696" height="198.14054054054054" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/318d2cd3-3016-461e-9ca3-8cb779e539ed_1110x316.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:316,&quot;width&quot;:1110,&quot;resizeWidth&quot;:696,&quot;bytes&quot;:39917,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174971492?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F318d2cd3-3016-461e-9ca3-8cb779e539ed_1110x316.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yo3s!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F318d2cd3-3016-461e-9ca3-8cb779e539ed_1110x316.png 424w, https://substackcdn.com/image/fetch/$s_!yo3s!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F318d2cd3-3016-461e-9ca3-8cb779e539ed_1110x316.png 848w, https://substackcdn.com/image/fetch/$s_!yo3s!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F318d2cd3-3016-461e-9ca3-8cb779e539ed_1110x316.png 1272w, https://substackcdn.com/image/fetch/$s_!yo3s!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F318d2cd3-3016-461e-9ca3-8cb779e539ed_1110x316.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The pointer itself is <code>nil</code>, yet the interface is not, because it still has type data for <code>*int</code>.</p><h4>Proper Checks for Interface Nil</h4><p>The safe way to handle this situation is to look inside the interface and compare the stored value directly. Type assertions are the most common tool for this. They let you grab the underlying value and then check it.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oK9q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec5eac45-db71-4e56-908d-653e6a3fd4f0_1121x175.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oK9q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec5eac45-db71-4e56-908d-653e6a3fd4f0_1121x175.png 424w, https://substackcdn.com/image/fetch/$s_!oK9q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec5eac45-db71-4e56-908d-653e6a3fd4f0_1121x175.png 848w, https://substackcdn.com/image/fetch/$s_!oK9q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec5eac45-db71-4e56-908d-653e6a3fd4f0_1121x175.png 1272w, https://substackcdn.com/image/fetch/$s_!oK9q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec5eac45-db71-4e56-908d-653e6a3fd4f0_1121x175.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oK9q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec5eac45-db71-4e56-908d-653e6a3fd4f0_1121x175.png" width="718" height="112.08742194469224" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ec5eac45-db71-4e56-908d-653e6a3fd4f0_1121x175.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:175,&quot;width&quot;:1121,&quot;resizeWidth&quot;:718,&quot;bytes&quot;:33801,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174971492?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec5eac45-db71-4e56-908d-653e6a3fd4f0_1121x175.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oK9q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec5eac45-db71-4e56-908d-653e6a3fd4f0_1121x175.png 424w, https://substackcdn.com/image/fetch/$s_!oK9q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec5eac45-db71-4e56-908d-653e6a3fd4f0_1121x175.png 848w, https://substackcdn.com/image/fetch/$s_!oK9q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec5eac45-db71-4e56-908d-653e6a3fd4f0_1121x175.png 1272w, https://substackcdn.com/image/fetch/$s_!oK9q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec5eac45-db71-4e56-908d-653e6a3fd4f0_1121x175.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The type assertion confirms that the interface holds a <code>*Node</code>, and the check against <code>nil</code> verifies the pointer itself has no data.</p><h3>Practical Cases of Nil Interfaces</h3><p>The details of how interfaces hold type and value pairs become important in real projects. Developers don&#8217;t usually think about the runtime layout of interfaces while writing code, but these mechanics influence how checks against <code>nil</code> behave. A few common patterns make this behavior stand out, and they tend to appear in areas like error handling, assignments, and more advanced checking strategies.</p><h4>Returning Errors</h4><p>Errors are one of the most frequent use cases for interfaces in Go, and they&#8217;re also one of the most frequent sources of confusion with <code>nil</code>. The <code>error</code> type is an interface, so when a function returns a typed <code>nil</code> pointer as an error, the caller receives an interface that isn&#8217;t actually empty.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kRH-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7574a2f0-c7c6-4785-8abd-f82259681e33_1105x560.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kRH-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7574a2f0-c7c6-4785-8abd-f82259681e33_1105x560.png 424w, https://substackcdn.com/image/fetch/$s_!kRH-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7574a2f0-c7c6-4785-8abd-f82259681e33_1105x560.png 848w, https://substackcdn.com/image/fetch/$s_!kRH-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7574a2f0-c7c6-4785-8abd-f82259681e33_1105x560.png 1272w, https://substackcdn.com/image/fetch/$s_!kRH-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7574a2f0-c7c6-4785-8abd-f82259681e33_1105x560.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kRH-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7574a2f0-c7c6-4785-8abd-f82259681e33_1105x560.png" width="660" height="334.4796380090498" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7574a2f0-c7c6-4785-8abd-f82259681e33_1105x560.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:560,&quot;width&quot;:1105,&quot;resizeWidth&quot;:660,&quot;bytes&quot;:68787,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174971492?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7574a2f0-c7c6-4785-8abd-f82259681e33_1105x560.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kRH-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7574a2f0-c7c6-4785-8abd-f82259681e33_1105x560.png 424w, https://substackcdn.com/image/fetch/$s_!kRH-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7574a2f0-c7c6-4785-8abd-f82259681e33_1105x560.png 848w, https://substackcdn.com/image/fetch/$s_!kRH-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7574a2f0-c7c6-4785-8abd-f82259681e33_1105x560.png 1272w, https://substackcdn.com/image/fetch/$s_!kRH-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7574a2f0-c7c6-4785-8abd-f82259681e33_1105x560.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This prints &#8220;error detected&#8221; because the returned value still carries the type <code>*CustomError</code>. The interface has a non-empty type field, which means it&#8217;s not equal to <code>nil</code>.</p><p>It&#8217;s a subtle behavior that can make error handling unreliable if overlooked. To prevent it, functions should return a plain <code>nil</code> when no error occurs, instead of returning a typed <code>nil</code> pointer. A quick fix is simply returning <code>nil</code> directly rather than a typed variable set to <code>nil</code>.</p><p>A second scenario can bring the point home by mixing typed and untyped returns:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6KVc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2e77a5f-4b11-424f-9f45-1eb43a618d26_1104x454.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6KVc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2e77a5f-4b11-424f-9f45-1eb43a618d26_1104x454.png 424w, https://substackcdn.com/image/fetch/$s_!6KVc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2e77a5f-4b11-424f-9f45-1eb43a618d26_1104x454.png 848w, https://substackcdn.com/image/fetch/$s_!6KVc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2e77a5f-4b11-424f-9f45-1eb43a618d26_1104x454.png 1272w, https://substackcdn.com/image/fetch/$s_!6KVc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2e77a5f-4b11-424f-9f45-1eb43a618d26_1104x454.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6KVc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2e77a5f-4b11-424f-9f45-1eb43a618d26_1104x454.png" width="1104" height="454" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a2e77a5f-4b11-424f-9f45-1eb43a618d26_1104x454.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:454,&quot;width&quot;:1104,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:59259,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174971492?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2e77a5f-4b11-424f-9f45-1eb43a618d26_1104x454.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6KVc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2e77a5f-4b11-424f-9f45-1eb43a618d26_1104x454.png 424w, https://substackcdn.com/image/fetch/$s_!6KVc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2e77a5f-4b11-424f-9f45-1eb43a618d26_1104x454.png 848w, https://substackcdn.com/image/fetch/$s_!6KVc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2e77a5f-4b11-424f-9f45-1eb43a618d26_1104x454.png 1272w, https://substackcdn.com/image/fetch/$s_!6KVc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2e77a5f-4b11-424f-9f45-1eb43a618d26_1104x454.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Only the second comparison evaluates to true, because it returns a <code>nil</code> interface value.</p><h4>Interface Assignments</h4><p>Nil behavior can also trip up developers when assigning values into interfaces. Assigning a typed <code>nil</code> pointer into an empty interface leaves the type attached, which means the interface is not <code>nil</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_7vV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d0ff230-fc81-48e6-b1b3-0a419dd738d2_1132x135.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_7vV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d0ff230-fc81-48e6-b1b3-0a419dd738d2_1132x135.png 424w, https://substackcdn.com/image/fetch/$s_!_7vV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d0ff230-fc81-48e6-b1b3-0a419dd738d2_1132x135.png 848w, https://substackcdn.com/image/fetch/$s_!_7vV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d0ff230-fc81-48e6-b1b3-0a419dd738d2_1132x135.png 1272w, https://substackcdn.com/image/fetch/$s_!_7vV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d0ff230-fc81-48e6-b1b3-0a419dd738d2_1132x135.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_7vV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d0ff230-fc81-48e6-b1b3-0a419dd738d2_1132x135.png" width="1132" height="135" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0d0ff230-fc81-48e6-b1b3-0a419dd738d2_1132x135.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:135,&quot;width&quot;:1132,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:18480,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174971492?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d0ff230-fc81-48e6-b1b3-0a419dd738d2_1132x135.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_7vV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d0ff230-fc81-48e6-b1b3-0a419dd738d2_1132x135.png 424w, https://substackcdn.com/image/fetch/$s_!_7vV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d0ff230-fc81-48e6-b1b3-0a419dd738d2_1132x135.png 848w, https://substackcdn.com/image/fetch/$s_!_7vV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d0ff230-fc81-48e6-b1b3-0a419dd738d2_1132x135.png 1272w, https://substackcdn.com/image/fetch/$s_!_7vV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d0ff230-fc81-48e6-b1b3-0a419dd738d2_1132x135.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>That single line is enough to puzzle someone new to Go. The type descriptor inside the interface is still <code>*int</code>, so the runtime treats it as non-nil.</p><p>Assignments with slices work the same way.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!W2Rf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945e366d-6ee7-46d9-99d1-2ed40de25f68_1127x137.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!W2Rf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945e366d-6ee7-46d9-99d1-2ed40de25f68_1127x137.png 424w, https://substackcdn.com/image/fetch/$s_!W2Rf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945e366d-6ee7-46d9-99d1-2ed40de25f68_1127x137.png 848w, https://substackcdn.com/image/fetch/$s_!W2Rf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945e366d-6ee7-46d9-99d1-2ed40de25f68_1127x137.png 1272w, https://substackcdn.com/image/fetch/$s_!W2Rf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945e366d-6ee7-46d9-99d1-2ed40de25f68_1127x137.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!W2Rf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945e366d-6ee7-46d9-99d1-2ed40de25f68_1127x137.png" width="1127" height="137" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/945e366d-6ee7-46d9-99d1-2ed40de25f68_1127x137.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:137,&quot;width&quot;:1127,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:20092,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174971492?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945e366d-6ee7-46d9-99d1-2ed40de25f68_1127x137.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!W2Rf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945e366d-6ee7-46d9-99d1-2ed40de25f68_1127x137.png 424w, https://substackcdn.com/image/fetch/$s_!W2Rf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945e366d-6ee7-46d9-99d1-2ed40de25f68_1127x137.png 848w, https://substackcdn.com/image/fetch/$s_!W2Rf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945e366d-6ee7-46d9-99d1-2ed40de25f68_1127x137.png 1272w, https://substackcdn.com/image/fetch/$s_!W2Rf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F945e366d-6ee7-46d9-99d1-2ed40de25f68_1127x137.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Even though <code>s</code> has no data and prints as <code>[]</code>, the type information remains. The slice header inside the interface has a nil data pointer with zero length and capacity, and the interface still carries the <code>[]string</code> type, so the interface value isn&#8217;t nil.</p><p>You can see the distinction more clearly by comparing to an empty interface variable that was never assigned:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Bssj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86fd9e97-3d3f-484a-8e20-bc1d6127a1b5_1134x68.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Bssj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86fd9e97-3d3f-484a-8e20-bc1d6127a1b5_1134x68.png 424w, https://substackcdn.com/image/fetch/$s_!Bssj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86fd9e97-3d3f-484a-8e20-bc1d6127a1b5_1134x68.png 848w, https://substackcdn.com/image/fetch/$s_!Bssj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86fd9e97-3d3f-484a-8e20-bc1d6127a1b5_1134x68.png 1272w, https://substackcdn.com/image/fetch/$s_!Bssj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86fd9e97-3d3f-484a-8e20-bc1d6127a1b5_1134x68.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Bssj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86fd9e97-3d3f-484a-8e20-bc1d6127a1b5_1134x68.png" width="1134" height="68" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/86fd9e97-3d3f-484a-8e20-bc1d6127a1b5_1134x68.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:68,&quot;width&quot;:1134,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:16717,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174971492?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86fd9e97-3d3f-484a-8e20-bc1d6127a1b5_1134x68.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Bssj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86fd9e97-3d3f-484a-8e20-bc1d6127a1b5_1134x68.png 424w, https://substackcdn.com/image/fetch/$s_!Bssj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86fd9e97-3d3f-484a-8e20-bc1d6127a1b5_1134x68.png 848w, https://substackcdn.com/image/fetch/$s_!Bssj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86fd9e97-3d3f-484a-8e20-bc1d6127a1b5_1134x68.png 1272w, https://substackcdn.com/image/fetch/$s_!Bssj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86fd9e97-3d3f-484a-8e20-bc1d6127a1b5_1134x68.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Here, both type and value are unset, which is why the equality check works as expected.</p><h4>Practical Check Pattern</h4><p>When writing code that deals with interfaces whose contents may be <code>nil</code>, it&#8217;s often safer to check the concrete value instead of the interface directly. Type assertions are the most common tool for this.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!d96x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82428eaa-de3f-4166-96fc-4125d5543bb8_1066x210.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!d96x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82428eaa-de3f-4166-96fc-4125d5543bb8_1066x210.png 424w, https://substackcdn.com/image/fetch/$s_!d96x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82428eaa-de3f-4166-96fc-4125d5543bb8_1066x210.png 848w, https://substackcdn.com/image/fetch/$s_!d96x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82428eaa-de3f-4166-96fc-4125d5543bb8_1066x210.png 1272w, https://substackcdn.com/image/fetch/$s_!d96x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82428eaa-de3f-4166-96fc-4125d5543bb8_1066x210.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!d96x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82428eaa-de3f-4166-96fc-4125d5543bb8_1066x210.png" width="672" height="132.3827392120075" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/82428eaa-de3f-4166-96fc-4125d5543bb8_1066x210.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:210,&quot;width&quot;:1066,&quot;resizeWidth&quot;:672,&quot;bytes&quot;:34775,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174971492?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82428eaa-de3f-4166-96fc-4125d5543bb8_1066x210.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!d96x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82428eaa-de3f-4166-96fc-4125d5543bb8_1066x210.png 424w, https://substackcdn.com/image/fetch/$s_!d96x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82428eaa-de3f-4166-96fc-4125d5543bb8_1066x210.png 848w, https://substackcdn.com/image/fetch/$s_!d96x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82428eaa-de3f-4166-96fc-4125d5543bb8_1066x210.png 1272w, https://substackcdn.com/image/fetch/$s_!d96x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82428eaa-de3f-4166-96fc-4125d5543bb8_1066x210.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The type assertion unwraps the interface and makes the pointer check accurate. Without it, the direct <code>i == nil</code> comparison would fail.</p><p>For generic checks where the type isn&#8217;t known ahead of time, reflection can help.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Vm6W!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3261c9c2-3742-42cc-859b-c810a9399f08_1111x454.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Vm6W!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3261c9c2-3742-42cc-859b-c810a9399f08_1111x454.png 424w, https://substackcdn.com/image/fetch/$s_!Vm6W!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3261c9c2-3742-42cc-859b-c810a9399f08_1111x454.png 848w, https://substackcdn.com/image/fetch/$s_!Vm6W!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3261c9c2-3742-42cc-859b-c810a9399f08_1111x454.png 1272w, https://substackcdn.com/image/fetch/$s_!Vm6W!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3261c9c2-3742-42cc-859b-c810a9399f08_1111x454.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Vm6W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3261c9c2-3742-42cc-859b-c810a9399f08_1111x454.png" width="669" height="273.3807380738074" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3261c9c2-3742-42cc-859b-c810a9399f08_1111x454.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:454,&quot;width&quot;:1111,&quot;resizeWidth&quot;:669,&quot;bytes&quot;:51324,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174971492?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3261c9c2-3742-42cc-859b-c810a9399f08_1111x454.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Vm6W!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3261c9c2-3742-42cc-859b-c810a9399f08_1111x454.png 424w, https://substackcdn.com/image/fetch/$s_!Vm6W!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3261c9c2-3742-42cc-859b-c810a9399f08_1111x454.png 848w, https://substackcdn.com/image/fetch/$s_!Vm6W!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3261c9c2-3742-42cc-859b-c810a9399f08_1111x454.png 1272w, https://substackcdn.com/image/fetch/$s_!Vm6W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3261c9c2-3742-42cc-859b-c810a9399f08_1111x454.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Reflection allows the runtime to confirm whether the stored value is nil, even if the exact type isn&#8217;t known when writing the code. This isn&#8217;t as fast as a type assertion, but it&#8217;s flexible for situations where the type can vary.</p><h3>Conclusion</h3><p>Interfaces in Go carry both type information and a value pointer, which is why a check against <code>nil</code> can behave in unexpected ways. When only the value is nil but the type is still attached, the interface won&#8217;t compare as empty. The safest way to handle these cases is to look at the underlying value through a type assertion or reflection, which makes it clear whether the interface is truly empty or holds a typed nil.</p><ol><li><p><em><a href="https://go.dev/ref/spec#Interface_types">Go Language Specification on Interfaces</a></em></p></li><li><p><em><a href="https://go.dev/blog/errors-are-values">Go Blog on Errors are Values</a></em></p></li><li><p><em><a href="https://pkg.go.dev/reflect">reflect Package Documentation</a></em></p></li><li><p><em><a href="https://go.dev/doc/faq#nil_error">Go FAQ on nil and interfaces</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Channel Capacity Limits in Go]]></title><description><![CDATA[Channels in Go let goroutines pass data back and forth without locking.]]></description><link>https://alexanderobregon.substack.com/p/channel-capacity-limits-in-go</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/channel-capacity-limits-in-go</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Fri, 26 Sep 2025 17:16:17 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/cb17a3bc-95e2-449c-b7d0-7e6a1ddf8df4_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Gu7J!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa19124b-ff11-4a1e-b9b5-dd1bf2b81ad6_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Gu7J!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa19124b-ff11-4a1e-b9b5-dd1bf2b81ad6_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!Gu7J!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa19124b-ff11-4a1e-b9b5-dd1bf2b81ad6_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!Gu7J!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa19124b-ff11-4a1e-b9b5-dd1bf2b81ad6_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!Gu7J!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa19124b-ff11-4a1e-b9b5-dd1bf2b81ad6_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Gu7J!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa19124b-ff11-4a1e-b9b5-dd1bf2b81ad6_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fa19124b-ff11-4a1e-b9b5-dd1bf2b81ad6_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Gu7J!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa19124b-ff11-4a1e-b9b5-dd1bf2b81ad6_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!Gu7J!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa19124b-ff11-4a1e-b9b5-dd1bf2b81ad6_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!Gu7J!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa19124b-ff11-4a1e-b9b5-dd1bf2b81ad6_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!Gu7J!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa19124b-ff11-4a1e-b9b5-dd1bf2b81ad6_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>Channels in Go let goroutines pass data back and forth without locking. They form a foundation for concurrency because they give a structured way for values to move between different routines while keeping synchronization handled by the language. Capacity has a bigger effect than many realize. It changes how the runtime schedules work, how blocking is applied, and how memory buffers are managed under load.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>Mechanics of Channel Capacity</h3><p>Channel capacity is a fixed property that controls how many values can sit in a queue between a sender and a receiver. The number is decided at the moment the channel is created, and from that point forward the Go runtime treats it as a hard boundary. No resizing happens in the background, and no adjustment occurs later on. Because of this, channel behavior is highly predictable, and the effects of choosing a certain capacity are felt immediately in how goroutines interact with one another.</p><p>Capacity also affects how memory is allocated. When a buffered channel is created, a block of memory is reserved upfront to hold the exact number of slots requested. Each slot is set aside for a single value of the channel&#8217;s element type. Those slots are then managed in a way that feels invisible to the developer but is carefully tracked by the runtime.</p><h4>Unbuffered Behavior</h4><p>An unbuffered channel has a capacity of zero, which means it can&#8217;t hold values. Every send operation waits for a receiver, and every receive waits for a sender. Both sides must arrive at the channel around the same time to complete the transfer. This forces direct synchronization between goroutines, making unbuffered channels useful when you want to guarantee that a value is acted on immediately.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jvFE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1339085c-55cf-4ef4-b80a-0ec931fb56fc_1061x702.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jvFE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1339085c-55cf-4ef4-b80a-0ec931fb56fc_1061x702.png 424w, https://substackcdn.com/image/fetch/$s_!jvFE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1339085c-55cf-4ef4-b80a-0ec931fb56fc_1061x702.png 848w, https://substackcdn.com/image/fetch/$s_!jvFE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1339085c-55cf-4ef4-b80a-0ec931fb56fc_1061x702.png 1272w, https://substackcdn.com/image/fetch/$s_!jvFE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1339085c-55cf-4ef4-b80a-0ec931fb56fc_1061x702.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jvFE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1339085c-55cf-4ef4-b80a-0ec931fb56fc_1061x702.png" width="620" height="410.2167766258247" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1339085c-55cf-4ef4-b80a-0ec931fb56fc_1061x702.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:702,&quot;width&quot;:1061,&quot;resizeWidth&quot;:620,&quot;bytes&quot;:81988,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174384912?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1339085c-55cf-4ef4-b80a-0ec931fb56fc_1061x702.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jvFE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1339085c-55cf-4ef4-b80a-0ec931fb56fc_1061x702.png 424w, https://substackcdn.com/image/fetch/$s_!jvFE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1339085c-55cf-4ef4-b80a-0ec931fb56fc_1061x702.png 848w, https://substackcdn.com/image/fetch/$s_!jvFE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1339085c-55cf-4ef4-b80a-0ec931fb56fc_1061x702.png 1272w, https://substackcdn.com/image/fetch/$s_!jvFE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1339085c-55cf-4ef4-b80a-0ec931fb56fc_1061x702.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The sender in this example halts at <code>ch &lt;- &#8220;ready&#8221;</code> until the receiver pulls the value. Nothing moves until both are present. This kind of tight coordination makes sure that no values are ever queued, but it also means a slow receiver will stall the sender entirely.</p><p>Unbuffered channels are often used when ordering is just as important as delivery, since they guarantee that both goroutines are synchronized at each transfer point.</p><h4>Buffered Behavior</h4><p>Buffered channels change the picture. When capacity is greater than zero, the runtime creates a ring buffer in memory to hold values until they&#8217;re received. Senders can place values into the buffer until it fills, at which point further sends wait until space is freed. Receivers can read values at their own pace, as long as the buffer contains data.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eGO-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4bcdf39-76f7-4ba3-be7c-bb2b3883147b_1060x527.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eGO-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4bcdf39-76f7-4ba3-be7c-bb2b3883147b_1060x527.png 424w, https://substackcdn.com/image/fetch/$s_!eGO-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4bcdf39-76f7-4ba3-be7c-bb2b3883147b_1060x527.png 848w, https://substackcdn.com/image/fetch/$s_!eGO-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4bcdf39-76f7-4ba3-be7c-bb2b3883147b_1060x527.png 1272w, https://substackcdn.com/image/fetch/$s_!eGO-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4bcdf39-76f7-4ba3-be7c-bb2b3883147b_1060x527.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eGO-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4bcdf39-76f7-4ba3-be7c-bb2b3883147b_1060x527.png" width="636" height="316.2" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b4bcdf39-76f7-4ba3-be7c-bb2b3883147b_1060x527.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:527,&quot;width&quot;:1060,&quot;resizeWidth&quot;:636,&quot;bytes&quot;:43002,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174384912?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4bcdf39-76f7-4ba3-be7c-bb2b3883147b_1060x527.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eGO-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4bcdf39-76f7-4ba3-be7c-bb2b3883147b_1060x527.png 424w, https://substackcdn.com/image/fetch/$s_!eGO-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4bcdf39-76f7-4ba3-be7c-bb2b3883147b_1060x527.png 848w, https://substackcdn.com/image/fetch/$s_!eGO-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4bcdf39-76f7-4ba3-be7c-bb2b3883147b_1060x527.png 1272w, https://substackcdn.com/image/fetch/$s_!eGO-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4bcdf39-76f7-4ba3-be7c-bb2b3883147b_1060x527.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This channel has room for three integers. All three sends complete without blocking, because the buffer has space for them. Whenthe buffer is full, any additional send would wait until a receive call made room.</p><p>To see blocking in action, the code can be adjusted so the receiver runs more slowly than the sender:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HhyD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d06f-0a97-45f4-abd6-41c306944228_1198x833.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HhyD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d06f-0a97-45f4-abd6-41c306944228_1198x833.png 424w, https://substackcdn.com/image/fetch/$s_!HhyD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d06f-0a97-45f4-abd6-41c306944228_1198x833.png 848w, https://substackcdn.com/image/fetch/$s_!HhyD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d06f-0a97-45f4-abd6-41c306944228_1198x833.png 1272w, https://substackcdn.com/image/fetch/$s_!HhyD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d06f-0a97-45f4-abd6-41c306944228_1198x833.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HhyD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d06f-0a97-45f4-abd6-41c306944228_1198x833.png" width="1198" height="833" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7bd2d06f-0a97-45f4-abd6-41c306944228_1198x833.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:833,&quot;width&quot;:1198,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:104088,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174384912?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d06f-0a97-45f4-abd6-41c306944228_1198x833.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HhyD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d06f-0a97-45f4-abd6-41c306944228_1198x833.png 424w, https://substackcdn.com/image/fetch/$s_!HhyD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d06f-0a97-45f4-abd6-41c306944228_1198x833.png 848w, https://substackcdn.com/image/fetch/$s_!HhyD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d06f-0a97-45f4-abd6-41c306944228_1198x833.png 1272w, https://substackcdn.com/image/fetch/$s_!HhyD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bd2d06f-0a97-45f4-abd6-41c306944228_1198x833.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Now the sender quickly fills the buffer, but then pauses until the receiver consumes a value. This rhythm between fast producers and slower consumers is a direct effect of buffer size, and it shows how capacity helps regulate flow.</p><h4>Internal Data Structures</h4><p>The Go runtime represents each channel with a structure called <code>hchan</code>, which lives in the runtime package. It contains bookkeeping fields such as the buffer pointer, the size of each element, the capacity, the current count of elements, and positions for the head and tail of the queue. It also holds lists of goroutines that are waiting to send or receive.</p><p>Although developers don&#8217;t interact with <code>hchan</code> directly, understanding that it exists helps explain the mechanics. Every send or receive operation updates those internal fields under locks to prevent data races. When a sender pushes a value into a buffered channel, the runtime writes it to the memory location at the tail index, increments the count, and then moves the tail forward. Receivers do the opposite, pulling from the head index and moving it forward. Both head and tail wrap around to form a circular buffer once they reach the end.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Wea2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc7aa983-6975-48e6-8578-69789cb88148_1094x701.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Wea2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc7aa983-6975-48e6-8578-69789cb88148_1094x701.png 424w, https://substackcdn.com/image/fetch/$s_!Wea2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc7aa983-6975-48e6-8578-69789cb88148_1094x701.png 848w, https://substackcdn.com/image/fetch/$s_!Wea2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc7aa983-6975-48e6-8578-69789cb88148_1094x701.png 1272w, https://substackcdn.com/image/fetch/$s_!Wea2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc7aa983-6975-48e6-8578-69789cb88148_1094x701.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Wea2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc7aa983-6975-48e6-8578-69789cb88148_1094x701.png" width="1094" height="701" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dc7aa983-6975-48e6-8578-69789cb88148_1094x701.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:701,&quot;width&quot;:1094,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:97105,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174384912?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc7aa983-6975-48e6-8578-69789cb88148_1094x701.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Wea2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc7aa983-6975-48e6-8578-69789cb88148_1094x701.png 424w, https://substackcdn.com/image/fetch/$s_!Wea2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc7aa983-6975-48e6-8578-69789cb88148_1094x701.png 848w, https://substackcdn.com/image/fetch/$s_!Wea2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc7aa983-6975-48e6-8578-69789cb88148_1094x701.png 1272w, https://substackcdn.com/image/fetch/$s_!Wea2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc7aa983-6975-48e6-8578-69789cb88148_1094x701.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This isn&#8217;t Go&#8217;s actual implementation, but it captures the idea of how values are tracked with head and tail pointers. The real runtime logic is more complex, since it has to deal with goroutine scheduling and memory safety, but the circular movement of head and tail makes the constant capacity possible without shifting data around in memory. I think it&#8217;s important to see this visually, even if it&#8217;s only a conceptual model, because the picture of a ring that fills up and wraps around helps make sense of why channels have a fixed size and how data flows through them.</p><p>Queues of waiting senders and receivers are also linked to the channel structure. Each goroutine that blocks on a send or receive is placed in one of these queues. When the channel state changes, the runtime checks those queues to wake the appropriate goroutines. This is how channels coordinate synchronization beyond just the ring buffer.</p><h3>What Happens When Buffers Fill</h3><p>A buffered channel feels smooth while values fit inside its capacity, but once the buffer reaches its maximum size the behavior changes. The Go runtime applies natural backpressure, which stops senders from racing ahead and forces receivers to catch up. This change is not hidden or delayed. It happens the moment the last slot is filled, and it directly affects which goroutines are allowed to run.</p><h4>Send Blocking</h4><p>When a sender encounters a full buffer, it doesn&#8217;t push values any further. The goroutine stops and is placed into a waiting list linked to that channel. Parking the goroutine means it is suspended by the scheduler and won&#8217;t run again until space in the channel opens. This gives Go a way to coordinate throughput without needing manual locks in user code.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rQso!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96a35f0f-0751-424b-949f-a6da1ce10d4d_1111x839.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rQso!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96a35f0f-0751-424b-949f-a6da1ce10d4d_1111x839.png 424w, https://substackcdn.com/image/fetch/$s_!rQso!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96a35f0f-0751-424b-949f-a6da1ce10d4d_1111x839.png 848w, https://substackcdn.com/image/fetch/$s_!rQso!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96a35f0f-0751-424b-949f-a6da1ce10d4d_1111x839.png 1272w, https://substackcdn.com/image/fetch/$s_!rQso!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96a35f0f-0751-424b-949f-a6da1ce10d4d_1111x839.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rQso!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96a35f0f-0751-424b-949f-a6da1ce10d4d_1111x839.png" width="673" height="508.23312331233126" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/96a35f0f-0751-424b-949f-a6da1ce10d4d_1111x839.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:839,&quot;width&quot;:1111,&quot;resizeWidth&quot;:673,&quot;bytes&quot;:86369,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174384912?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96a35f0f-0751-424b-949f-a6da1ce10d4d_1111x839.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rQso!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96a35f0f-0751-424b-949f-a6da1ce10d4d_1111x839.png 424w, https://substackcdn.com/image/fetch/$s_!rQso!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96a35f0f-0751-424b-949f-a6da1ce10d4d_1111x839.png 848w, https://substackcdn.com/image/fetch/$s_!rQso!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96a35f0f-0751-424b-949f-a6da1ce10d4d_1111x839.png 1272w, https://substackcdn.com/image/fetch/$s_!rQso!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96a35f0f-0751-424b-949f-a6da1ce10d4d_1111x839.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The goroutine sending values here will stop as soon as two numbers are in the channel. It won&#8217;t resume until the main function begins draining the buffer. That pause is the runtime&#8217;s enforcement of capacity.</p><p>A second example shows multiple senders lined up on the same channel.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KDE0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf367f18-3f4a-403d-b58c-19e1fda93cec_1103x663.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KDE0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf367f18-3f4a-403d-b58c-19e1fda93cec_1103x663.png 424w, https://substackcdn.com/image/fetch/$s_!KDE0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf367f18-3f4a-403d-b58c-19e1fda93cec_1103x663.png 848w, https://substackcdn.com/image/fetch/$s_!KDE0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf367f18-3f4a-403d-b58c-19e1fda93cec_1103x663.png 1272w, https://substackcdn.com/image/fetch/$s_!KDE0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf367f18-3f4a-403d-b58c-19e1fda93cec_1103x663.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KDE0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf367f18-3f4a-403d-b58c-19e1fda93cec_1103x663.png" width="669" height="402.1278331822303" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/df367f18-3f4a-403d-b58c-19e1fda93cec_1103x663.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:663,&quot;width&quot;:1103,&quot;resizeWidth&quot;:669,&quot;bytes&quot;:74841,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174384912?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf367f18-3f4a-403d-b58c-19e1fda93cec_1103x663.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!KDE0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf367f18-3f4a-403d-b58c-19e1fda93cec_1103x663.png 424w, https://substackcdn.com/image/fetch/$s_!KDE0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf367f18-3f4a-403d-b58c-19e1fda93cec_1103x663.png 848w, https://substackcdn.com/image/fetch/$s_!KDE0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf367f18-3f4a-403d-b58c-19e1fda93cec_1103x663.png 1272w, https://substackcdn.com/image/fetch/$s_!KDE0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf367f18-3f4a-403d-b58c-19e1fda93cec_1103x663.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Only one value fits in the buffer, so all but the first sender will block until the receiver takes the slot. This queuing effect is a direct outcome of fixed capacity.</p><h4>Receive Blocking</h4><p>The opposite happens when a receiver tries to pull from an empty channel. If no sender is ready, the receiver is suspended and waits for data. This behavior makes channel reads predictable, because a receive either returns a value that was already buffered or halts until a sender provides one.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!b_AI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5a31d5-edd3-42ea-8844-767ba6820013_1054x665.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!b_AI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5a31d5-edd3-42ea-8844-767ba6820013_1054x665.png 424w, https://substackcdn.com/image/fetch/$s_!b_AI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5a31d5-edd3-42ea-8844-767ba6820013_1054x665.png 848w, https://substackcdn.com/image/fetch/$s_!b_AI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5a31d5-edd3-42ea-8844-767ba6820013_1054x665.png 1272w, https://substackcdn.com/image/fetch/$s_!b_AI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5a31d5-edd3-42ea-8844-767ba6820013_1054x665.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!b_AI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5a31d5-edd3-42ea-8844-767ba6820013_1054x665.png" width="608" height="383.60531309297915" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dc5a31d5-edd3-42ea-8844-767ba6820013_1054x665.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:665,&quot;width&quot;:1054,&quot;resizeWidth&quot;:608,&quot;bytes&quot;:64986,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174384912?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5a31d5-edd3-42ea-8844-767ba6820013_1054x665.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!b_AI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5a31d5-edd3-42ea-8844-767ba6820013_1054x665.png 424w, https://substackcdn.com/image/fetch/$s_!b_AI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5a31d5-edd3-42ea-8844-767ba6820013_1054x665.png 848w, https://substackcdn.com/image/fetch/$s_!b_AI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5a31d5-edd3-42ea-8844-767ba6820013_1054x665.png 1272w, https://substackcdn.com/image/fetch/$s_!b_AI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc5a31d5-edd3-42ea-8844-767ba6820013_1054x665.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The message prints right away, but the line pulling from the channel won&#8217;t complete until the goroutine sends the number two seconds later. Receivers don&#8217;t burn CPU while waiting, they simply yield until a sender wakes them up.</p><p>This waiting mechanism is what allows large systems with many idle receivers to scale without wasting resources.</p><h4>Fairness in Scheduling</h4><p>Go tries to avoid favoring one side of a channel over the other. If a value is sent while a receiver is already waiting, the runtime skips the buffer and hands the value directly to the waiting goroutine. This avoids extra memory operations and makes the transfer immediate. The same shortcut works in reverse when senders are blocked and a receiver arrives.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-EfD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fad27ad-ebba-468d-aa24-12a9024e2c80_1117x559.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-EfD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fad27ad-ebba-468d-aa24-12a9024e2c80_1117x559.png 424w, https://substackcdn.com/image/fetch/$s_!-EfD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fad27ad-ebba-468d-aa24-12a9024e2c80_1117x559.png 848w, https://substackcdn.com/image/fetch/$s_!-EfD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fad27ad-ebba-468d-aa24-12a9024e2c80_1117x559.png 1272w, https://substackcdn.com/image/fetch/$s_!-EfD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fad27ad-ebba-468d-aa24-12a9024e2c80_1117x559.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-EfD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fad27ad-ebba-468d-aa24-12a9024e2c80_1117x559.png" width="630" height="315.2820053715309" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5fad27ad-ebba-468d-aa24-12a9024e2c80_1117x559.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:559,&quot;width&quot;:1117,&quot;resizeWidth&quot;:630,&quot;bytes&quot;:63111,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174384912?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fad27ad-ebba-468d-aa24-12a9024e2c80_1117x559.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-EfD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fad27ad-ebba-468d-aa24-12a9024e2c80_1117x559.png 424w, https://substackcdn.com/image/fetch/$s_!-EfD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fad27ad-ebba-468d-aa24-12a9024e2c80_1117x559.png 848w, https://substackcdn.com/image/fetch/$s_!-EfD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fad27ad-ebba-468d-aa24-12a9024e2c80_1117x559.png 1272w, https://substackcdn.com/image/fetch/$s_!-EfD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5fad27ad-ebba-468d-aa24-12a9024e2c80_1117x559.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This code doesn&#8217;t rely on buffering at all, but it shows the direct handoff in action. Both goroutines sync up on the channel, and the runtime connects them without touching any queue.</p><p>In more complex workloads where many senders and receivers are waiting, the runtime walks through its lists to give waiting goroutines their turn. The goal is to keep transfers balanced without letting one side starve the other.</p><h4>Closing Channels</h4><p>Closing a channel changes how both senders and receivers behave. After a channel is marked closed, no new sends are accepted. Any goroutine trying to send into a closed channel will panic immediately. Receivers, however, can continue draining any values still in the buffer. After the buffer is empty, a receive call returns the zero value of the element type along with a flag showing the channel is closed.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wadD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c884565-48c5-4862-a884-d887693075f3_1116x663.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wadD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c884565-48c5-4862-a884-d887693075f3_1116x663.png 424w, https://substackcdn.com/image/fetch/$s_!wadD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c884565-48c5-4862-a884-d887693075f3_1116x663.png 848w, https://substackcdn.com/image/fetch/$s_!wadD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c884565-48c5-4862-a884-d887693075f3_1116x663.png 1272w, https://substackcdn.com/image/fetch/$s_!wadD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c884565-48c5-4862-a884-d887693075f3_1116x663.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wadD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c884565-48c5-4862-a884-d887693075f3_1116x663.png" width="627" height="372.491935483871" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c884565-48c5-4862-a884-d887693075f3_1116x663.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:663,&quot;width&quot;:1116,&quot;resizeWidth&quot;:627,&quot;bytes&quot;:60581,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174384912?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c884565-48c5-4862-a884-d887693075f3_1116x663.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wadD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c884565-48c5-4862-a884-d887693075f3_1116x663.png 424w, https://substackcdn.com/image/fetch/$s_!wadD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c884565-48c5-4862-a884-d887693075f3_1116x663.png 848w, https://substackcdn.com/image/fetch/$s_!wadD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c884565-48c5-4862-a884-d887693075f3_1116x663.png 1272w, https://substackcdn.com/image/fetch/$s_!wadD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c884565-48c5-4862-a884-d887693075f3_1116x663.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The loop here drains both values that were in the buffer before the channel was closed. After that, the <code>ok</code> flag signals that no further values will arrive.</p><p>This mix of draining existing data and then returning zero values is handled entirely by the runtime&#8217;s channel bookkeeping. It prevents goroutines from hanging forever on a closed channel while still allowing buffered values to be processed.</p><h3>Conclusion</h3><p>Channel capacity in Go defines how the runtime manages storage, blocking, and scheduling around message passing. Every send and receive is tied to the fixed size set at creation, which drives how goroutines line up, pause, and resume. From unbuffered channels that enforce direct synchronization to buffered ones that hold values in a ring, the mechanics are predictable and consistent.</p><ol><li><p><em><a href="https://go.dev/ref/spec#Channel_types">Go Language Specification on Channels</a></em></p></li><li><p><em><a href="https://go.dev/blog/pipelines">Go Blog on Concurrency Patterns</a></em></p></li><li><p><em><a href="https://go.dev/doc/effective_go#channels">Go Package Documentation for Channels</a></em></p></li><li><p><em><a href="https://github.com/golang/go/blob/master/src/runtime/chan.go">Go Runtime Source Code for Channels (</a></em><code>chan.go</code><em><a href="https://github.com/golang/go/blob/master/src/runtime/chan.go">)</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Scheduler Latency in Go Runtime]]></title><description><![CDATA[Most Go applications depend on goroutines to run work in parallel.]]></description><link>https://alexanderobregon.substack.com/p/scheduler-latency-in-go-runtime</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/scheduler-latency-in-go-runtime</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Wed, 24 Sep 2025 17:23:26 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/81c362b9-90fc-4976-9d0b-e5bf5f45447d_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FhZa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1f565ba-333b-4195-a628-126ec1a4d0b7_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FhZa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1f565ba-333b-4195-a628-126ec1a4d0b7_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!FhZa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1f565ba-333b-4195-a628-126ec1a4d0b7_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!FhZa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1f565ba-333b-4195-a628-126ec1a4d0b7_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!FhZa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1f565ba-333b-4195-a628-126ec1a4d0b7_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FhZa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1f565ba-333b-4195-a628-126ec1a4d0b7_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c1f565ba-333b-4195-a628-126ec1a4d0b7_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FhZa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1f565ba-333b-4195-a628-126ec1a4d0b7_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!FhZa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1f565ba-333b-4195-a628-126ec1a4d0b7_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!FhZa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1f565ba-333b-4195-a628-126ec1a4d0b7_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!FhZa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1f565ba-333b-4195-a628-126ec1a4d0b7_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>Most Go applications depend on goroutines to run work in parallel. A scheduler manages when each goroutine gets time on available threads, making sure they don&#8217;t all compete at once. The delay involved in handing control from one goroutine to another, or in responding when a goroutine becomes ready to run, is known as scheduler latency. That delay affects how responsive an application feels under load and how smoothly goroutines keep moving forward.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>How the Go Scheduler Operates</h3><p>The scheduler in Go is the piece that makes goroutines practical at scale. It decides how many lightweight execution units can move forward at a time, how they share threads, and how blocked work gets handled. What makes this system unique is that Go can run massive numbers of goroutines without overwhelming the operating system, thanks to how scheduling maps them onto a smaller set of threads.</p><h4>Goroutines and Threads</h4><p>A goroutine starts when you use the <code>go</code> keyword, but what happens behind that call is more than just spinning up an operating system thread. A new goroutine begins with a small stack, typically only a few kilobytes, and that stack can expand as it grows deeper into function calls. This dynamic growth is part of why so many goroutines can exist in memory at once without consuming the resources that thousands of threads would require.</p><p>Operating system threads still do the real work, but Go uses them more like reusable carriers. The runtime maintains a pool of threads and assigns goroutines to them when it&#8217;s their turn to run. Threads carry execution while goroutines are lightweight descriptions of what to run. That distinction makes goroutines cheap to create and tear down.</p><p>You can see the difference between goroutines and threads with a quick code sample:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6-xR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F748a2f5f-41cf-482c-a539-1fd93877b2e1_1198x786.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6-xR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F748a2f5f-41cf-482c-a539-1fd93877b2e1_1198x786.png 424w, https://substackcdn.com/image/fetch/$s_!6-xR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F748a2f5f-41cf-482c-a539-1fd93877b2e1_1198x786.png 848w, https://substackcdn.com/image/fetch/$s_!6-xR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F748a2f5f-41cf-482c-a539-1fd93877b2e1_1198x786.png 1272w, https://substackcdn.com/image/fetch/$s_!6-xR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F748a2f5f-41cf-482c-a539-1fd93877b2e1_1198x786.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6-xR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F748a2f5f-41cf-482c-a539-1fd93877b2e1_1198x786.png" width="1198" height="786" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/748a2f5f-41cf-482c-a539-1fd93877b2e1_1198x786.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:786,&quot;width&quot;:1198,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:93316,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174383863?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F748a2f5f-41cf-482c-a539-1fd93877b2e1_1198x786.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6-xR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F748a2f5f-41cf-482c-a539-1fd93877b2e1_1198x786.png 424w, https://substackcdn.com/image/fetch/$s_!6-xR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F748a2f5f-41cf-482c-a539-1fd93877b2e1_1198x786.png 848w, https://substackcdn.com/image/fetch/$s_!6-xR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F748a2f5f-41cf-482c-a539-1fd93877b2e1_1198x786.png 1272w, https://substackcdn.com/image/fetch/$s_!6-xR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F748a2f5f-41cf-482c-a539-1fd93877b2e1_1198x786.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This code launches several goroutines but prints only the number of logical processors, not the number of goroutines. The runtime schedules many goroutines across a limited number of logical processors (<code>P</code>). It may create more operating system threads as needed, but at most <code>GOMAXPROCS</code> threads run Go code at once.</p><h4>Work Stealing and Load Balancing</h4><p>Each logical processor, represented internally as P, keeps its own run queue of goroutines ready to execute. That design avoids constant contention over a single global queue. Instead, each P can pick from its own list and keep threads busy. When one P runs out of goroutines, the runtime doesn&#8217;t leave it idle. It reaches into another P&#8217;s queue and steals some work to keep things balanced. Work stealing is a common strategy in concurrent runtimes, but in Go it&#8217;s tuned for small, fast switches between goroutines.</p><p>Here&#8217;s a small example that puts stress on work distribution.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!W4Ja!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6bdb7d9-0279-482c-afd5-1dc63bac5abb_1139x783.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!W4Ja!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6bdb7d9-0279-482c-afd5-1dc63bac5abb_1139x783.png 424w, https://substackcdn.com/image/fetch/$s_!W4Ja!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6bdb7d9-0279-482c-afd5-1dc63bac5abb_1139x783.png 848w, https://substackcdn.com/image/fetch/$s_!W4Ja!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6bdb7d9-0279-482c-afd5-1dc63bac5abb_1139x783.png 1272w, https://substackcdn.com/image/fetch/$s_!W4Ja!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6bdb7d9-0279-482c-afd5-1dc63bac5abb_1139x783.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!W4Ja!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6bdb7d9-0279-482c-afd5-1dc63bac5abb_1139x783.png" width="1139" height="783" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b6bdb7d9-0279-482c-afd5-1dc63bac5abb_1139x783.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:783,&quot;width&quot;:1139,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:85802,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174383863?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6bdb7d9-0279-482c-afd5-1dc63bac5abb_1139x783.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!W4Ja!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6bdb7d9-0279-482c-afd5-1dc63bac5abb_1139x783.png 424w, https://substackcdn.com/image/fetch/$s_!W4Ja!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6bdb7d9-0279-482c-afd5-1dc63bac5abb_1139x783.png 848w, https://substackcdn.com/image/fetch/$s_!W4Ja!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6bdb7d9-0279-482c-afd5-1dc63bac5abb_1139x783.png 1272w, https://substackcdn.com/image/fetch/$s_!W4Ja!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6bdb7d9-0279-482c-afd5-1dc63bac5abb_1139x783.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This runs twelve heavy loops, usually on machines with fewer logical processors. The scheduler spreads them out, stealing from busy queues to keep all available processors active. Without that stealing step, some processors would stay idle while others handle a backlog.</p><p>Sometimes you&#8217;ll also see the runtime shift work when goroutines block, which blends into how system calls are managed. That keeps latency low but adds complexity to scheduling decisions.</p><h4>System Calls and Blocking</h4><p>Blocking calls are an unavoidable part of real applications, whether it&#8217;s reading from disk, writing to a socket, or waiting on an external API. When a goroutine performs one of these actions, the thread it runs on can&#8217;t be used by anything else until the call finishes. If nothing were done, a single blocked call could reduce the amount of parallel work the runtime can do.</p><p>The scheduler detects when a goroutine blocks in a system call. The thread that entered the call can stay blocked, and its processor slot (<code>P</code>) is handed to another thread so runnable goroutines keep making progress. When the call returns, the goroutine is placed back on a run queue.</p><p>Here&#8217;s a simple case that reflects blocking in action:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nu2D!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed10a40-f6a1-4d59-8858-74f49d34a0bf_949x835.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nu2D!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed10a40-f6a1-4d59-8858-74f49d34a0bf_949x835.png 424w, https://substackcdn.com/image/fetch/$s_!nu2D!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed10a40-f6a1-4d59-8858-74f49d34a0bf_949x835.png 848w, https://substackcdn.com/image/fetch/$s_!nu2D!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed10a40-f6a1-4d59-8858-74f49d34a0bf_949x835.png 1272w, https://substackcdn.com/image/fetch/$s_!nu2D!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed10a40-f6a1-4d59-8858-74f49d34a0bf_949x835.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nu2D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed10a40-f6a1-4d59-8858-74f49d34a0bf_949x835.png" width="949" height="835" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5ed10a40-f6a1-4d59-8858-74f49d34a0bf_949x835.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:835,&quot;width&quot;:949,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:92593,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174383863?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed10a40-f6a1-4d59-8858-74f49d34a0bf_949x835.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nu2D!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed10a40-f6a1-4d59-8858-74f49d34a0bf_949x835.png 424w, https://substackcdn.com/image/fetch/$s_!nu2D!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed10a40-f6a1-4d59-8858-74f49d34a0bf_949x835.png 848w, https://substackcdn.com/image/fetch/$s_!nu2D!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed10a40-f6a1-4d59-8858-74f49d34a0bf_949x835.png 1272w, https://substackcdn.com/image/fetch/$s_!nu2D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed10a40-f6a1-4d59-8858-74f49d34a0bf_949x835.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Each goroutine issues a request. While one waits for a delayed response, others can continue making progress, because the scheduler shifts new goroutines to threads that remain free. Without this handoff, the blocking network call would stall progress.</p><p>The runtime can also reuse threads once a system call completes, reducing the overhead of creating them from scratch. That reuse makes the system efficient even under heavy I/O, while still keeping goroutines responsive.</p><h3>What Scheduler Latency Looks Like</h3><p>Scheduler latency is the small but measurable gap between when a goroutine is ready to run and when it actually starts running. This delay exists because the runtime is constantly juggling queues, preemption checks, and system resources. For most applications the pause is brief, often so short it goes unnoticed, but under load the timing can stretch enough to affect performance.</p><h4>Normal Scheduling Costs</h4><p>Under regular conditions, the runtime has only a modest amount of work to manage. Goroutines flow through queues, and the scheduler inserts checks at points in the code to see if a goroutine has run long enough. Checks for yielding happen at safe points such as function calls. Since Go 1.14, the runtime can also preempt long-running code that lacks frequent calls, which keeps CPU-bound work from blocking others. That checking process introduces a small delay because the runtime saves state and looks for other goroutines that need to run. Most of the time this adds only microseconds of overhead, but the effect grows when thousands of goroutines are involved. The tradeoff is fairness: each one gets a turn without locking the CPU for too long.</p><p>A short program can show this balance.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xnYL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03f5f08e-86fc-4d79-baea-d0806fc15bfa_955x755.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xnYL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03f5f08e-86fc-4d79-baea-d0806fc15bfa_955x755.png 424w, https://substackcdn.com/image/fetch/$s_!xnYL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03f5f08e-86fc-4d79-baea-d0806fc15bfa_955x755.png 848w, https://substackcdn.com/image/fetch/$s_!xnYL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03f5f08e-86fc-4d79-baea-d0806fc15bfa_955x755.png 1272w, https://substackcdn.com/image/fetch/$s_!xnYL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03f5f08e-86fc-4d79-baea-d0806fc15bfa_955x755.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xnYL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03f5f08e-86fc-4d79-baea-d0806fc15bfa_955x755.png" width="955" height="755" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/03f5f08e-86fc-4d79-baea-d0806fc15bfa_955x755.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:755,&quot;width&quot;:955,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:75012,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174383863?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03f5f08e-86fc-4d79-baea-d0806fc15bfa_955x755.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xnYL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03f5f08e-86fc-4d79-baea-d0806fc15bfa_955x755.png 424w, https://substackcdn.com/image/fetch/$s_!xnYL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03f5f08e-86fc-4d79-baea-d0806fc15bfa_955x755.png 848w, https://substackcdn.com/image/fetch/$s_!xnYL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03f5f08e-86fc-4d79-baea-d0806fc15bfa_955x755.png 1272w, https://substackcdn.com/image/fetch/$s_!xnYL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03f5f08e-86fc-4d79-baea-d0806fc15bfa_955x755.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Each goroutine runs a heavy loop. Preemption checks prevent one loop from taking all the CPU, which creates a smoother share of time but introduces a slight delay each time a switch occurs. For small workloads it&#8217;s barely measurable, though it&#8217;s always there in the background.</p><h4>Latency Under Load</h4><p>When workloads scale into tens or hundreds of thousands of goroutines, queues inside the scheduler grow long. Each processor slot P has to juggle its own queue and sometimes reach into others to steal runnable goroutines. That coordination costs more under pressure, which can extend the time a goroutine waits after becoming ready.</p><p>This experiment shows how scheduling overhead grows under heavier load:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!57ch!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe19ae85b-3168-43cc-b148-c819f37dd018_1023x728.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!57ch!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe19ae85b-3168-43cc-b148-c819f37dd018_1023x728.png 424w, https://substackcdn.com/image/fetch/$s_!57ch!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe19ae85b-3168-43cc-b148-c819f37dd018_1023x728.png 848w, https://substackcdn.com/image/fetch/$s_!57ch!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe19ae85b-3168-43cc-b148-c819f37dd018_1023x728.png 1272w, https://substackcdn.com/image/fetch/$s_!57ch!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe19ae85b-3168-43cc-b148-c819f37dd018_1023x728.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!57ch!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe19ae85b-3168-43cc-b148-c819f37dd018_1023x728.png" width="691" height="491.7380254154448" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e19ae85b-3168-43cc-b148-c819f37dd018_1023x728.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1023,&quot;resizeWidth&quot;:691,&quot;bytes&quot;:79806,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174383863?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe19ae85b-3168-43cc-b148-c819f37dd018_1023x728.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!57ch!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe19ae85b-3168-43cc-b148-c819f37dd018_1023x728.png 424w, https://substackcdn.com/image/fetch/$s_!57ch!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe19ae85b-3168-43cc-b148-c819f37dd018_1023x728.png 848w, https://substackcdn.com/image/fetch/$s_!57ch!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe19ae85b-3168-43cc-b148-c819f37dd018_1023x728.png 1272w, https://substackcdn.com/image/fetch/$s_!57ch!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe19ae85b-3168-43cc-b148-c819f37dd018_1023x728.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The sleep call gives the runtime many opportunities to switch, but because so many goroutines are active, some have to wait longer before being scheduled again. This isn&#8217;t a bug in the runtime, just a result of queues being deeper than normal.</p><p>For a different angle, consider a workload that mixes short CPU-bound work with blocking operations:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NGmr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb894d284-20f6-4e45-8786-0ec4d23247df_900x729.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NGmr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb894d284-20f6-4e45-8786-0ec4d23247df_900x729.png 424w, https://substackcdn.com/image/fetch/$s_!NGmr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb894d284-20f6-4e45-8786-0ec4d23247df_900x729.png 848w, https://substackcdn.com/image/fetch/$s_!NGmr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb894d284-20f6-4e45-8786-0ec4d23247df_900x729.png 1272w, https://substackcdn.com/image/fetch/$s_!NGmr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb894d284-20f6-4e45-8786-0ec4d23247df_900x729.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NGmr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb894d284-20f6-4e45-8786-0ec4d23247df_900x729.png" width="654" height="529.74" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b894d284-20f6-4e45-8786-0ec4d23247df_900x729.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:729,&quot;width&quot;:900,&quot;resizeWidth&quot;:654,&quot;bytes&quot;:73126,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174383863?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb894d284-20f6-4e45-8786-0ec4d23247df_900x729.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NGmr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb894d284-20f6-4e45-8786-0ec4d23247df_900x729.png 424w, https://substackcdn.com/image/fetch/$s_!NGmr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb894d284-20f6-4e45-8786-0ec4d23247df_900x729.png 848w, https://substackcdn.com/image/fetch/$s_!NGmr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb894d284-20f6-4e45-8786-0ec4d23247df_900x729.png 1272w, https://substackcdn.com/image/fetch/$s_!NGmr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb894d284-20f6-4e45-8786-0ec4d23247df_900x729.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The runtime is now switching between blocking and active work. That extra juggling adds measurable delay, which under large loads can stretch into milliseconds. Applications with strict response needs must account for this, as queue depth and stealing both lengthen wait times.</p><h4>Preemption and Scheduling Fairness</h4><p>Preemption is the process where the runtime interrupts a long-running goroutine so that others don&#8217;t starve. Earlier versions of Go had coarser checks, but from Go 1.14 forward, preemption was improved to interrupt goroutines at more points in the code, including long loops with no function calls. This change made latency much more predictable.</p><p>Preemption adds its own small overhead because the runtime has to pause the current goroutine, save its state, and move another one onto the thread. That pause can be worth it, since it prevents starvation and spreads time more evenly. Without it, a single CPU-bound goroutine could delay thousands of others.</p><p>Here&#8217;s a code sample that benefits from preemption:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7Zer!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7618473f-fbb0-4428-a36a-b344466268da_968x735.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7Zer!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7618473f-fbb0-4428-a36a-b344466268da_968x735.png 424w, https://substackcdn.com/image/fetch/$s_!7Zer!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7618473f-fbb0-4428-a36a-b344466268da_968x735.png 848w, https://substackcdn.com/image/fetch/$s_!7Zer!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7618473f-fbb0-4428-a36a-b344466268da_968x735.png 1272w, https://substackcdn.com/image/fetch/$s_!7Zer!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7618473f-fbb0-4428-a36a-b344466268da_968x735.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7Zer!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7618473f-fbb0-4428-a36a-b344466268da_968x735.png" width="558" height="423.68801652892563" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7618473f-fbb0-4428-a36a-b344466268da_968x735.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:735,&quot;width&quot;:968,&quot;resizeWidth&quot;:558,&quot;bytes&quot;:62012,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174383863?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7618473f-fbb0-4428-a36a-b344466268da_968x735.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7Zer!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7618473f-fbb0-4428-a36a-b344466268da_968x735.png 424w, https://substackcdn.com/image/fetch/$s_!7Zer!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7618473f-fbb0-4428-a36a-b344466268da_968x735.png 848w, https://substackcdn.com/image/fetch/$s_!7Zer!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7618473f-fbb0-4428-a36a-b344466268da_968x735.png 1272w, https://substackcdn.com/image/fetch/$s_!7Zer!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7618473f-fbb0-4428-a36a-b344466268da_968x735.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Without <code>runtime.Gosched</code>, this loop will still be interrupted on Go 1.14 and later because goroutines are asynchronously preemptible. The runtime can stop a long-running goroutine at safe points and schedule others, so a manual yield is optional for responsiveness on current Go releases.</p><p>A second can show fairness a but more clearly:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ACfR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69750191-ade2-474e-9c65-98c720d1d828_1099x700.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ACfR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69750191-ade2-474e-9c65-98c720d1d828_1099x700.png 424w, https://substackcdn.com/image/fetch/$s_!ACfR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69750191-ade2-474e-9c65-98c720d1d828_1099x700.png 848w, https://substackcdn.com/image/fetch/$s_!ACfR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69750191-ade2-474e-9c65-98c720d1d828_1099x700.png 1272w, https://substackcdn.com/image/fetch/$s_!ACfR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69750191-ade2-474e-9c65-98c720d1d828_1099x700.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ACfR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69750191-ade2-474e-9c65-98c720d1d828_1099x700.png" width="611" height="389.171974522293" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/69750191-ade2-474e-9c65-98c720d1d828_1099x700.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:700,&quot;width&quot;:1099,&quot;resizeWidth&quot;:611,&quot;bytes&quot;:67577,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/174383863?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69750191-ade2-474e-9c65-98c720d1d828_1099x700.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ACfR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69750191-ade2-474e-9c65-98c720d1d828_1099x700.png 424w, https://substackcdn.com/image/fetch/$s_!ACfR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69750191-ade2-474e-9c65-98c720d1d828_1099x700.png 848w, https://substackcdn.com/image/fetch/$s_!ACfR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69750191-ade2-474e-9c65-98c720d1d828_1099x700.png 1272w, https://substackcdn.com/image/fetch/$s_!ACfR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69750191-ade2-474e-9c65-98c720d1d828_1099x700.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Each worker prints several lines. Without preemption in place, one worker could have run through all its iterations before any of the others had a chance to print. Modern scheduling keeps them interleaved so that output reflects multiple workers making progress side by side. That fairness does add a touch of delay during context switches, but it keeps the system responsive and prevents any one goroutine from taking over.</p><h3>Conclusion</h3><p>Scheduler latency in Go comes from the constant balancing act of handing goroutines to threads, stealing work across processors, and interrupting long-running loops when needed. Those mechanics keep large numbers of goroutines active without overwhelming the system. Delays can stretch under heavy pressure, but the runtime&#8217;s scheduling design keeps execution moving in a way that balances fairness and responsiveness.</p><ol><li><p><em><a href="https://golang.org/doc/faq#goroutines">Go Scheduler Documentation</a></em></p></li><li><p><em><a href="https://pkg.go.dev/runtime/pprof">Go Runtime Scheduler Tracing</a></em></p></li><li><p><em><a href="https://golang.org/ref/mem">Concurrency in Go Memory Model</a></em></p></li><li><p><em><a href="https://pkg.go.dev/runtime#GOMAXPROCS">GOMAXPROCS and Concurrency</a></em></p></li><li><p><em><a href="https://golang.org/doc/go1.14#runtime">Go Preemption in Go 1.14 Release Notes</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Scheduler Tracing in Go Runtime]]></title><description><![CDATA[Tracing the Go scheduler provides a clear view into how goroutines are created, scheduled, and executed by the runtime.]]></description><link>https://alexanderobregon.substack.com/p/scheduler-tracing-in-go-runtime</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/scheduler-tracing-in-go-runtime</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Fri, 19 Sep 2025 17:30:34 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/254a5635-c3ee-4b2a-a88a-14307d922f97_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!y--I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeef020e-213e-4daf-b760-20d4788e611d_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!y--I!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeef020e-213e-4daf-b760-20d4788e611d_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!y--I!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeef020e-213e-4daf-b760-20d4788e611d_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!y--I!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeef020e-213e-4daf-b760-20d4788e611d_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!y--I!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeef020e-213e-4daf-b760-20d4788e611d_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!y--I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeef020e-213e-4daf-b760-20d4788e611d_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eeef020e-213e-4daf-b760-20d4788e611d_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!y--I!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeef020e-213e-4daf-b760-20d4788e611d_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!y--I!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeef020e-213e-4daf-b760-20d4788e611d_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!y--I!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeef020e-213e-4daf-b760-20d4788e611d_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!y--I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeef020e-213e-4daf-b760-20d4788e611d_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>Tracing the Go scheduler provides a clear view into how goroutines are created, scheduled, and executed by the runtime. Go programs often depend on thousands of goroutines, and the runtime scheduler decides how they run across available operating system threads. When tracing the scheduler, developers gain direct access to events such as goroutine creation, blocking, unblocking, and processor handoff. These traces expose metrics that help in analyzing performance bottlenecks and goroutine behavior, which is valuable for both small programs and large production services.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>How Scheduler Tracing Works in Go</h3><p>Tracing in the Go runtime is not limited to simple timing data. The scheduler emits a structured stream of events that reveal how goroutines are created, moved between processors, and blocked on system calls. Understanding this trace requires some background on how the scheduler itself is organized, how tracing support is activated, and what the output contains once a trace is captured.</p><h4>Scheduler Mechanics</h4><p>The Go scheduler follows the M-P-G model, where goroutines (G) are scheduled to run on processors (P), which are executed on operating system threads called machines (M). This model was built to scale across many cores without requiring developers to manage threads manually. Each processor holds a run queue of goroutines, and the scheduler assigns them to threads that have processors attached. When a processor has no work, it can steal goroutines from the queue of another processor to keep execution balanced.</p><p>To see the effect of goroutines being distributed across threads, consider this simple example:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Wxss!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a9b0b8-2f71-4baa-a236-3ef9db3a6b10_1002x616.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Wxss!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a9b0b8-2f71-4baa-a236-3ef9db3a6b10_1002x616.png 424w, https://substackcdn.com/image/fetch/$s_!Wxss!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a9b0b8-2f71-4baa-a236-3ef9db3a6b10_1002x616.png 848w, https://substackcdn.com/image/fetch/$s_!Wxss!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a9b0b8-2f71-4baa-a236-3ef9db3a6b10_1002x616.png 1272w, https://substackcdn.com/image/fetch/$s_!Wxss!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a9b0b8-2f71-4baa-a236-3ef9db3a6b10_1002x616.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Wxss!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a9b0b8-2f71-4baa-a236-3ef9db3a6b10_1002x616.png" width="1002" height="616" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27a9b0b8-2f71-4baa-a236-3ef9db3a6b10_1002x616.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:616,&quot;width&quot;:1002,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:62939,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173798841?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a9b0b8-2f71-4baa-a236-3ef9db3a6b10_1002x616.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Wxss!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a9b0b8-2f71-4baa-a236-3ef9db3a6b10_1002x616.png 424w, https://substackcdn.com/image/fetch/$s_!Wxss!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a9b0b8-2f71-4baa-a236-3ef9db3a6b10_1002x616.png 848w, https://substackcdn.com/image/fetch/$s_!Wxss!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a9b0b8-2f71-4baa-a236-3ef9db3a6b10_1002x616.png 1272w, https://substackcdn.com/image/fetch/$s_!Wxss!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27a9b0b8-2f71-4baa-a236-3ef9db3a6b10_1002x616.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This code launches several goroutines while limiting execution to two processors. Although the internal <code>getg()</code> isn&#8217;t part of the public API and isn&#8217;t accessible in normal programs, the principle is that goroutines are constantly moved between processors and threads to keep execution balanced. Developers normally observe this through tracing rather than digging into runtime internals directly.</p><p>Work stealing, preemption, and queuing all happen under the control of the scheduler. The trace reveals these decisions, showing when goroutines migrate or are suspended because of blocking events.</p><h4>Tracing Support in the Runtime</h4><p>The <code>runtime/trace</code> package gives a direct way to capture scheduler activity. When a trace is started, the runtime logs events covering goroutine state changes, system call blocks, garbage collection, and network events. All of this is recorded in a binary format that can be examined with the <code>go tool trace</code> command.</p><p>A trace can be started from code by creating a file and starting the trace:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JukD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafb5fbd5-b201-4e42-82ca-24ba12d0b9a5_1001x728.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JukD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafb5fbd5-b201-4e42-82ca-24ba12d0b9a5_1001x728.png 424w, https://substackcdn.com/image/fetch/$s_!JukD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafb5fbd5-b201-4e42-82ca-24ba12d0b9a5_1001x728.png 848w, https://substackcdn.com/image/fetch/$s_!JukD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafb5fbd5-b201-4e42-82ca-24ba12d0b9a5_1001x728.png 1272w, https://substackcdn.com/image/fetch/$s_!JukD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafb5fbd5-b201-4e42-82ca-24ba12d0b9a5_1001x728.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JukD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafb5fbd5-b201-4e42-82ca-24ba12d0b9a5_1001x728.png" width="1001" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/afb5fbd5-b201-4e42-82ca-24ba12d0b9a5_1001x728.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1001,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:68651,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173798841?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafb5fbd5-b201-4e42-82ca-24ba12d0b9a5_1001x728.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JukD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafb5fbd5-b201-4e42-82ca-24ba12d0b9a5_1001x728.png 424w, https://substackcdn.com/image/fetch/$s_!JukD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafb5fbd5-b201-4e42-82ca-24ba12d0b9a5_1001x728.png 848w, https://substackcdn.com/image/fetch/$s_!JukD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafb5fbd5-b201-4e42-82ca-24ba12d0b9a5_1001x728.png 1272w, https://substackcdn.com/image/fetch/$s_!JukD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafb5fbd5-b201-4e42-82ca-24ba12d0b9a5_1001x728.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This snippet records all runtime events during execution and writes them to <code>trace.out</code>. Running <code>go tool trace trace.out</code> opens a web-based interface that provides views of goroutine activity, processor scheduling, and latency events.</p><p>Tracing can also be activated without writing code. The <code>go test</code> command includes a <code>-trace</code> flag, which automatically records a trace while running tests. This is useful for analyzing performance in a test suite without instrumenting the code manually.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Tvki!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c7670ba-2336-4abf-81b6-9f40e2962358_842x33.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Tvki!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c7670ba-2336-4abf-81b6-9f40e2962358_842x33.png 424w, https://substackcdn.com/image/fetch/$s_!Tvki!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c7670ba-2336-4abf-81b6-9f40e2962358_842x33.png 848w, https://substackcdn.com/image/fetch/$s_!Tvki!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c7670ba-2336-4abf-81b6-9f40e2962358_842x33.png 1272w, https://substackcdn.com/image/fetch/$s_!Tvki!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c7670ba-2336-4abf-81b6-9f40e2962358_842x33.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Tvki!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c7670ba-2336-4abf-81b6-9f40e2962358_842x33.png" width="666" height="26.102137767220903" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2c7670ba-2336-4abf-81b6-9f40e2962358_842x33.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:33,&quot;width&quot;:842,&quot;resizeWidth&quot;:666,&quot;bytes&quot;:7686,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173798841?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c7670ba-2336-4abf-81b6-9f40e2962358_842x33.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Tvki!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c7670ba-2336-4abf-81b6-9f40e2962358_842x33.png 424w, https://substackcdn.com/image/fetch/$s_!Tvki!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c7670ba-2336-4abf-81b6-9f40e2962358_842x33.png 848w, https://substackcdn.com/image/fetch/$s_!Tvki!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c7670ba-2336-4abf-81b6-9f40e2962358_842x33.png 1272w, https://substackcdn.com/image/fetch/$s_!Tvki!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c7670ba-2336-4abf-81b6-9f40e2962358_842x33.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>This flexibility means tracing can be used in controlled experiments, automated tests, or during production incident investigations. Each approach produces the same format, making analysis consistent across contexts.</p><h4>What the Trace Shows</h4><p>After a trace is collected and opened with <code>go tool trace</code>, the scheduler&#8217;s decisions become visible on a timeline. The trace includes event categories for goroutine lifecycle, processor activity, and system calls. Developers can zoom into a single goroutine to see when it was created, when it started running, and when it blocked. They can also step back to a system-wide view that shows processor queues filling and emptying as load shifts around.</p><p>Here&#8217;s a minimal program designed to generate interesting scheduler behavior for a trace:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!z_Zp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff914eeac-db56-48f8-94b2-555c4718946e_1062x835.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!z_Zp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff914eeac-db56-48f8-94b2-555c4718946e_1062x835.png 424w, https://substackcdn.com/image/fetch/$s_!z_Zp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff914eeac-db56-48f8-94b2-555c4718946e_1062x835.png 848w, https://substackcdn.com/image/fetch/$s_!z_Zp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff914eeac-db56-48f8-94b2-555c4718946e_1062x835.png 1272w, https://substackcdn.com/image/fetch/$s_!z_Zp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff914eeac-db56-48f8-94b2-555c4718946e_1062x835.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!z_Zp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff914eeac-db56-48f8-94b2-555c4718946e_1062x835.png" width="1062" height="835" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f914eeac-db56-48f8-94b2-555c4718946e_1062x835.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:835,&quot;width&quot;:1062,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:94492,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173798841?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff914eeac-db56-48f8-94b2-555c4718946e_1062x835.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!z_Zp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff914eeac-db56-48f8-94b2-555c4718946e_1062x835.png 424w, https://substackcdn.com/image/fetch/$s_!z_Zp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff914eeac-db56-48f8-94b2-555c4718946e_1062x835.png 848w, https://substackcdn.com/image/fetch/$s_!z_Zp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff914eeac-db56-48f8-94b2-555c4718946e_1062x835.png 1272w, https://substackcdn.com/image/fetch/$s_!z_Zp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff914eeac-db56-48f8-94b2-555c4718946e_1062x835.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The code above creates a burst of goroutines, each blocking on a timed sleep. The trace will display these goroutines entering the run queue, being scheduled, then parking while they sleep. The viewer will also show processor load shifting as goroutines wake up and re-enter the queues.</p><p>Another useful aspect of tracing is the ability to connect scheduler events to user code. Custom regions can be marked with <code>trace.WithRegion</code>, which labels a block of work so it appears in the trace:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!me1K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8defe2-f410-48b9-afa0-7ea9772d9128_1078x175.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!me1K!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8defe2-f410-48b9-afa0-7ea9772d9128_1078x175.png 424w, https://substackcdn.com/image/fetch/$s_!me1K!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8defe2-f410-48b9-afa0-7ea9772d9128_1078x175.png 848w, https://substackcdn.com/image/fetch/$s_!me1K!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8defe2-f410-48b9-afa0-7ea9772d9128_1078x175.png 1272w, https://substackcdn.com/image/fetch/$s_!me1K!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8defe2-f410-48b9-afa0-7ea9772d9128_1078x175.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!me1K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8defe2-f410-48b9-afa0-7ea9772d9128_1078x175.png" width="1078" height="175" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5c8defe2-f410-48b9-afa0-7ea9772d9128_1078x175.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:175,&quot;width&quot;:1078,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:37490,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173798841?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8defe2-f410-48b9-afa0-7ea9772d9128_1078x175.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!me1K!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8defe2-f410-48b9-afa0-7ea9772d9128_1078x175.png 424w, https://substackcdn.com/image/fetch/$s_!me1K!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8defe2-f410-48b9-afa0-7ea9772d9128_1078x175.png 848w, https://substackcdn.com/image/fetch/$s_!me1K!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8defe2-f410-48b9-afa0-7ea9772d9128_1078x175.png 1272w, https://substackcdn.com/image/fetch/$s_!me1K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c8defe2-f410-48b9-afa0-7ea9772d9128_1078x175.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>This adds a labeled entry to the trace, making it easier to match scheduler events to specific workloads. Custom regions like this can be combined with the runtime&#8217;s own events, letting developers match what the code was doing with how the scheduler handled it.</p><h3>Metrics Exposed by Scheduler Tracing</h3><p>Tracing is not only about recording events. It also produces a set of metrics that help developers see how goroutines interact with the runtime scheduler. These metrics provide context for execution delays, blocking behavior, and processor usage patterns, making it easier to link runtime decisions to code-level behavior.</p><h4>Goroutine Latency and Blocking</h4><p>Latency refers to the time between a goroutine being created and the point where it actually begins running. In a trace, you can see whether goroutines spend most of their time waiting in queues or actively executing. Blocking metrics reveal when goroutines pause while waiting on a channel, a lock, or a network operation.</p><p>A practical way to generate blocking events for analysis is to use a channel where multiple goroutines contend for the same resource:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xetB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77ef1659-b275-4158-bb83-f4c58e664381_850x787.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xetB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77ef1659-b275-4158-bb83-f4c58e664381_850x787.png 424w, https://substackcdn.com/image/fetch/$s_!xetB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77ef1659-b275-4158-bb83-f4c58e664381_850x787.png 848w, https://substackcdn.com/image/fetch/$s_!xetB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77ef1659-b275-4158-bb83-f4c58e664381_850x787.png 1272w, https://substackcdn.com/image/fetch/$s_!xetB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77ef1659-b275-4158-bb83-f4c58e664381_850x787.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xetB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77ef1659-b275-4158-bb83-f4c58e664381_850x787.png" width="694" height="642.5623529411764" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/77ef1659-b275-4158-bb83-f4c58e664381_850x787.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:787,&quot;width&quot;:850,&quot;resizeWidth&quot;:694,&quot;bytes&quot;:84736,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173798841?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77ef1659-b275-4158-bb83-f4c58e664381_850x787.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xetB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77ef1659-b275-4158-bb83-f4c58e664381_850x787.png 424w, https://substackcdn.com/image/fetch/$s_!xetB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77ef1659-b275-4158-bb83-f4c58e664381_850x787.png 848w, https://substackcdn.com/image/fetch/$s_!xetB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77ef1659-b275-4158-bb83-f4c58e664381_850x787.png 1272w, https://substackcdn.com/image/fetch/$s_!xetB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77ef1659-b275-4158-bb83-f4c58e664381_850x787.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This code causes several goroutines to block on a channel receive. The trace will show those goroutines waiting until the channel is written to, giving a view into both the latency before execution and the blocking behavior during execution.</p><p>Blocking can also occur with mutexes, which can be useful to observe in traces:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SBg6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b184782-4873-40e8-9e31-f7b0694e5009_806x456.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SBg6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b184782-4873-40e8-9e31-f7b0694e5009_806x456.png 424w, https://substackcdn.com/image/fetch/$s_!SBg6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b184782-4873-40e8-9e31-f7b0694e5009_806x456.png 848w, https://substackcdn.com/image/fetch/$s_!SBg6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b184782-4873-40e8-9e31-f7b0694e5009_806x456.png 1272w, https://substackcdn.com/image/fetch/$s_!SBg6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b184782-4873-40e8-9e31-f7b0694e5009_806x456.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SBg6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b184782-4873-40e8-9e31-f7b0694e5009_806x456.png" width="565" height="319.6526054590571" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8b184782-4873-40e8-9e31-f7b0694e5009_806x456.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:456,&quot;width&quot;:806,&quot;resizeWidth&quot;:565,&quot;bytes&quot;:54144,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173798841?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b184782-4873-40e8-9e31-f7b0694e5009_806x456.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SBg6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b184782-4873-40e8-9e31-f7b0694e5009_806x456.png 424w, https://substackcdn.com/image/fetch/$s_!SBg6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b184782-4873-40e8-9e31-f7b0694e5009_806x456.png 848w, https://substackcdn.com/image/fetch/$s_!SBg6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b184782-4873-40e8-9e31-f7b0694e5009_806x456.png 1272w, https://substackcdn.com/image/fetch/$s_!SBg6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b184782-4873-40e8-9e31-f7b0694e5009_806x456.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The code here records one goroutine holding a lock while another waits. Traces reveal this as a block-and-unblock sequence tied to the mutex.</p><h4>Processor Utilization</h4><p>Tracing also captures how processors (P) are scheduled across available threads and how busy they remain during the lifetime of a workload. A P is per-CPU scheduler state. An OS thread (M) must hold a P to run Go code. When an M enters a blocking system call it returns its P to the idle pool and on return it must acquire a P again.</p><p>An experiment that creates bursts of goroutines can help visualize processor load:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PEP_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65c0a4c6-4efe-49d9-8d1f-22926f788355_984x754.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PEP_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65c0a4c6-4efe-49d9-8d1f-22926f788355_984x754.png 424w, https://substackcdn.com/image/fetch/$s_!PEP_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65c0a4c6-4efe-49d9-8d1f-22926f788355_984x754.png 848w, https://substackcdn.com/image/fetch/$s_!PEP_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65c0a4c6-4efe-49d9-8d1f-22926f788355_984x754.png 1272w, https://substackcdn.com/image/fetch/$s_!PEP_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65c0a4c6-4efe-49d9-8d1f-22926f788355_984x754.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PEP_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65c0a4c6-4efe-49d9-8d1f-22926f788355_984x754.png" width="984" height="754" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/65c0a4c6-4efe-49d9-8d1f-22926f788355_984x754.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:754,&quot;width&quot;:984,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:73221,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173798841?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65c0a4c6-4efe-49d9-8d1f-22926f788355_984x754.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PEP_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65c0a4c6-4efe-49d9-8d1f-22926f788355_984x754.png 424w, https://substackcdn.com/image/fetch/$s_!PEP_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65c0a4c6-4efe-49d9-8d1f-22926f788355_984x754.png 848w, https://substackcdn.com/image/fetch/$s_!PEP_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65c0a4c6-4efe-49d9-8d1f-22926f788355_984x754.png 1272w, https://substackcdn.com/image/fetch/$s_!PEP_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65c0a4c6-4efe-49d9-8d1f-22926f788355_984x754.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Running this with multiple processors shows in the trace how work is spread across available threads. When viewed in the trace tool, you can see whether processors are well balanced or if one thread is overloaded while others are idle.</p><p>Long gaps in processor usage may indicate goroutines waiting too frequently on I/O, while consistently full utilization could suggest heavy CPU-bound computation. Both patterns are visible in the trace timeline.</p><h4>Network Poller Activity</h4><p>Go&#8217;s runtime includes a network poller that interacts with the operating system to manage non-blocking I/O. This poller parks goroutines that are waiting for I/O readiness and wakes them when the socket or file descriptor is ready. Tracing records both the parking event and the point where the goroutine resumes.</p><p>A small server example can produce useful poller activity in a trace:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oH5A!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdef0fcd-26c8-4633-949d-a09fc31c1aa3_564x884.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oH5A!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdef0fcd-26c8-4633-949d-a09fc31c1aa3_564x884.png 424w, https://substackcdn.com/image/fetch/$s_!oH5A!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdef0fcd-26c8-4633-949d-a09fc31c1aa3_564x884.png 848w, https://substackcdn.com/image/fetch/$s_!oH5A!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdef0fcd-26c8-4633-949d-a09fc31c1aa3_564x884.png 1272w, https://substackcdn.com/image/fetch/$s_!oH5A!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdef0fcd-26c8-4633-949d-a09fc31c1aa3_564x884.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oH5A!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdef0fcd-26c8-4633-949d-a09fc31c1aa3_564x884.png" width="564" height="884" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fdef0fcd-26c8-4633-949d-a09fc31c1aa3_564x884.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:884,&quot;width&quot;:564,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:91354,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173798841?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdef0fcd-26c8-4633-949d-a09fc31c1aa3_564x884.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oH5A!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdef0fcd-26c8-4633-949d-a09fc31c1aa3_564x884.png 424w, https://substackcdn.com/image/fetch/$s_!oH5A!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdef0fcd-26c8-4633-949d-a09fc31c1aa3_564x884.png 848w, https://substackcdn.com/image/fetch/$s_!oH5A!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdef0fcd-26c8-4633-949d-a09fc31c1aa3_564x884.png 1272w, https://substackcdn.com/image/fetch/$s_!oH5A!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdef0fcd-26c8-4633-949d-a09fc31c1aa3_564x884.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When a client connects and sends data, the trace shows goroutines waiting on network readiness and then resuming once data arrives. This visualization helps identify delays that come not from CPU scheduling but from I/O waits handled by the poller.</p><h4>Practical Example of Analyzing a Trace</h4><p>Metrics gain meaning when connected to a concrete workload. Suppose you trace a program that creates a large number of goroutines that each wait on a channel. The trace shows a spike in goroutine creation events, followed by long queues of blocked goroutines. This suggests that concurrency is outpacing the available processors.</p><p>Here&#8217;s a simple workload to generate such behavior:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XUSm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2fb176e9-90a5-45b5-a9dc-7caa1fe490c7_904x669.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XUSm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2fb176e9-90a5-45b5-a9dc-7caa1fe490c7_904x669.png 424w, https://substackcdn.com/image/fetch/$s_!XUSm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2fb176e9-90a5-45b5-a9dc-7caa1fe490c7_904x669.png 848w, https://substackcdn.com/image/fetch/$s_!XUSm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2fb176e9-90a5-45b5-a9dc-7caa1fe490c7_904x669.png 1272w, https://substackcdn.com/image/fetch/$s_!XUSm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2fb176e9-90a5-45b5-a9dc-7caa1fe490c7_904x669.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XUSm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2fb176e9-90a5-45b5-a9dc-7caa1fe490c7_904x669.png" width="904" height="669" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2fb176e9-90a5-45b5-a9dc-7caa1fe490c7_904x669.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:669,&quot;width&quot;:904,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:67363,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173798841?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2fb176e9-90a5-45b5-a9dc-7caa1fe490c7_904x669.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XUSm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2fb176e9-90a5-45b5-a9dc-7caa1fe490c7_904x669.png 424w, https://substackcdn.com/image/fetch/$s_!XUSm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2fb176e9-90a5-45b5-a9dc-7caa1fe490c7_904x669.png 848w, https://substackcdn.com/image/fetch/$s_!XUSm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2fb176e9-90a5-45b5-a9dc-7caa1fe490c7_904x669.png 1272w, https://substackcdn.com/image/fetch/$s_!XUSm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2fb176e9-90a5-45b5-a9dc-7caa1fe490c7_904x669.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Tracing this reveals hundreds of goroutines blocking until the channel closes. When it closes, the scheduler must suddenly run all those goroutines, which causes a visible burst of activity. Metrics such as latency and processor load explain why execution appears delayed and uneven.</p><h4>Comparing Tracing With Profiling</h4><p>Profiling and tracing serve related but different goals. Profiling, through tools like <code>pprof</code>, measures where CPU cycles or memory allocations occur across the life of a program. It gives aggregate data over time. Tracing records exact events, including scheduling, blocking, and processor activity, and shows them in sequence on a timeline.</p><p>A simple CPU profile might reveal that a function consumes most of the runtime, but it wouldn&#8217;t explain why so many goroutines are delayed before running that function. A trace fills this gap by providing the timeline of goroutine creation, queueing, and execution.</p><p>Here&#8217;s an example of collecting a CPU profile for contrast:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zItc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafd4e43b-bd5a-4e91-84a0-823ec533f35d_967x82.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zItc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafd4e43b-bd5a-4e91-84a0-823ec533f35d_967x82.png 424w, https://substackcdn.com/image/fetch/$s_!zItc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafd4e43b-bd5a-4e91-84a0-823ec533f35d_967x82.png 848w, https://substackcdn.com/image/fetch/$s_!zItc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafd4e43b-bd5a-4e91-84a0-823ec533f35d_967x82.png 1272w, https://substackcdn.com/image/fetch/$s_!zItc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafd4e43b-bd5a-4e91-84a0-823ec533f35d_967x82.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zItc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafd4e43b-bd5a-4e91-84a0-823ec533f35d_967x82.png" width="584" height="49.52223371251293" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/afd4e43b-bd5a-4e91-84a0-823ec533f35d_967x82.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:82,&quot;width&quot;:967,&quot;resizeWidth&quot;:584,&quot;bytes&quot;:18161,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173798841?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafd4e43b-bd5a-4e91-84a0-823ec533f35d_967x82.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zItc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafd4e43b-bd5a-4e91-84a0-823ec533f35d_967x82.png 424w, https://substackcdn.com/image/fetch/$s_!zItc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafd4e43b-bd5a-4e91-84a0-823ec533f35d_967x82.png 848w, https://substackcdn.com/image/fetch/$s_!zItc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafd4e43b-bd5a-4e91-84a0-823ec533f35d_967x82.png 1272w, https://substackcdn.com/image/fetch/$s_!zItc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafd4e43b-bd5a-4e91-84a0-823ec533f35d_967x82.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Profiles like this help identify hotspots, while traces explain the order and timing of runtime events. Both tools are often used side by side, where profiling identifies functions worth inspecting, and tracing explains how those functions interact with the scheduler and goroutines.</p><h3>Conclusion</h3><p>Tracing in Go gives a direct look at how the scheduler moves goroutines across processors, handles blocking, and manages I/O waits. The mechanics behind these traces show more than surface-level timing. They provide a timeline of how work is created, queued, suspended, and resumed. Looking at these events in detail helps connect what the code is doing with how the runtime makes decisions, turning scheduler behavior into something observable instead of hidden in background execution.</p><ol><li><p><em><a href="https://pkg.go.dev/runtime/trace">Go runtime trace package</a></em></p></li><li><p><em><a href="https://pkg.go.dev/cmd/trace">Go tool trace command</a></em></p></li><li><p><em><a href="https://pkg.go.dev/runtime/pprof">pprof profiling tool</a></em></p></li><li><p><em><a href="https://pkg.go.dev/runtime#GOMAXPROCS">GOMAXPROCS and scheduler tuning</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item><item><title><![CDATA[Deferred Recover in Go Panic Handling]]></title><description><![CDATA[Go has its own way of handling errors through panics, deferred calls, and the recover function.]]></description><link>https://alexanderobregon.substack.com/p/deferred-recover-in-go-panic-handling</link><guid isPermaLink="false">https://alexanderobregon.substack.com/p/deferred-recover-in-go-panic-handling</guid><dc:creator><![CDATA[Alexander Obregon]]></dc:creator><pubDate>Wed, 17 Sep 2025 17:05:07 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/a91550d1-0cf6-46d0-b797-9ad5c843ee92_882x449.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ULtZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96d17596-be3b-4955-b508-3f04d07e336a_756x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ULtZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96d17596-be3b-4955-b508-3f04d07e336a_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!ULtZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96d17596-be3b-4955-b508-3f04d07e336a_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!ULtZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96d17596-be3b-4955-b508-3f04d07e336a_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!ULtZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96d17596-be3b-4955-b508-3f04d07e336a_756x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ULtZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96d17596-be3b-4955-b508-3f04d07e336a_756x283.png" width="756" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/96d17596-be3b-4955-b508-3f04d07e336a_756x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ULtZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96d17596-be3b-4955-b508-3f04d07e336a_756x283.png 424w, https://substackcdn.com/image/fetch/$s_!ULtZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96d17596-be3b-4955-b508-3f04d07e336a_756x283.png 848w, https://substackcdn.com/image/fetch/$s_!ULtZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96d17596-be3b-4955-b508-3f04d07e336a_756x283.png 1272w, https://substackcdn.com/image/fetch/$s_!ULtZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96d17596-be3b-4955-b508-3f04d07e336a_756x283.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://go.dev/">Image Source</a></figcaption></figure></div><p>Go has its own way of handling errors through panics, deferred calls, and the recover function. A panic stops normal flow when something unexpected happens, while deferred calls are instructions set aside to run as a function finishes. Recover works in this process by letting the function take back control after a panic is raised. All of these features combine to form how panic handling works in Go.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/subscribe?"><span>Subscribe now</span></a></p><h3>Deferred Functions and Panic Propagation</h3><p>Deferred calls play a special part in Go&#8217;s runtime because they always run before a function exits. This is true regardless of whether the function exits normally or because of a panic. When paired with recover, deferred functions create a safety net that can stop a panic from bubbling further up the call stack.</p><h4>Order of Deferred Calls</h4><p>Go treats deferred calls like entries on a stack. Each time a function calls defer, that operation gets pushed to the stack. When the function is about to finish, the runtime pops them one by one in reverse order. This makes the last deferred call the first one to run. It applies equally whether the function finishes normally or through a panic.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_do3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8846020-c90f-4e21-903a-0c08fcaa5ba6_1346x524.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_do3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8846020-c90f-4e21-903a-0c08fcaa5ba6_1346x524.png 424w, https://substackcdn.com/image/fetch/$s_!_do3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8846020-c90f-4e21-903a-0c08fcaa5ba6_1346x524.png 848w, https://substackcdn.com/image/fetch/$s_!_do3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8846020-c90f-4e21-903a-0c08fcaa5ba6_1346x524.png 1272w, https://substackcdn.com/image/fetch/$s_!_do3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8846020-c90f-4e21-903a-0c08fcaa5ba6_1346x524.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_do3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8846020-c90f-4e21-903a-0c08fcaa5ba6_1346x524.png" width="1346" height="524" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f8846020-c90f-4e21-903a-0c08fcaa5ba6_1346x524.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:524,&quot;width&quot;:1346,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:65798,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173795459?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8846020-c90f-4e21-903a-0c08fcaa5ba6_1346x524.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_do3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8846020-c90f-4e21-903a-0c08fcaa5ba6_1346x524.png 424w, https://substackcdn.com/image/fetch/$s_!_do3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8846020-c90f-4e21-903a-0c08fcaa5ba6_1346x524.png 848w, https://substackcdn.com/image/fetch/$s_!_do3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8846020-c90f-4e21-903a-0c08fcaa5ba6_1346x524.png 1272w, https://substackcdn.com/image/fetch/$s_!_do3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8846020-c90f-4e21-903a-0c08fcaa5ba6_1346x524.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When this code runs, the panic starts unwinding and prints <code>Defer C</code>, then <code>Defer B</code>, then <code>Defer A</code>. The print right before the panic still runs, but no lines after the panic are reached.</p><p>This stack-based rule means you can predict how resource cleanup or recovery attempts will line up. A function might open multiple resources and use defer for each one, and during a panic they&#8217;ll be closed in the reverse order they were acquired. That behavior is consistent across the language and makes deferred calls more reliable during error handling.</p><p>A smaller example makes the stack order even clearer:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jPxd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3127839f-8409-415f-a0c8-2dd583fca69b_1357x454.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jPxd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3127839f-8409-415f-a0c8-2dd583fca69b_1357x454.png 424w, https://substackcdn.com/image/fetch/$s_!jPxd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3127839f-8409-415f-a0c8-2dd583fca69b_1357x454.png 848w, https://substackcdn.com/image/fetch/$s_!jPxd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3127839f-8409-415f-a0c8-2dd583fca69b_1357x454.png 1272w, https://substackcdn.com/image/fetch/$s_!jPxd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3127839f-8409-415f-a0c8-2dd583fca69b_1357x454.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jPxd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3127839f-8409-415f-a0c8-2dd583fca69b_1357x454.png" width="1357" height="454" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3127839f-8409-415f-a0c8-2dd583fca69b_1357x454.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:454,&quot;width&quot;:1357,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:40632,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173795459?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3127839f-8409-415f-a0c8-2dd583fca69b_1357x454.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jPxd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3127839f-8409-415f-a0c8-2dd583fca69b_1357x454.png 424w, https://substackcdn.com/image/fetch/$s_!jPxd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3127839f-8409-415f-a0c8-2dd583fca69b_1357x454.png 848w, https://substackcdn.com/image/fetch/$s_!jPxd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3127839f-8409-415f-a0c8-2dd583fca69b_1357x454.png 1272w, https://substackcdn.com/image/fetch/$s_!jPxd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3127839f-8409-415f-a0c8-2dd583fca69b_1357x454.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Even without a panic, the prints go from <code>3</code> down to <code>1</code>. This shows that the order of deferred calls isn&#8217;t tied only to panic handling but is built into how Go treats defer in general.</p><h4>Recover Inside Deferred Functions</h4><p>Recover has one restriction that often surprises beginners. It only returns a non-nil value when it&#8217;s called inside a deferred function that is running during a panic unwind. If you call recover outside that context, it silently gives back nil. That rule ties recover tightly to deferred calls, making them the exclusive place where panic recovery is possible.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!J-Ms!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77d28d14-c420-4740-9070-d1ca43ed72cc_1351x698.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!J-Ms!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77d28d14-c420-4740-9070-d1ca43ed72cc_1351x698.png 424w, https://substackcdn.com/image/fetch/$s_!J-Ms!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77d28d14-c420-4740-9070-d1ca43ed72cc_1351x698.png 848w, https://substackcdn.com/image/fetch/$s_!J-Ms!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77d28d14-c420-4740-9070-d1ca43ed72cc_1351x698.png 1272w, https://substackcdn.com/image/fetch/$s_!J-Ms!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77d28d14-c420-4740-9070-d1ca43ed72cc_1351x698.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!J-Ms!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77d28d14-c420-4740-9070-d1ca43ed72cc_1351x698.png" width="1351" height="698" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/77d28d14-c420-4740-9070-d1ca43ed72cc_1351x698.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:698,&quot;width&quot;:1351,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:98011,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173795459?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77d28d14-c420-4740-9070-d1ca43ed72cc_1351x698.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!J-Ms!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77d28d14-c420-4740-9070-d1ca43ed72cc_1351x698.png 424w, https://substackcdn.com/image/fetch/$s_!J-Ms!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77d28d14-c420-4740-9070-d1ca43ed72cc_1351x698.png 848w, https://substackcdn.com/image/fetch/$s_!J-Ms!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77d28d14-c420-4740-9070-d1ca43ed72cc_1351x698.png 1272w, https://substackcdn.com/image/fetch/$s_!J-Ms!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F77d28d14-c420-4740-9070-d1ca43ed72cc_1351x698.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The call to recover inside the deferred anonymous function captures the panic and stops the stack from unwinding further. Control then returns to main, where execution continues normally. Without the deferred block, the panic would have kept climbing until it terminated the entire process.</p><p>Deferred recover functions can also be combined with cleanup logic. You might have one deferred call that closes resources and another that runs recovery code. Their order matters because only the recover call that runs while the panic is still active will succeed.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!d15-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663df9b3-ae96-4efd-959b-598b4b15c6d1_1350x627.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!d15-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663df9b3-ae96-4efd-959b-598b4b15c6d1_1350x627.png 424w, https://substackcdn.com/image/fetch/$s_!d15-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663df9b3-ae96-4efd-959b-598b4b15c6d1_1350x627.png 848w, https://substackcdn.com/image/fetch/$s_!d15-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663df9b3-ae96-4efd-959b-598b4b15c6d1_1350x627.png 1272w, https://substackcdn.com/image/fetch/$s_!d15-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663df9b3-ae96-4efd-959b-598b4b15c6d1_1350x627.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!d15-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663df9b3-ae96-4efd-959b-598b4b15c6d1_1350x627.png" width="1350" height="627" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/663df9b3-ae96-4efd-959b-598b4b15c6d1_1350x627.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:627,&quot;width&quot;:1350,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:69172,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173795459?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663df9b3-ae96-4efd-959b-598b4b15c6d1_1350x627.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!d15-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663df9b3-ae96-4efd-959b-598b4b15c6d1_1350x627.png 424w, https://substackcdn.com/image/fetch/$s_!d15-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663df9b3-ae96-4efd-959b-598b4b15c6d1_1350x627.png 848w, https://substackcdn.com/image/fetch/$s_!d15-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663df9b3-ae96-4efd-959b-598b4b15c6d1_1350x627.png 1272w, https://substackcdn.com/image/fetch/$s_!d15-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F663df9b3-ae96-4efd-959b-598b4b15c6d1_1350x627.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This prints <code>Closing down</code> first, then the recovery message, because deferred calls unwind from the most recent. If you swapped their order, recovery would happen first and the closing message would follow afterward. That detail often decides how you structure deferred code in functions that need both cleanup and recovery.</p><p>Recover is flexible in what it returns, since panic can be raised with any type, not only strings. A panic might carry an error type, a number, or even a struct. Recover will always give back the same value, which means you can design recovery logic that checks for expected types and acts accordingly.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fEM-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e4c369b-0286-4249-a630-96ddaf391f9a_1356x870.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fEM-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e4c369b-0286-4249-a630-96ddaf391f9a_1356x870.png 424w, https://substackcdn.com/image/fetch/$s_!fEM-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e4c369b-0286-4249-a630-96ddaf391f9a_1356x870.png 848w, https://substackcdn.com/image/fetch/$s_!fEM-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e4c369b-0286-4249-a630-96ddaf391f9a_1356x870.png 1272w, https://substackcdn.com/image/fetch/$s_!fEM-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e4c369b-0286-4249-a630-96ddaf391f9a_1356x870.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fEM-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e4c369b-0286-4249-a630-96ddaf391f9a_1356x870.png" width="1356" height="870" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7e4c369b-0286-4249-a630-96ddaf391f9a_1356x870.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:870,&quot;width&quot;:1356,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:108492,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173795459?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e4c369b-0286-4249-a630-96ddaf391f9a_1356x870.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fEM-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e4c369b-0286-4249-a630-96ddaf391f9a_1356x870.png 424w, https://substackcdn.com/image/fetch/$s_!fEM-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e4c369b-0286-4249-a630-96ddaf391f9a_1356x870.png 848w, https://substackcdn.com/image/fetch/$s_!fEM-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e4c369b-0286-4249-a630-96ddaf391f9a_1356x870.png 1272w, https://substackcdn.com/image/fetch/$s_!fEM-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e4c369b-0286-4249-a630-96ddaf391f9a_1356x870.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The deferred recovery inspects the panic value and branches logic based on its type. That ability adds flexibility to how recovery is used in real projects, where panic values might not always be plain strings.</p><h3>Control Flow After Recover</h3><p>Recover changes the normal path of panic handling in a way that&#8217;s subtle but important. A panic sets off a chain reaction of deferred calls, and without recovery it will eventually end the goroutine. When recover is introduced, that sequence can be interrupted, allowing execution to continue past the point of failure.</p><h4>What Happens When a Panic Starts</h4><p>When panic is triggered, Go creates a panic object that carries the value passed in. The runtime then begins a process called unwinding, which is just a step-by-step run of deferred calls on the stack. Each deferred function is executed in the reverse order they were registered. Normal flow stops immediately when panic is called, so any statements after it won&#8217;t run.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vFJa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc83154-56b8-46ad-bd02-2e2b7f21fc2a_1225x486.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vFJa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc83154-56b8-46ad-bd02-2e2b7f21fc2a_1225x486.png 424w, https://substackcdn.com/image/fetch/$s_!vFJa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc83154-56b8-46ad-bd02-2e2b7f21fc2a_1225x486.png 848w, https://substackcdn.com/image/fetch/$s_!vFJa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc83154-56b8-46ad-bd02-2e2b7f21fc2a_1225x486.png 1272w, https://substackcdn.com/image/fetch/$s_!vFJa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc83154-56b8-46ad-bd02-2e2b7f21fc2a_1225x486.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vFJa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc83154-56b8-46ad-bd02-2e2b7f21fc2a_1225x486.png" width="1225" height="486" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7bc83154-56b8-46ad-bd02-2e2b7f21fc2a_1225x486.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:486,&quot;width&quot;:1225,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:54956,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173795459?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc83154-56b8-46ad-bd02-2e2b7f21fc2a_1225x486.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vFJa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc83154-56b8-46ad-bd02-2e2b7f21fc2a_1225x486.png 424w, https://substackcdn.com/image/fetch/$s_!vFJa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc83154-56b8-46ad-bd02-2e2b7f21fc2a_1225x486.png 848w, https://substackcdn.com/image/fetch/$s_!vFJa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc83154-56b8-46ad-bd02-2e2b7f21fc2a_1225x486.png 1272w, https://substackcdn.com/image/fetch/$s_!vFJa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc83154-56b8-46ad-bd02-2e2b7f21fc2a_1225x486.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The line &#8220;Step two&#8221; never appears because panic halts the normal sequence. The runtime records the panic and starts moving up through the stack. If nothing stops it, the process continues until no deferred calls are left, at which point the goroutine ends with a panic message and stack trace.</p><p>A function with multiple levels of calls makes the unwinding process more visible:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pdmq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27815d3c-a8eb-4325-ac8f-a770afc95c9e_1284x382.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pdmq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27815d3c-a8eb-4325-ac8f-a770afc95c9e_1284x382.png 424w, https://substackcdn.com/image/fetch/$s_!pdmq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27815d3c-a8eb-4325-ac8f-a770afc95c9e_1284x382.png 848w, https://substackcdn.com/image/fetch/$s_!pdmq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27815d3c-a8eb-4325-ac8f-a770afc95c9e_1284x382.png 1272w, https://substackcdn.com/image/fetch/$s_!pdmq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27815d3c-a8eb-4325-ac8f-a770afc95c9e_1284x382.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pdmq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27815d3c-a8eb-4325-ac8f-a770afc95c9e_1284x382.png" width="1284" height="382" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27815d3c-a8eb-4325-ac8f-a770afc95c9e_1284x382.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:382,&quot;width&quot;:1284,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:44318,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173795459?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27815d3c-a8eb-4325-ac8f-a770afc95c9e_1284x382.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pdmq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27815d3c-a8eb-4325-ac8f-a770afc95c9e_1284x382.png 424w, https://substackcdn.com/image/fetch/$s_!pdmq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27815d3c-a8eb-4325-ac8f-a770afc95c9e_1284x382.png 848w, https://substackcdn.com/image/fetch/$s_!pdmq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27815d3c-a8eb-4325-ac8f-a770afc95c9e_1284x382.png 1272w, https://substackcdn.com/image/fetch/$s_!pdmq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27815d3c-a8eb-4325-ac8f-a770afc95c9e_1284x382.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The panic starts in <code>third</code>, but without recovery it climbs through <code>second</code> and <code>first</code> until it reaches <code>main</code>. The runtime prints a trace of all these frames so it&#8217;s easier to see where the panic originated.</p><h4>How Recover Stops the Panic</h4><p>Recover interrupts unwinding, but only when it&#8217;s called inside a deferred function that&#8217;s active during a panic. When it succeeds, it gives back the panic value and clears the panic state from the runtime. That action stops the stack from being unwound any further.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IzVO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F140c6e63-d360-4aff-998e-f9cd35683f39_1290x662.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IzVO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F140c6e63-d360-4aff-998e-f9cd35683f39_1290x662.png 424w, https://substackcdn.com/image/fetch/$s_!IzVO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F140c6e63-d360-4aff-998e-f9cd35683f39_1290x662.png 848w, https://substackcdn.com/image/fetch/$s_!IzVO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F140c6e63-d360-4aff-998e-f9cd35683f39_1290x662.png 1272w, https://substackcdn.com/image/fetch/$s_!IzVO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F140c6e63-d360-4aff-998e-f9cd35683f39_1290x662.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IzVO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F140c6e63-d360-4aff-998e-f9cd35683f39_1290x662.png" width="1290" height="662" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/140c6e63-d360-4aff-998e-f9cd35683f39_1290x662.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:662,&quot;width&quot;:1290,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:82517,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173795459?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F140c6e63-d360-4aff-998e-f9cd35683f39_1290x662.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IzVO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F140c6e63-d360-4aff-998e-f9cd35683f39_1290x662.png 424w, https://substackcdn.com/image/fetch/$s_!IzVO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F140c6e63-d360-4aff-998e-f9cd35683f39_1290x662.png 848w, https://substackcdn.com/image/fetch/$s_!IzVO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F140c6e63-d360-4aff-998e-f9cd35683f39_1290x662.png 1272w, https://substackcdn.com/image/fetch/$s_!IzVO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F140c6e63-d360-4aff-998e-f9cd35683f39_1290x662.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Execution skips over the statement after panic, but the deferred block regains control, prints the recovery message, and lets the function return normally. The process doesn&#8217;t rewind back into the statement after panic. Instead, it continues as if the function ended naturally once all deferred code is done.</p><p>Recover can also be used to pass information back to the caller. For example, a function can recover from a panic and then return a default value, giving the caller a fallback instead of an abrupt stop.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nrpK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39078503-d2d7-49b8-983d-b823ef1e03b6_1219x629.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nrpK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39078503-d2d7-49b8-983d-b823ef1e03b6_1219x629.png 424w, https://substackcdn.com/image/fetch/$s_!nrpK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39078503-d2d7-49b8-983d-b823ef1e03b6_1219x629.png 848w, https://substackcdn.com/image/fetch/$s_!nrpK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39078503-d2d7-49b8-983d-b823ef1e03b6_1219x629.png 1272w, https://substackcdn.com/image/fetch/$s_!nrpK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39078503-d2d7-49b8-983d-b823ef1e03b6_1219x629.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nrpK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39078503-d2d7-49b8-983d-b823ef1e03b6_1219x629.png" width="1219" height="629" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/39078503-d2d7-49b8-983d-b823ef1e03b6_1219x629.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:629,&quot;width&quot;:1219,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:75968,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173795459?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39078503-d2d7-49b8-983d-b823ef1e03b6_1219x629.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nrpK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39078503-d2d7-49b8-983d-b823ef1e03b6_1219x629.png 424w, https://substackcdn.com/image/fetch/$s_!nrpK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39078503-d2d7-49b8-983d-b823ef1e03b6_1219x629.png 848w, https://substackcdn.com/image/fetch/$s_!nrpK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39078503-d2d7-49b8-983d-b823ef1e03b6_1219x629.png 1272w, https://substackcdn.com/image/fetch/$s_!nrpK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39078503-d2d7-49b8-983d-b823ef1e03b6_1219x629.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The divide by zero panic is caught, and recover provides a way to supply a result to the caller instead of stopping everything.</p><h4>What If Recover Is Not Called</h4><p>If no deferred function calls recover, the panic continues to climb through the stack. Each deferred function still runs, which makes it possible to perform cleanup such as closing files or flushing buffers. But once the last deferred function has run, the goroutine ends, and if it&#8217;s the main goroutine, the process exits.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dyaL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab052269-f4ac-4b13-b13d-f5062ac81317_1351x456.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dyaL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab052269-f4ac-4b13-b13d-f5062ac81317_1351x456.png 424w, https://substackcdn.com/image/fetch/$s_!dyaL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab052269-f4ac-4b13-b13d-f5062ac81317_1351x456.png 848w, https://substackcdn.com/image/fetch/$s_!dyaL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab052269-f4ac-4b13-b13d-f5062ac81317_1351x456.png 1272w, https://substackcdn.com/image/fetch/$s_!dyaL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab052269-f4ac-4b13-b13d-f5062ac81317_1351x456.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dyaL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab052269-f4ac-4b13-b13d-f5062ac81317_1351x456.png" width="1351" height="456" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ab052269-f4ac-4b13-b13d-f5062ac81317_1351x456.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:456,&quot;width&quot;:1351,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:57178,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173795459?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab052269-f4ac-4b13-b13d-f5062ac81317_1351x456.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!dyaL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab052269-f4ac-4b13-b13d-f5062ac81317_1351x456.png 424w, https://substackcdn.com/image/fetch/$s_!dyaL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab052269-f4ac-4b13-b13d-f5062ac81317_1351x456.png 848w, https://substackcdn.com/image/fetch/$s_!dyaL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab052269-f4ac-4b13-b13d-f5062ac81317_1351x456.png 1272w, https://substackcdn.com/image/fetch/$s_!dyaL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab052269-f4ac-4b13-b13d-f5062ac81317_1351x456.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Even though the panic ends the run, the deferred call still executes. That&#8217;s why it&#8217;s safe to use defer for cleanup regardless of whether recover is used. The difference is that without recovery, execution doesn&#8217;t return to the caller.</p><p>This default behavior is helpful for debugging because the runtime prints the panic message and a full stack trace, which can reveal where the problem began and how it traveled through the call chain.</p><h4>Multiple Panics During Unwinding</h4><p>Panics can also occur inside deferred functions themselves. If a deferred call panics during the unwinding of another panic, the new panic takes precedence and replaces the original. This can make it harder to track down the first cause because only the most recent panic is reported.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Gvys!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67d4e1dc-cbf0-4c70-9849-7ccb509de5dd_1345x591.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Gvys!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67d4e1dc-cbf0-4c70-9849-7ccb509de5dd_1345x591.png 424w, https://substackcdn.com/image/fetch/$s_!Gvys!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67d4e1dc-cbf0-4c70-9849-7ccb509de5dd_1345x591.png 848w, https://substackcdn.com/image/fetch/$s_!Gvys!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67d4e1dc-cbf0-4c70-9849-7ccb509de5dd_1345x591.png 1272w, https://substackcdn.com/image/fetch/$s_!Gvys!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67d4e1dc-cbf0-4c70-9849-7ccb509de5dd_1345x591.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Gvys!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67d4e1dc-cbf0-4c70-9849-7ccb509de5dd_1345x591.png" width="1345" height="591" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/67d4e1dc-cbf0-4c70-9849-7ccb509de5dd_1345x591.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:591,&quot;width&quot;:1345,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:62105,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173795459?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67d4e1dc-cbf0-4c70-9849-7ccb509de5dd_1345x591.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Gvys!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67d4e1dc-cbf0-4c70-9849-7ccb509de5dd_1345x591.png 424w, https://substackcdn.com/image/fetch/$s_!Gvys!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67d4e1dc-cbf0-4c70-9849-7ccb509de5dd_1345x591.png 848w, https://substackcdn.com/image/fetch/$s_!Gvys!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67d4e1dc-cbf0-4c70-9849-7ccb509de5dd_1345x591.png 1272w, https://substackcdn.com/image/fetch/$s_!Gvys!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67d4e1dc-cbf0-4c70-9849-7ccb509de5dd_1345x591.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The output only reflects the panic from the deferred call, not the original one. The first panic is discarded.</p><p>Recovery still works in these cases, but it only captures the panic that&#8217;s active at the time it&#8217;s called. If multiple panics happen, only the most recent is available to recover.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!buEX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f08a562-229b-4b51-b3b0-23b00a5b838b_1355x662.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!buEX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f08a562-229b-4b51-b3b0-23b00a5b838b_1355x662.png 424w, https://substackcdn.com/image/fetch/$s_!buEX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f08a562-229b-4b51-b3b0-23b00a5b838b_1355x662.png 848w, https://substackcdn.com/image/fetch/$s_!buEX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f08a562-229b-4b51-b3b0-23b00a5b838b_1355x662.png 1272w, https://substackcdn.com/image/fetch/$s_!buEX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f08a562-229b-4b51-b3b0-23b00a5b838b_1355x662.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!buEX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f08a562-229b-4b51-b3b0-23b00a5b838b_1355x662.png" width="1355" height="662" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9f08a562-229b-4b51-b3b0-23b00a5b838b_1355x662.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:662,&quot;width&quot;:1355,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:71307,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://alexanderobregon.substack.com/i/173795459?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f08a562-229b-4b51-b3b0-23b00a5b838b_1355x662.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!buEX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f08a562-229b-4b51-b3b0-23b00a5b838b_1355x662.png 424w, https://substackcdn.com/image/fetch/$s_!buEX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f08a562-229b-4b51-b3b0-23b00a5b838b_1355x662.png 848w, https://substackcdn.com/image/fetch/$s_!buEX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f08a562-229b-4b51-b3b0-23b00a5b838b_1355x662.png 1272w, https://substackcdn.com/image/fetch/$s_!buEX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f08a562-229b-4b51-b3b0-23b00a5b838b_1355x662.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The recovery block only sees &#8220;secondary panic,&#8221; while the original &#8220;primary panic&#8221; disappears. That behavior means recovery logic needs to account for the fact that earlier panics can be overwritten during unwinding.</p><h3>Conclusion</h3><p>Deferred recover in Go works by pairing the guarantee of deferred calls with the ability to interrupt panic unwinding. A panic starts by halting execution and walking back through the stack, but a deferred recover function can catch that process, capture the panic value, and stop it from going further. The runtime then continues as though the function ended normally. This balance between automatic unwinding and targeted recovery gives Go a structured way to regain control without breaking the flow of deferred cleanup.</p><ol><li><p><em><a href="https://pkg.go.dev/builtin#panic">Go Panic and Recover</a></em></p></li><li><p><em><a href="https://go.dev/ref/spec#Defer_statements">Go Defer Statement</a></em></p></li><li><p><em><a href="https://pkg.go.dev/runtime">Go Runtime Package</a></em></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Alexander Obregon's Substack&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://alexanderobregon.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Alexander Obregon's Substack</span></a></p>]]></content:encoded></item></channel></rss>