Skip to content

fix: make quota check+increment atomic in license route #12

Description

@PriyeshPandey2000

Problem

frontend/app/api/license/check/route.ts reads pagesUsed with kv.get then increments with kv.incrby in two separate operations. Concurrent uploads can both pass the limit check before either increments, allowing over-consumption of the page quota.

const used = (await kv.get<number>(key)) ?? 0   // read
if (used + pages > limit) { ... deny ... }
await kv.incrby(key, pages)                      // write — not atomic with read

Fix

Use a single atomic INCRBY then check if the result exceeds the limit. Roll back if over:

const newUsed = await kv.incrby(key, pages)
if (newUsed > limit) {
  await kv.incrby(key, -pages) // undo
  return deny(newUsed - pages, limit)
}
return allow(newUsed, limit)

Or use a Lua script for true atomicity (single round-trip, no undo needed).

Priority

Low — only matters under concurrent uploads from the same token. Not an issue at current usage levels.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions