0Pricing
Go Academy · Lesson

sync.WaitGroup

Waiting for a collection of goroutines

sync.WaitGroup is a free Go Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Purpose

sync.WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the count, each goroutine calls Done when complete, and Wait blocks until the count reaches zero.

Basic usage

Add before launching each goroutine; Done at the end of each goroutine (via defer); Wait after launching all goroutines.

var wg sync.WaitGroup
for _, item := range items {
    wg.Add(1)
    go func(v Item) {
        defer wg.Done()
        process(v)
    }(item)
}
wg.Wait()

Add must happen before goroutine starts

Call wg.Add(1) before go func(), never inside the goroutine. Otherwise Wait might return before the goroutine registers itself.

Common mistake: loop variable capture

Pass the loop variable as an argument to the goroutine function, not via closure, to avoid all goroutines sharing the same variable.

for _, v := range items {
    wg.Add(1)
    go func(item Item) { // correct: copy
        defer wg.Done()
        process(item)
    }(v)
}

Reusing a WaitGroup

A WaitGroup may be reused after Wait returns, but only if all previous Done calls have returned. Do not reuse concurrently with outstanding Done calls.

WaitGroup with results

WaitGroup does not collect results — combine it with a channel or a slice (with mutex) to gather output from goroutines.

results := make([]Result, len(items))
for i, item := range items {
    wg.Add(1)
    go func(idx int, v Item) {
        defer wg.Done()
        results[idx] = process(v)
    }(i, item)
}
wg.Wait()

Add with batch count

You can pass the total count to a single Add call before the loop, which is slightly more efficient than one Add per goroutine.

wg.Add(len(items))
for _, item := range items {
    go func(v Item) { defer wg.Done(); process(v) }(item)
}

Do not copy a WaitGroup

Like Mutex, a WaitGroup must not be copied after first use. Pass by pointer or embed in a struct passed by pointer.

WaitGroup vs errgroup

golang.org/x/sync/errgroup wraps WaitGroup and adds error propagation. Prefer errgroup when any goroutine failure should stop others.

Combining with context

Use errgroup.WithContext to get both WaitGroup semantics and a context that is cancelled on the first error, cleanly stopping all goroutines.

g, ctx := errgroup.WithContext(context.Background())
g.Go(func() error { return doWork(ctx) })
if err := g.Wait(); err != nil { log.Fatal(err) }

Zero value is usable

sync.WaitGroup zero value is ready to use — no constructor needed. Just declare it and call Add.

Quick Check

What happens if you call wg.Add(1) inside the goroutine instead of before launching it?

Recap: sync.WaitGroup

Key points:

  • Add before goroutine launch; Done via defer inside goroutine
  • Wait blocks until count reaches zero
  • Never copy; never Add inside goroutine
  • Use errgroup for error propagation

Frequently asked questions

Is the “sync.WaitGroup” lesson free?

Yes — the full text of “sync.WaitGroup” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.

What will I learn in “sync.WaitGroup”?

Waiting for a collection of goroutines You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Go Academy?

No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “sync.WaitGroup” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Go Academy lesson?

Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. sync.Mutex and sync.RWMutex
  2. sync.WaitGroup
  3. sync.Once and sync.Map
  4. Race Detector and Safe Patterns
← Back to Go Academy