request path
Walk of GET /alice/stats with Redis on. platform="tuf". TUF is the sibling that also speaks Upstash REST besides a wire URL.
- CORS middleware (added first, runs second).
CacheRateLimitMiddlewarewithplatform="tuf"(added last, runs first).- Skip check. Path is not
/,/docs,/redoc,/openapi.json,/favicon.ico. Method is GET. Redis is on. - Handle is the first path segment, lowercased:
alice. - Cache key is
cache:tuf:{sha256(GET:/alice/stats:sorted_query)}. - On HIT, body is base64-decoded and returned with
X-Cache: HIT. Done. - Negative key
invalid:tuf:alice. On HIT, HTTP 404User does not exist,X-Cache: NEGATIVE-HIT. Invalid-user rate limits apply (10/IP and 5/handle per 10 minutes). - Live limits: 60 req/min per IP, 30 req/min per handle. Over: 429 with
Retry-Afterand exponential backoff 5s to 300s. - Route
fetch_dsa_progress. Contests, rating, and badges still call that fetch so a missing user 404s, then return empty models. make_envelopewraps it. HTTP 200 cached for 3600s unlessCache-Controlsays otherwise.X-Cache: MISS.
Without Redis, steps 5 to 8 disappear. Every GET hits backend-go.takeuforward.org. Rate limits disappear too.
redis_enabled() is true if TUF_REDIS_URL or REDIS_URL is set, or both UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN. Integer knobs also accept a TUF_ prefix (TUF_API_CACHE_TTL_SECONDS wins over API_CACHE_TTL_SECONDS).
Invalid-user markers add "username not found" on top of the family list. TUF’s Go backend uses that wording.
sequenceDiagram
participant B as Browser
participant MW as CacheRateLimit
participant R as Redis or Upstash
participant RT as stats route
participant GO as backend-go.takeuforward.org
B->>MW: GET /alice/stats
MW->>R: GET cache:tuf:digest
alt hit
R-->>MW: body
MW-->>B: 200 X-Cache HIT
else miss
MW->>R: GET invalid:tuf:alice
MW->>R: INCR rl:ip and rl:handle
MW->>RT: call_next
RT->>GO: v1/progress/dsa/alice
RT-->>MW: envelope
MW->>R: SETEX cache 3600s
MW-->>B: 200 X-Cache MISS
endIP is X-Forwarded-For first hop, else X-Real-IP, else request.client.host.
/playground is not in SKIP_PATHS. With Redis on, the first path segment is treated as handle playground. Playground sample handle is striver.
Redis env#
Wire URL or Upstash REST. Redis errors fail open: cache miss, rate limit allow.
| Env | Default |
|---|---|
TUF_REDIS_URL or REDIS_URL |
unset |
UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN |
unset |
API_CACHE_TTL_SECONDS (or TUF_API_CACHE_TTL_SECONDS) |
3600 |
INVALID_USER_CACHE_TTL_SECONDS |
300 |
RATE_LIMIT_IP_REQUESTS |
60 per 60s |
RATE_LIMIT_HANDLE_REQUESTS |
30 per 60s |
INVALID_RATE_LIMIT_IP_REQUESTS |
10 per 600s |
INVALID_RATE_LIMIT_HANDLE_REQUESTS |
5 per 600s |
RATE_LIMIT_BACKOFF_BASE_SECONDS |
5 |
RATE_LIMIT_BACKOFF_MAX_SECONDS |
300 |
Keys:
cache:tuf:{sha256}invalid:tuf:{handle}rl:ip:tuf:{ip}/rl:handle:tuf:{handle}backoff:{same}/violations:{same}