send.webforms.toRead the docs →

engineeringbilling

We had a column called quota_reset_at. Nothing ever wrote to it.

A schema column can describe a promise perfectly and still not keep it. Here's the bug, and the boring-on-purpose fix.

WebForms4 min read

Every plan on the pricing page says a submission allowance "per month." The org table has a column, quota_reset_at, that exists for exactly one reason: to record when that allowance last reset, so the dashboard and the API can tell a customer when their counter goes back to zero. Both of those things were true and neither of them was a lie. What was missing is that nothing in the codebase ever actually wrote a new value into that column. It was set once, when a workspace was created, and then never touched again by anything.

quota_used, meanwhile, only ever went up - incremented on every accepted submission, exactly as you'd expect. Put those two facts together and the outcome is exactly what it sounds like: the first workspace to actually reach its monthly limit would have stayed at that limit permanently. Every submission after that point would hit a 402 forever, not just for the rest of that month but for every month after it, because nothing was ever going to reset quota_used back to zero.

Why this kind of bug is easy to miss

It's invisible in every normal testing path. A fresh workspace starts at zero usage. A developer testing quota enforcement sends a handful of test submissions, sees the counter go up, sees the limit kick in correctly at the right number, and moves on - because the counter incrementing and the limit being enforced are both working exactly as designed. The only way to notice the reset never happens is to still be watching a specific workspace a full month later, past the boundary where the reset was supposed to fire. Nobody's test suite runs for a month.

It's the same shape of bug as a retention policy that promises to delete old data after N days: the column exists, the copy on the pricing page describes the behavior accurately, and the only thing missing is a piece of code whose entire job is to execute on a schedule and actually do the thing everything else assumes is already happening.

The fix is supposed to be boring

A worker job, on an hourly sweep, doing one atomic UPDATE: for every workspace whose stamped reset period is before the current UTC calendar month, zero its usage counter and move the stamp forward to the start of this month. Atomic matters here specifically - a submission landing in the middle of the sweep increments quota_used in its own transaction, and a naive read-modify-write in the reset job could clobber that concurrent write. A single UPDATE statement with quota_used set to a literal 0 means the worst case is a submission that gets counted against the period that just ended, never a lost row and never two resets firing on the same workspace.

quota-reset.ts (simplified)
UPDATE organizations
SET quota_used = 0, quota_reset_at = :periodStart
WHERE quota_reset_at < :periodStart;

The period is the UTC calendar month, deliberately, because that's what the plan pages and the fair use policy actually say - anchoring to each workspace's signup date instead would make the published copy wrong for almost everyone reading it. And a missed tick is harmless by construction: if the worker is down for a day, or a week, the next pass just recomputes the current period from scratch and catches every stale row in one sweep, however long it's been.

The actual lesson

A schema column and a line of marketing copy can both be completely correct descriptions of intended behavior and still not add up to that behavior existing. Somewhere between the schema and the pricing page, there has to be a piece of code whose only job is executing the promise on a timer - not implied by the existence of a timestamp column, not assumed because the feature is obviously important enough that surely someone built it. If you have a column that only gets read, never written after creation, that's worth a specific, deliberate check, because the alternative is finding out from a customer who's been locked out for two months and can't figure out why.

Get your endpoint

Free for 300 submissions a month. No card required.

Start free