Errgroup

Concurrent work with first-error cancellation using errgroup.

package main

import (
	"context"
	"fmt"
	"time"

	"golang.org/x/sync/errgroup"
)

func fetchURL(ctx context.Context, url string) error {
	// Simulate fetching
	select {
	case <-time.After(200 * time.Millisecond):
		if url == "https://fail.example.com" {
			return fmt.Errorf("failed to fetch %s", url)
		}
		fmt.Println("fetched:", url)
		return nil
	case <-ctx.Done():
		return ctx.Err()
	}
}

func main() {
	urls := []string{
		"https://go.dev",
		"https://pkg.go.dev",
		"https://fail.example.com",
		"https://example.com",
	}

	g, ctx := errgroup.WithContext(context.Background())
	g.SetLimit(2) // max 2 concurrent

	for _, url := range urls {
		url := url
		g.Go(func() error {
			return fetchURL(ctx, url)
		})
	}

	if err := g.Wait(); err != nil {
		fmt.Println("error:", err)
	} else {
		fmt.Println("all succeeded")
	}
}

💻 Run locally

Copy the code above and run it on your machine

© 2026 ByteLearn.dev. Free courses for developers. · Privacy