Web presence of Neil O'Toole.


I’m a big fan of the Go stdlib sync/errgroup package. The errgroup.Group type makes it trivial to manage multiple worker goroutines that all need to succeed, and often obviates the need for sync.WaitGroup.

However, both in personal and client projects, I regularly ran into the issue where I wanted to rate-limit the number of simultaneous goroutines. An example would be where the goroutines are calling a backend API (or DB) that itself has rate limits.

I created the neilotoole/errgroup package as a drop-in replacement for stdlib errgroup. You use it like so:

import ""

func main() {
  numG, qSize := 8, 4
  g, ctx := errgroup.WithContextN(ctx, numG, qSize)
  g.Go(func() error {
    // do something
    return nil

The numG and qSize params control the gating behavior of the Group. In benchmarks, this implementation often outperforms stdlib errgroup, but obviously take your own benchmarks for your specific workload.

UPDATE 2023-01-10: The Go team have updated sync/errgroup with a Group.SetLimit method, which eliminates the need for my implementation (and their implementation is superior too). You should use sync/errgroup instead; I’m happily retiring neilotoole/errgroup.