Golang / Golang Internals and Memory Management Interview Questions
How do you implement a worker pool in Go?
A worker pool limits the number of goroutines working concurrently, preventing resource exhaustion when processing a large number of tasks. It is one of the most common Go concurrency patterns.
// Classic worker pool pattern func workerPool(ctx context.Context, jobs <-chan Job, results chan<- Result, numWorkers int) { var wg sync.WaitGroup for i := 0; i < numWorkers; i++ { wg.Add(1) go func(id int) { defer wg.Done() for { select { case <-ctx.Done(): return // cancelled case job, ok := <-jobs: if !ok { return } // channel closed â no more jobs result := process(job) select { case results <- result: case <-ctx.Done(): return } } } }(i) } // Close results after all workers finish go func() { wg.Wait() close(results) }() } // Usage const numWorkers = 10 jobs := make(chan Job, 100) results := make(chan Result, 100) ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() workerPool(ctx, jobs, results, numWorkers) // Feed jobs go func() { defer close(jobs) for _, job := range allJobs { select { case jobs <- job: case <-ctx.Done(): return } } }() // Collect results for r := range results { fmt.Println(r) }
The worker pool pattern ensures bounded concurrency — with virtual threads in other languages this is less critical, but in Go it matters when each goroutine holds OS resources (database connections, file handles) that are finite. Set numWorkers based on the resource constraint: for I/O-bound work constrained by a connection pool of size N, use N workers. For CPU-bound work, use runtime.NumCPU() workers.
More Related questions...