Guide · Open source
How to use conc: structured concurrency in Go
Updated · written with AI from the project's own documentation and checked against our catalogue data
conc is an MIT-licensed Go library for running concurrent work in a more structured way. It is aimed at Go developers who use goroutines in long-running services and want fewer leaked goroutines and clearer concurrent code. After this guide you will know how to add conc to a Go project and use its WaitGroup and pool types.
Quick start
- 1Install the package. Run go get github.com/sourcegraph/conc in your Go project.
- 2Pick a type. Use conc.WaitGroup for a safer sync.WaitGroup, or a pool type for limits, results, errors or cancellation.
- 3Declare the owner. Create a var wg conc.WaitGroup in the function that starts the goroutines.
- 4Start work. Call wg.Go with the function you want to run concurrently.
- 5Defer Wait. Call wg.Wait before the owner goes out of scope so every goroutine finishes and any panic surfaces.
- 6Configure pools if needed. Call WithMaxGoroutines to cap concurrency, and WithErrors or WithContext for fallible tasks.
Install conc in your Go project
conc is a Go package, so the only prerequisite listed in the source is Go itself. Add the library to your project with the command from the README.
go get github.com/sourcegraph/concReplace sync.WaitGroup with conc.WaitGroup
The main type, conc.WaitGroup, is described as a safer version of sync.WaitGroup. Every goroutine you start with its Go method is owned by that WaitGroup, and Wait should always be called before the WaitGroup goes out of scope. A common pattern is to defer Wait right after declaring the WaitGroup.
If a goroutine needs to outlive the function that starts it, pass a pointer to the WaitGroup into the spawning function instead.
- Declare the WaitGroup with var wg conc.WaitGroup
- Start work with wg.Go(...)
- Call wg.Wait() before the owner returns, or defer it
func main() {
var wg conc.WaitGroup
defer wg.Wait()
startTheThing(&wg)
}
func startTheThing(wg *conc.WaitGroup) {
wg.Go(func() { ... })
}Understand how panics are handled
A goroutine started without a panic handler crashes the whole process when it panics. In conc, any call to Wait will panic if one of the spawned goroutines panicked. The panic value is decorated with a stack trace from the child goroutine, so the cause is not lost.
The README compares this with the standard library approach, which needs a custom error type, a channel, a deferred recover and debug.Stack. With conc, the same job is a single Go call followed by Wait.
func main() {
var wg conc.WaitGroup
wg.Go(doSomethingThatMightPanic)
// panics with a nice stacktrace
wg.Wait()
}Pick the right type for your task
Beyond WaitGroup, the README lists several types for common patterns. Choose based on what you need from the concurrent work.
- conc.WaitGroup: a safer sync.WaitGroup
- pool.Pool: a concurrency-limited task runner
- pool.ResultPool: a concurrent task runner that collects results
- pool.(Result)?ErrorPool: for tasks that can fail
- pool.(Result)?ContextPool: for tasks that should be canceled on failure
- stream.Stream: ordered tasks run in parallel with serial callbacks
- iter.Map and iter.ForEach: concurrent map or iteration over a slice
- panics.Catcher: catch panics in your own goroutines
Configure a pool
Pools are created with pool.New() or pool.NewWithResults[T](), then configured with methods. WithMaxGoroutines sets the maximum number of goroutines in the pool, which is the main way to limit concurrency. WithErrors, WithContext and WithFirstError adjust how failures are handled.
- p.WithMaxGoroutines() sets the goroutine limit
- p.WithErrors() lets tasks return errors
- p.WithContext(ctx) cancels tasks on first error
- p.WithFirstError() keeps only the first error instead of an aggregated one
Know who the library is for
conc suits Go developers who run goroutines in long-running services, teams that want clearer concurrent code, and anyone who needs a concurrency-limited task runner or ordered parallel streams. It assumes you already know goroutines and sync.WaitGroup, so it is not a first step for learning Go.
What people use it for
- Starting background goroutines in a long-running service without losing track of them
- Running a fixed number of tasks at once with pool.Pool and WithMaxGoroutines
- Collecting results from concurrent tasks with pool.ResultPool
- Mapping or iterating over a slice concurrently with iter.Map or iter.ForEach
- Processing an ordered stream of tasks in parallel with stream.Stream
Frequently asked questions
How do I install conc?
Run go get github.com/sourcegraph/conc in your Go project. The README lists Go as the only prerequisite.
Is conc free to use?
conc is released under the MIT licence, as stated in the project information. Check the LICENSE file in the repository for the full terms.
What does conc.WaitGroup do differently from sync.WaitGroup?
Every goroutine started with conc.WaitGroup has an owner that must wait for it, which helps prevent leaked goroutines. Wait also re-raises any panic from a spawned goroutine, with a stack trace, so failures are not silently lost.
Can I use conc outside Go?
No. conc is only a Go package, so it does not help users of other languages.
What are good alternatives to conc?
The project information lists errgroup (golang.org/x/sync/errgroup), ants and tunny as comparable projects. Pick based on whether you need error handling, a worker pool or ordered streams.
Does conc add dependencies to my project?
The README does not discuss its dependency footprint. If you need zero dependencies and only the standard library, check the module's dependencies yourself before adopting it.
New agent skills, repos and AI tools — every week
The best new skills and open-source projects, the fastest-growing repos, and one free prompt. Five minutes to read. Unsubscribe anytime.
Our verdict
conc is a good fit for Go teams running long-lived services who want fewer leaked goroutines, automatic panic propagation and clearer concurrent code. If you are new to Go, need only the standard library with no dependencies, or do not use Go at all, pick something else such as the standard sync package or a simpler alternative.
Install options & downloads