errgroup
Use `errgroup` when sibling goroutines should return the first error and share cancellation.
Canonical guidance
- prefer
errgroupfor sibling tasks that can fail independently - derive a shared context with
errgroup.WithContext - return errors directly from worker functions
Use when
- parallel fetches
- fan-out request handling
- bounded multi-step workflows
Avoid
- using
WaitGroupplus custom error channels for the same pattern - ignoring the derived context inside worker calls
- forcing
errgroupinto fire-and-forget work
Preferred pattern
g, ctx := errgroup.WithContext(ctx)
for _, id := range ids {
g.Go(func() error {
return fetchOne(ctx, id)
})
}
if err := g.Wait(); err != nil {
return err
}
Anti-pattern
- parallel code that has three separate mechanisms for waiting, canceling, and collecting errors
Explanation: This anti-pattern is tempting because each piece seems simple, but the combination quickly becomes lifecycle glue the standard helper already solved.
Why
errgroupcompresses a common concurrency pattern into one readable abstraction
Related pages
Sources
- golang.org/x/sync/errgroup package - Go Authors
- Not using errgroup (#73) - Teiva Harsanyi