Help us shape the future of Go! Take the 2026 Go Developer Survey

throttle

package
v0.2.50 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 22, 2026 License: MPL-2.0 Imports: 2 Imported by: 0

Documentation

Overview

Package throttle is a small per-key fixed-window rate limiter. It exists to gate the chassis's unsigned credential-mint endpoints (`/auth/dev/enroll`, `/auth/invitations/consume`) against brute-force probing without dragging in a full rate-limit library.

Sizing rationale: state is one int + one timestamp per active key (typically the caller's IP). Lazy cleanup on every Allow evicts buckets older than 2× the window so the map stays bounded under churn even when long-lived attackers cycle through IPs.

What this is NOT:

  • distributed (single process; restart resets counters)
  • sliding-window (boundary-burst behaviour is acceptable for our anti-abuse threat model)
  • per-user (caller carries no identity at the gate; that's the point of throttling unsigned endpoints)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Throttle

type Throttle struct {
	// contains filtered or unexported fields
}

Throttle is a per-key fixed-window counter. Zero value is not usable — call New.

func New

func New(limit int, window time.Duration) *Throttle

New returns a Throttle that admits up to `limit` attempts per `window` per key.

limit == 0 (or negative) disables the throttle: every Allow call returns ok=true. This is the cheap kill switch used by tests and by operators setting TXCO_THROTTLE_DISABLED=1.

window must be positive when limit > 0; a zero window would make every attempt count toward the same eternal bucket. The constructor clamps to 1s in that case rather than panicking — defensive against env-misconfiguration without surfacing an error to startup.

func (*Throttle) Allow

func (t *Throttle) Allow(key string) (bool, time.Duration)

Allow records an attempt for key. Returns (true, 0) when the attempt is below threshold (and the count has been bumped); returns (false, retryAfter) when the bucket is exhausted, where retryAfter is the remaining duration in the current window.

Disabled throttles (limit==0) always return (true, 0) without touching state.

Side effect: lazy cleanup of stale buckets. On each call we sweep the map and drop any bucket whose resetAt is more than `window` in the past — that's twice the active-window age, so we never evict a bucket that's still counting. Cleanup is O(n) in map size but n is bounded by recent unique callers, which is small in practice.

func (*Throttle) Size

func (t *Throttle) Size() int

Size returns the number of live buckets. Exported for tests that assert the lazy cleanup actually evicts; not intended for callers to inspect at runtime.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL