Skip to content
FeaturesPricingAffiliateBlogHelpAboutContact
Get StartedSign In
Back to Blog
industry2026-05-2312 min read

My Idempotency-Key was 800 characters long — POS sync app slowed down, defense-in-depth storage bloat (PR #661 XI F4)

Bjarni (37) runs Kaffi Solskin specialty coffee in Reykjavik downtown Laugavegur. His freelance iOS dev Thordis built an app that POS-syncs every 90 seconds. Bjarni: "order POST takes 4-5 seconds, was sub-second a week ago". thMenu support: idempotency_keys table 12,847 rows, some keys 800 chars long. Thordis well-meaning Idempotency-Key format: uuid+device+timestamp+sequence+audit metadata = 809 chars, fresh per call (retry-safety broken + storage bloat). Forensic: 4 endpoints (orders, payments/create, loyalty/redeem, products) checked Idempotency-Key presence only — NO length cap, NO charset allowlist. Stripe spec 255 + alphanumerics/-_.:, Square 192. Authenticated attacker scenario: 10MB binary blob Idempotency-Key + rate-limit-allowed burst = D1 5GB quota exhausted in 30 seconds, QUOTA_EXCEEDED for all writes. **PR #661 batch XI F4** fix: inline check on 4 endpoints: `if (idempotencyKey && (length > 255 || !/^[A-Za-z0-9-_.:]+$/.test(...))) return 400 invalid_idempotency_key`. Stripe ceiling 255 + allowlist covering UUID/32-hex/namespaced "prefix:rest" shapes. Optional-vs-required differentiated. Bjarni/Thordis refactored app: order-{uuid} ~42 chars stable across retries; after 14-day TTL prune cycle POST latency dropped back to ~200ms. Pattern: every client-supplied header that becomes a primary or cache key needs length + charset cap; presence-only is insufficient for defense-in-depth.

th

thMenu Team

thmenu.com

Found this helpful? Share it.