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.