Skip to content

feat(git): add per-client clone rate limiting#244

Draft
worstell wants to merge 1 commit intomainfrom
eworstell/per-client-rate-limit
Draft

feat(git): add per-client clone rate limiting#244
worstell wants to merge 1 commit intomainfrom
eworstell/per-client-rate-limit

Conversation

@worstell
Copy link
Copy Markdown
Contributor

@worstell worstell commented Apr 1, 2026

Add a per-client-IP concurrent clone limiter to prevent a single client from monopolizing all clone capacity. When a client exceeds the configured limit, requests are rejected with 429 Too Many Requests and a Retry-After header.

Changes

  • ratelimit.go: ClientCloneTracker tracks in-flight clone count per client IP. TryAcquire returns a release function on success, or false when the limit is reached. Thread-safe, cleans up entries when all slots are released.
  • Config.MaxClonesPerClient: HCL-configurable via max-clones-per-client in the git strategy block. Defaults to 0 (disabled).
  • submitClone: Extracted from handleRequest to encapsulate clone submission with rate limiting. Returns 429 when the client exceeds the limit; otherwise submits the clone job and serves via spool/upstream.
  • cachew.git.clone_rejections_total: New OTel counter with client attribute for observability.

How it works

  1. When a git request arrives for a repo in StateEmpty, submitClone checks the per-client tracker before submitting the clone job.
  2. If the client has fewer than max-clones-per-client in-flight clones, a slot is acquired and the clone job is submitted. The slot is released when the clone completes.
  3. If the client is at the limit, the request is rejected with 429 and a Retry-After: 30 header. No clone is submitted.
  4. When disabled (max-clones-per-client = 0, the default), behavior is unchanged.

Testing

  • Unit tests for acquire/release, idempotent release, concurrent contention, entry cleanup, and IP extraction.
  • All existing tests pass.

Add a per-client-IP concurrent clone limiter to prevent a single client
from monopolizing all clone capacity. When a client exceeds the
configured limit, requests are rejected with 429 Too Many Requests
and a Retry-After header.

Configurable via max-clones-per-client in the git strategy config
block. Defaults to 0 (disabled). The tracker counts in-flight clones
per client IP and releases slots when clone jobs complete.

New metric cachew.git.clone_rejections_total (by client IP) provides
observability into rate-limited requests.

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019d4a57-1477-707c-bb89-5543fddff0e7
@worstell worstell force-pushed the eworstell/per-client-rate-limit branch from ac55e5b to f75e12e Compare April 1, 2026 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant