Skip to content

Go Goroutine WaitGroup: Not Waiting

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about Go Goroutine WaitGroup: Not Waiting. We cover key concepts, practical examples, and best practices.

WaitGroup usage -- Use sync.WaitGroup correctly by calling Add() before the goroutine starts, not inside it.

The Problem

Calling wg.Add() inside the goroutine creates a race condition. The main goroutine may call wg.Wait() before Add() executes, causing premature exit.

Wrong

var wg sync.WaitGroup
for i := 0; i < 5; i++ {
    go func() {
        wg.Add(1) // TOO LATE!
        defer wg.Done()
        work()
    }()
}
wg.Wait() // May exit before all Add() calls!

Output:

// Race condition. WaitGroup may return early.
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
    wg.Add(1) // Correct: call before goroutine
    go func() {
        defer wg.Done()
        work()
    }()
}
wg.Wait() // Waits for all 5 goroutines

Output:

// All goroutines complete before main exits

Prevention

  • Call wg.Add() before starting the goroutine
  • Use defer wg.Done() inside the goroutine
  • wg.Wait() blocks until counter reaches 0
  • Do not pass wg by value (no copy)
  • Use wg.Add() with known count for bounded parallelism

Common Mistakes with goroutine wait group

  1. Using return to exit a function early instead of wrapping a pure value in the monad
  2. Mixing let bindings with <- bindings in do notation, producing type errors
  3. Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors

These mistakes appear frequently in real-world GO code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

**Can I reuse a WaitGroup?**

Yes. Wait for completion, then Add again.

What if I Add after Wait?

Panic: WaitGroup is reused before previous Wait returns.

How to handle errors in goroutines?

Use errgroup instead of WaitGroup for error propagation.


Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. DodaTech tutorials help Go developers build production-ready software used by millions.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro