Skip to content

Rate-limit lh4.googleusercontent.com full-tier image fetches - #25

Merged
WilfordGrimley merged 1 commit into
masterfrom
worktree-image-cdn-rate-limit
Jul 16, 2026
Merged

Rate-limit lh4.googleusercontent.com full-tier image fetches#25
WilfordGrimley merged 1 commit into
masterfrom
worktree-image-cdn-rate-limit

Conversation

@WilfordGrimley

Copy link
Copy Markdown

Summary

Investigating throughput for the local OCR/phash pilot (docs/features/printing-tags.md Stage 8) surfaced a real gap: the image CDN Worker's full tier is a pure passthrough to https://lh4.googleusercontent.com/d/{id}... (Google's image-serving CDN, not the Drive API) with no rate limiting anywhere in the codebase. This path is shared by three callers:

  • frontend/src/features/pdf/pdfImage.ts (PDF export)
  • frontend/src/features/download/downloadImages.ts (bulk image download)
  • the local OCR/phash pilot (a separate, not-yet-merged branch)

The existing GOOGLE_DRIVE_RATE_LIMITER binding doesn't cover this - it only guards GoogleDriveService.executeCall, the real Drive API (a different Google domain entirely). A sustained high-volume caller hammering the unguarded lh4.googleusercontent.com endpoint risks degrading it for live PDF export/download traffic too, not just whatever's generating the load.

Changes

  • New IMAGE_FULL_TIER_RATE_LIMITER Cloudflare rate-limiting binding (wrangler.toml, 3 req/s sustained - conservative since there's no published Google quota for this specific endpoint to size against; comfortably serves normal PDF/bulk-download bursts).
  • src/utils.ts: fetchWithRateLimit helper - mirrors GoogleDriveService.executeCall's existing check-then-backoff-then-retry pattern (checked-in-limit, delay-and-retry on denial, defensive retry on an upstream 429), but as a standalone primitive since this call site is a plain unauthenticated GET to a different Google domain than executeCall is built around (POST, OAuth, Drive API).
  • src/handler/image.ts: the full tier now routes through fetchWithRateLimit instead of a bare fetch().
  • worker-configuration.d.ts: added the new binding's type.

Test plan

  • npx vitest run - 53/53 passed (including 3 new tests for the retry/backoff/exhaustion behavior in tests/utils.test.ts, and 1 new handler-level test confirming the full tier actually routes through the limiter)
  • All existing tests (PDF export / bulk download's underlying full-tier requests) pass unchanged - no regression to normal burst usage
  • npx tsc --noEmit - no new errors (pre-existing cloudflare:test/global type-resolution gaps in the vitest-pool-workers test environment, unrelated to this change)

Lands independently of the pilot's own branch - deploy ahead of any full-catalog pilot run so live traffic is protected regardless of pilot timing.

🤖 Generated with Claude Code

https://claude.ai/code/session_016i9S7LQsCL3FGaih3ZTRBJ

Shared by PDF export, bulk download, and the local OCR/phash pilot -
previously unguarded (GOOGLE_DRIVE_RATE_LIMITER only covers the real
Drive API, a different Google domain this path never touches).
@WilfordGrimley
WilfordGrimley merged commit 936eaef into master Jul 16, 2026
3 checks passed
@WilfordGrimley
WilfordGrimley deleted the worktree-image-cdn-rate-limit branch July 16, 2026 02:15
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