sync/errgroup for Go: A Complete Guide with Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course
\n

sync/errgroup for Go: A Complete Guide with Examples

\n\n
\n

1. What It Is and Why You Need It

\n

\n The sync/errgroup library is part of the official golang.org/x/sync extension, providing a powerful and elegant way to manage concurrent goroutines with error handling. The standard Go library has the sync package with WaitGroup, but it cannot collect errors from goroutines. errgroup solves this problem: you launch several goroutines, and if at least one of them returns an error, the group immediately (or upon completion of all) signals this, canceling the context and allowing the remaining goroutines to terminate gracefully.\n

\n

\n Why is this needed? In real applications, you often need to execute several independent tasks in parallel: download files, process data, make API requests. If one task fails with an error, there is no point in continuing the others — you need to stop quickly and return the error to the user. errgroup does this automatically: you pass a context, and upon the first error, the context is canceled, and all goroutines listening to this context can terminate early.\n

\n

\n This is especially useful in microservices, web servers, and CLI utilities where fast error response is important. Unlike manual management with channels and select, errgroup provides a clean, declarative API that is difficult to misuse.\n

\n
\n\n
\n

2. Installation

\n

\n sync/errgroup is not part of the Go standard library, but is part of the golang.org/x/sync submodule. Installation is done with a single command:\n

\n
go get golang.org/x/sync/errgroup
\n

\n After that, you can import the package into your code:\n

\n
import "golang.org/x/sync/errgroup"
\n

\n Make sure you have Go version 1.13 or higher installed (1.18+ is recommended for generics support, although errgroup does not use them). If you are using modules (go.mod), the go get command will automatically update the go.sum file.\n

\n
\n\n
\n

3. Quick Start — Minimal Working Example

\n

\n Below is a simple example that launches three goroutines, each of which returns an error if the passed number is negative. If at least one goroutine returns an error, errgroup.Wait() will return it.\n

\n
package main\n\nimport (\n    "context"\n    "fmt"\n    "golang.org/x/sync/errgroup"\n)\n\nfunc main() {\n    g, ctx := errgroup.WithContext(context.Background())\n\n    numbers := []int{1, -2, 3}\n    for _, n := range numbers {\n        n := n // capture variable\n        g.Go(func() error {\n            select {\n            case <-ctx.Done():\n                return ctx.Err()\n            default:\n            }\n            if n < 0 {\n                return fmt.Errorf("negative number: %d", n)\n            }\n            fmt.Printf("Processed %d\\n", n)\n            return nil\n        })\n    }\n\n    if err := g.Wait(); err != nil {\n        fmt.Printf("Error: %v\\n", err)\n    } else {\n        fmt.Println("All tasks completed successfully")\n    }\n}
\n

\n Output: Processed 1, Processed 3, Error: negative number: -2. Note that the goroutine with the number 3 might not have executed if the context was canceled before it started — this demonstrates the early stopping mechanism.\n

\n
\n\n
\n

4. Main Methods/Functions

\n

Below are all the key API elements of the errgroup package. Each method is accompanied by its signature, description, and a working example.

\n\n

4.

Recommendations