Agent Wranglers

SCL-31Recommended

Give each customer a fair share

Cap how much work each customer or tenant can have running or queued at once. One heavy customer then slows only their own work.

How to do it

Per-client rate limits count requests, but one export can cost more than a thousand page views. Count running work per tenant, such as jobs and open exports, in a shared store. Beyond the cap, queue the work or answer 429. The Google SRE book sets quotas per customer, and under overload it refuses only the customers over their quota. Larger plans can get larger caps.

Examples

JavaScript example

const MAX_RUNNING_EXPORTS = 3;

export async function startExport(redis, tenantId, start) {
  const key = `running-exports:${tenantId}`;
  if (await redis.incr(key) > MAX_RUNNING_EXPORTS) {
    await redis.decr(key);
    return { status: 429, retryAfterSeconds: 30 };
  }
  await redis.expire(key, 3600);
  return start({ onDone: () => redis.decr(key) });
}

Python example

MAX_RUNNING_EXPORTS = 3

def start_export(redis, tenant_id: str, start):
    key = f"running-exports:{tenant_id}"
    if redis.incr(key) > MAX_RUNNING_EXPORTS:
        redis.decr(key)
        return {"status": 429, "retry_after_seconds": 30}
    redis.expire(key, 3600)
    return start(on_done=lambda: redis.decr(key))

How to check

On staging, one tenant starts 100 exports at once. No more than its cap run together, and an export from another tenant starts within 30 seconds.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/scaling/load-balancing-and-autoscaling/per-tenant-limits">Agent Wranglers scaling playbook</a>. In code you write, add a comment next to it with the same link.