Every paid AI call on Novus first passes one gate: a per-user counter that allows 30 requests every 60 seconds, resets on the clock, and — surprisingly — lets you through when it breaks. Below is a live model of that exact gate. Drive it.
Fire requests and watch the current window fill. At 30 it flips to 429. When the 60-second window rolls over, the count resets to zero and you're clear again. The clock runs fast so you can watch it — speed is yours to set.
Time is chopped into fixed 60-second windows. Each request bumps a counter for the current window; cross 30 and you're blocked until the clock ticks into the next window, where the counter starts fresh at zero. Simple, cheap, and atomic in Postgres.
watch the counter reset on rolloverIf the counter’s database call errors — say the migration hasn’t run yet — the limiter returns true and lets the request through. It’s best-effort hardening that must never take the app down. Errors aren’t attacker-controllable, so fail-open isn’t a bypass. Flip “infra down” to see it.
export async function checkRateLimit( userId: string, limit = 30, windowSeconds = 60, ): Promise<boolean> { try { const { data, error } = await supabaseAdmin.rpc('check_ai_rate_limit', { p_user: userId, p_limit: limit, p_window_seconds: windowSeconds, }) if (error) return true // ← fail OPEN: infra error must not take the app down return data === true } catch { return true // ← same story: allow rather than crash } }