Skip to content

Exempt read-only requests from demo-mode rate limit#8

Merged
Ho1yShif merged 1 commit into
mainfrom
fix/demo-rate-limit-exempt-safe-methods
Jul 14, 2026
Merged

Exempt read-only requests from demo-mode rate limit#8
Ho1yShif merged 1 commit into
mainfrom
fix/demo-rate-limit-exempt-safe-methods

Conversation

@Ho1yShif

Copy link
Copy Markdown
Collaborator

Problem

On the public demo (DEMO=true), normal browsing gets 429d. A HAR from /home showed read-only GETs — /api/v1/settings, /api/v1/tools, /api/v1/knowledge/list, /api/v1/settings/llm-options — all returning 429 with Retry-After: 30.

Root cause

The demo HTTP catch-all (deeptutor/api/main.py) counted every request except / and /api/outputs against the per-IP budget (default 15/min). But the limiter exists to cap provider-key spend — and:

  • every key-spending REST endpoint is a POST (co_writer edit, voice tts/stt, book compile/regenerate, partners chat), and
  • chat spend is already guarded per-message on the /chat and /ws WebSocket loops.

Read-only page-load GETs spend nothing, yet each burned a token. A single SPA page load fires several at once, so a couple of refreshes exhaust the minute budget and the app starts 429ing on the reads it needs to render.

Fix

Only count unsafe HTTP methods in the demo catch-all; exempt GET/HEAD/OPTIONS. The WebSocket per-message guard and the / + /api/outputs exemptions are unchanged, and the actual spend cap (all POST spenders) is preserved.

Adds a regression test asserting read-only GETs are never limited even well past the per-minute cap.

🤖 Generated with Claude Code

The demo HTTP catch-all counted every request except / and /api/outputs
against the per-IP spend budget. But the limiter's job is to cap provider-key
*spend*, and every key-spending REST endpoint is a POST (co_writer edit, voice
tts/stt, book compile, partners chat) while chat spend is guarded per-message
on the WebSocket loops. Read-only page-load GETs (/api/v1/settings, /tools,
/knowledge/list, /settings/llm-options) spend nothing, yet each burned a token
— so a single SPA page load fired several at once and normal browsing quickly
429'd on the reads it needed to render.

Only count unsafe HTTP methods; exempt GET/HEAD/OPTIONS. Adds a regression test
that read-only GETs are never limited even past the per-minute cap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Ho1yShif Ho1yShif merged commit a0c66bd into main Jul 14, 2026
11 checks passed
@Ho1yShif Ho1yShif deleted the fix/demo-rate-limit-exempt-safe-methods branch July 14, 2026 19:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant