Go Internals

What are the limits of Go channels?

By the message size, maximum allocation, and performance

Pavel Fokin
3 min readJun 26, 2022
What are the limits of Go channels?

Did you ever think about the limits of Go channels? I decided to look into the golang repo to find out how channels are created.

Here is what I found out.

Making a channel

I started by looking for the code of the function that creates a channel. Not surprisingly I could find it in the runtime/chan.go file.

Function makechannel has the following signature.

makechan function

Then let’s review what are the chantype and hchan types.

Channel types

A chantype is a wrapper for a _type struct.

chantype struct

A _type type is an underlying struct for any go type, and it looks as follows.

_type struct

Then let’s take a look on the hchan type.

hchan struct

Let’s move forward and look into the makechan function.

Message size

When we start from the beginning of the makechan function. We can see that it checks for a size of the future channel’s message.

Maximum message size

And the maximum message size is 2¹⁶ bytes, or 64 kilobytes.

Maximum allocation

The next step is to check the size of the memory that can be allocated for a new channel.

memory allocation

What is the maxAlloc size?

maxAlloc

The maxAlloc determines the maximum memory size that is theoretically allowed. On the 64-bit Unix-like systems this is 2⁴⁷ bytes (~140 Terabytes).

Though, it allows allocating up to 140 Terabytes. You will meet the memory issues if you will try to do so 😄.

Performance

By the following naive benchmark, we can measure the upper limits for the send/receive operations.

Naive channels benchmark

The send and receive operations are mainly spending time in the goroutine’s context switching. On my machine, this number is stably <100 ns.

➜  channels git:(main) ✗ go test -bench=.
goos: darwin
goarch: arm64
pkg: pavel-fokin/go-patterns/concurrency/channels
BenchmarkUnbufferedChannelInt-8 11091662 107.5 ns/op
BenchmarkBufferedChannelInt-8 15082126 80.11 ns/op
PASS
ok pavel-fokin/go-patterns/concurrency/channels 7.021s

Final thoughts

Looking into the Go internals is definitively worth it. You not only can see the details of implementation but also learn best practices.

Happy coding!

Further readings

If you like this article you can be interested in the following.

--

--