The reverse proxy

A reverse proxy that never needs a database to remember who's abusing it.

Scrapers, credential-stuffing, runaway agentic retry loops, repeat LLM prompts — all of them are the same shape: infinite-cardinality traffic a fixed-memory structure was built to handle. SketchProxy wires epochsketch straight into net/http and httputil.ReverseProxy. One dependency, one binary, no cache cluster.

View source →Back to Ecosystem
#01

Request lifecycle

Prompt Cachekeyed on IP + Auth + bodyAgentic Loop Breakerobserves 5xx outcomes, not volumeWallet Defensekeyed on Authorization headerRate Limitkeyed on IP + PathReverseProxythe actual backend callmissnot trippedunder thresholdunder thresholdhit →served from memory, nothing below runstripped →503, backend never calledover threshold →429over threshold →429, or tarpit band: delayed forward
A decision made early skips everything below it. Rate limit and wallet defense read two different signals (IP+Path vs. Authorization) — either can reject a request the other would have let through. The loop breaker reads response outcomes, not request volume, so it sits outside both. Only a request that clears all four gates reaches the real backend.
#02

Features

FeatureGates onOwn Sketch?
Rate limitRequest volume per IP+PathYes
TarpitThe volume band just below the drop thresholdReuses rate limit's estimate
Wallet defenseRequest volume per Authorization headerYes, dedicated
Prompt cacheLLM request/response caching, keyed on IP+Auth+bodyYes, feeds admission's TinyLFU filter
Anomaly webhookFirst-sighting keys (first == true)Reuses rate limit's Observe
Agentic loop breakerBackend 5xx frequency per caller+pathYes, dedicated, Observed only on 5xx
#03

Quick start

Shell
# flags
go run ./cmd/sketchproxy -listen :8080 -target http://localhost:5000

# or a config file — CLI flags always override it
go run ./cmd/sketchproxy -config config.yaml
#04

Example config

config.yaml
server:
  listen_addr: ":8080"
  target_url: "http://localhost:5000"

rate_limit:
  enabled: true
  threshold: 100          # estimate at which a caller+path gets 429'd

tarpit:
  enabled: true
  threshold: 50            # must be < rate_limit.threshold
  delay: 2s
  max_concurrent: 1000

agentic_loop_breaker:
  enabled: false
  threshold: 5              # 5xx-frequency estimate that trips the breaker
#05

Performance

Measured with go test -bench=. -benchmem (Apple M4 Pro; treat as relative, not absolute, on other hardware).

Benchmarkns/opallocs/op
Pre-EpochSketch baseline~35,20071
IP+Path key extraction~140
Auth key extraction~220
Full pipeline, concurrent~14,10083

The two key-extraction benchmarks are what matter most for the hot path — zero allocations, whether the key comes from the request line or a header.

#06

Docker

Shell
docker run -p 8080:8080 ghcr.io/shyam-s00/epochsketch/sketchproxy:latest \
  -target http://host.docker.internal:5000
#07

Deliberately not

A backend-wide circuit breakerA general HTTP cacheDistributed / cross-instance state