Skip to main content
Version: Next (unreleased)

Rate Limiter

Worker count limits how many jobs run at once. RateLimiter limits how many are submitted per unit of time — useful when the downstream system has a rate limit of its own, such as an API that allows 10 calls per second.

Tokens are spent at submission, not when a worker starts the job. If jobs back up in the queue, they can reach the downstream system in bursts above the rate. Keep the queue short, or enforce the limit inside the job when the downstream limit is strict.

rl := worker.NewRateLimiter(pool, 10, time.Second) // 10 jobs per second
defer rl.Stop()

for _, msg := range messages {
err := rl.Submit(ctx, worker.JobFunc(func(ctx context.Context) error {
return smsAPI.Send(ctx, msg)
}))
if err != nil {
return err
}
}

NewRateLimiter(pool, n, interval) panics if n < 1 or interval <= 0.

How tokens work​

The limiter holds up to n tokens and starts full. Every submit spends one. Every interval, the bucket is topped back up to n.

Because it refills in steps rather than continuously, up to n jobs can start back to back at the start of each interval. If the downstream limit is strict about spacing, use a smaller n over a shorter interval: 1 per 100ms rather than 10 per second.

Submitting​

MethodWithout a tokenReturns
Submit(ctx, job)waits for one, or for ctx to endnil, ctx.Err(), a pool error, or ErrLimiterStopped
TrySubmit(job)returns ErrRateLimitednil, ErrRateLimited, a pool error, or ErrLimiterStopped

Submit submits with SubmitContext, so the job runs with a context derived from ctx. If ctx is cancelled after the job is queued, the job is cancelled too.

If the pool rejects a job — ErrPoolFull from TrySubmit, ErrPoolClosed from either — the token is returned to the bucket.

Stopping​

Stop stops the refill goroutine. Afterwards, both submit methods return ErrLimiterStopped, including a Submit that was waiting for a token. Always stop a limiter you no longer need, or its goroutine runs for the life of the process.

Rate limiting HTTP traffic?​

RateLimiter limits jobs going into a pool. To limit requests coming into an HTTP server, per client, see go-ratelimit.