Throttling Goroutines
Control concurrency.
Throttling Goroutines is a free Go Academy lesson on CoddyKit. This is lesson 3 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, and your progress syncs across the web and the CoddyKit app. The Go Academy course includes 4 lessons in total.
Throttling Concurrency
Sometimes you do not limit per second, you limit how many goroutines run at once. This caps simultaneous load on a resource regardless of timing.
- Bounds parallelism
- Protects connection pools
- Prevents memory spikes
The Semaphore Channel
A buffered channel works as a counting semaphore. Its capacity equals the maximum concurrency. Acquiring sends a token; releasing receives one.
sem := make(chan struct{}, 3)Acquire and Release
Before starting work, send into the channel to acquire a slot (blocks if full). When done, receive to release it, freeing the slot for another goroutine.
sem <- struct{}{} // acquire
// do work
<-sem // releaseWhy struct{}
An empty struct struct{}{} occupies zero bytes. Using it as the channel element makes the semaphore a pure signal with no wasted memory.
Throttling a Loop
Launch a goroutine per task but gate each on the semaphore. At most cap goroutines do real work concurrently; the rest block at acquire.
for _, task := range tasks {
sem <- struct{}{}
go func(t Task) {
defer func() { <-sem }()
process(t)
}(t)
}Pairing with WaitGroup
The semaphore bounds concurrency but does not tell you when everything finishes. Combine it with a sync.WaitGroup to wait for all tasks.
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
defer func() { <-sem }()
process(t)
}()Release in defer
Always release in a defer so the slot frees even if the work panics or returns early. Forgetting to release leaks slots and eventually deadlocks new acquirers.
A Complete Throttled Run
This program runs eight tasks with at most two concurrent, printing start and end to show the cap in action.
package main
import (
"fmt"
"sync"
"time"
)
func main() {
sem := make(chan struct{}, 2)
var wg sync.WaitGroup
for i := 0; i < 8; i++ {
wg.Add(1)
sem <- struct{}{}
go func(id int) {
defer wg.Done()
defer func() { <-sem }()
fmt.Println("start", id)
time.Sleep(20 * time.Millisecond)
fmt.Println("end", id)
}(i)
}
wg.Wait()
fmt.Println("done")
}errgroup with SetLimit
The golang.org/x/sync/errgroup package offers SetLimit to throttle a group and propagate the first error. It is a cleaner alternative for many cases, though it is an external package.
Throttling vs Worker Pool
A worker pool reuses a fixed set of goroutines pulling from a queue. Semaphore throttling spawns a goroutine per task but caps active ones. Pools are leaner for huge task counts; semaphores are simpler to bolt on.
Choosing the Limit
For database calls, set the limit at or below your connection pool size. For outbound HTTP, match the host connection limit. Too high causes resource exhaustion; too low wastes capacity.
Quick Check
Test your throttling knowledge.
Recap
You learned goroutine throttling:
- A buffered channel acts as a counting semaphore
- Acquire by send, release by receive in defer
- struct{} elements cost zero bytes
- Pair with WaitGroup to wait for completion
- Size the limit to the protected resource
Learn Go with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 51
- Lessons
- 203
Frequently Asked Questions
Is the “Throttling Goroutines” lesson free?
Yes — any 3 lessons of the Go Academy learning path, including “Throttling Goroutines”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Go Academy course includes 4 lessons in total.
What will I learn in “Throttling Goroutines”?
Control concurrency. 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, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 4.
How long does the “Throttling Goroutines” 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
- Token Bucket Concept
- golang.org/x/time/rate
- Throttling Goroutines
- Backoff and Retry