Skip to main content

Posts

Showing posts with the label Golang

Go 1.23+ Concurrency Patterns: Migrating from Channels to iter.Seq

  For over a decade, Go developers have abused channels. Lacking a standard iterator interface, we turned to buffered channels and goroutines to implement generator patterns. We treated   chan T   as an   Iterator<T> , spawning goroutines just to iterate over paginated API responses, file lines, or database rows. While syntactically elegant, this pattern is a performance trap. With the release of Go 1.23 and the standardization of the  iter  package (via the "range over func" experiment becoming standard), we can finally stop using concurrency primitives for sequential logic. The Root Cause: The Hidden Cost of Channel Iteration Using channels for simple iteration introduces unnecessary  scheduler overhead  and  memory contention . When you spawn a goroutine to feed a channel solely for iteration (the Producer-Consumer pattern applied to sequential data), you incur the following costs: Context Switching:  Every time the channel buff...

Go Concurrency: Refactoring Channel Pipelines to the `iter` Package for Lower GC Pressure

  For over a decade, the idiomatic way to implement lazy generators or data pipelines in Go was the "concurrency pattern": spin up a goroutine, push data into a channel, and close the channel when done. While elegant, this pattern abuses Go's concurrency primitives for sequential logic. Using channels for simple iteration incurs significant performance penalties: heavy Garbage Collector (GC) pressure from short-lived goroutine stacks, scheduler overhead (context switching), and the risk of goroutine leaks if the consumer exits early. With Go 1.23, the standard library introduced the  iter  package. This allows us to refactor push-based channel generators into pull-based iterators, eliminating the concurrency overhead entirely while maintaining the ergonomics of  for-range  loops. The Root Cause: Why Channels Are Expensive for Iteration When you use a channel merely to stream data from point A to point B without parallel processing, you incur costs at three layer...