Skip to content

Implement a adaptive query cost governor that tracks per-wallet database query cost and throttles wallets exceeding the rolling budget #755

Description

@Chucks1093

Summary

The API has no per-wallet database cost controls. A single wallet making expensive paginated queries, deep search requests, or large analytics calls can saturate the connection pool and degrade the experience for all users. This issue implements a query cost governor that assigns a cost unit to each query based on its estimated database impact, tracks per-wallet rolling spend in Redis, and throttles wallets that exceed the budget with a 429 response and a backoff window.

Scope

1. Query cost model

  • Define a cost map in configuration: each route pattern maps to a cost unit (e.g. GET /creators = 1, GET /creators/:id/holders = 3, GET /search = 5, GET /creators/:id/history = 2)
  • Parameterised costs: limit query param multiplies the base cost (e.g. limit=100 on a cost-3 route = cost 30)
  • Cost map configurable via environment without code changes

2. Rolling budget tracking

  • On each authenticated request, before query execution, read the wallet's rolling spend from Redis key qcost:{walletAddress} (a sorted set of { cost, timestamp } entries)
  • Evict entries older than the rolling window (default 60 seconds) from the sorted set
  • If the sum of remaining entries plus the current request cost exceeds the budget (default 200 units/60s), return 429 query_budget_exceeded with Retry-After set to when the oldest entry will expire
  • Otherwise, append the current cost entry and proceed

3. Cost response headers

  • Add X-Query-Cost: {cost} and X-Query-Budget-Remaining: {remaining} headers to every authenticated response
  • On throttled responses include X-Query-Budget-Reset: {unix_timestamp} indicating when the budget resets

4. Admin override

  • Admin wallets (configurable list) bypass the governor entirely
  • A POST /internal/qcost/reset/:walletAddress endpoint (internal network only) allows operators to clear a wallet's budget immediately

5. Integration tests

  • Send requests summing to exactly the budget — assert all succeed
  • Send one request that pushes the total over the budget — assert 429 with correct Retry-After
  • Verify X-Query-Cost and X-Query-Budget-Remaining headers on each response
  • Wait for the rolling window to expire — assert requests succeed again
  • Admin wallet sends requests exceeding the budget — assert no throttling

Acceptance Criteria

  • Cost map applied correctly per route with limit param multiplier
  • Rolling budget tracked in Redis with window eviction
  • Budget exceeded returns 429 with Retry-After and X-Query-Budget-Reset
  • Cost and remaining budget headers on every authenticated response
  • Admin wallets bypass the governor
  • Budget resets correctly after the rolling window

ETA: 24 hours


Coordinate on Telegram

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardThird CampaignCampaign: Third Campaign

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions