Skip to content

perf(d1): fewer statements on the proxy hot path #110

Closed

Description

@dev-bobsong

Found while reviewing the release that became v0.2.0 (tracking: #116).

Problem

Measured with a statement-counting D1 stub, one public-tier proxied request costs 8 statements / 4 row writes — and a pure cache HIT costs the same, because the quota is deliberately charged before the cache:

SELECT … FROM api_keys                                  key lookup
SELECT … FROM blocked_hosts …                           every request
INSERT quota_counters ×3 + SELECT count ×3              quota.ts (upsert, then re-read)
INSERT request_logs …                                   logging

On the free tier rows written (not statements) are the binding constraint, so separating the two:

  • RETURNING count on both the quota upsert and the rate-limit upsert removes 3 reads and one round trip each (latency win, not billing).
  • The three quota bumps can go out as one db.batch().
  • checkDbBlocklist runs on every request including hits; memoize it per isolate for ~30 s, mirroring the existing DoH memo in dns-check.ts, invalidated on admin writes. −1 read per request.
  • The only real write reduction is moving the per-minute limit off D1: an opt-in Workers Rate Limiting binding, with the D1 fixed window kept as the default for deployments that need cross-isolate enforcement.

Change

Ship the free wins first (RETURNING, batch, memo), measure, then decide on the rate-limiting binding as a separate opt-in.

Acceptance

  • Statement count per public request drops from 8 to 4 (5 with the memo) — pinned by a test that counts statements.
  • Quota and rate-limit semantics unchanged, including fail-open.
  • README's free-tier sizing section reflects the new numbers.

Files

app/proxy/quota.ts, app/proxy/ratelimit.ts, app/proxy/guard.ts, README.md

Activity

  1. added
    opsCost, limits, alerting, production safety
    on Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    opsCost, limits, alerting, production safety

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions