Configure overdraft quotas
By default, Aperture charges every quota bucket that matches a request in parallel: if a request costs $1 and three buckets match, each bucket drops by $1. Overdrafts add a sequential dimension. Instead of debiting every matching bucket at once, an overdraft chain spends a primary bucket first and borrows from the next bucket in the chain only when the primary runs out.
Use overdrafts when most users should share one allocation but some users need extra headroom. You can give everyone a base quota, then let a group or an individual borrow from an additional bucket, without redefining the base quota for everyone.
How overdrafts work
A request draws from the buckets in a chain in order:
- It spends the primary bucket first.
- When the primary bucket cannot cover the full cost, it takes what remains there and borrows the rest from the next overdraft bucket.
- It keeps borrowing from the remaining overdraft buckets in the configured order.
- It is rejected only after the entire chain cannot cover the cost.
A single request can split across buckets. If the primary bucket has $0.50 remaining and a request costs $2.00, Aperture debits $0.50 from the primary bucket and borrows $1.50 from the next overdraft bucket. The last bucket in a chain can go negative to cover a request. When it does, the chain stays blocked until a refill brings the combined balance back above zero.
Overdrafts change only what happens within a single chain. Buckets that a request matches through separate quota entries are still charged in parallel.
Prerequisites
Before you begin, you need:
- An Aperture instance with at least one provider configured.
- Admin access to the Aperture configuration.
- At least two quota buckets defined: a primary bucket and one or more buckets to use as overflow.
Step 1: Define the quota buckets
Open the Aperture dashboard and go to Administration > Configuration.
Define the buckets in thequotas section. An overflow bucket is an ordinary quota definition; nothing in the definition marks it as an overdraft. The following example defines a per-user daily bucket and a shared engineering pool:
"quotas": {
"daily:<user>": {
"capacity": "$10.00",
"rate": "$5.00/day",
"on_exceed": "reject"
},
"eng-team-pool": {
"capacity": "$200.00",
"rate": "$200.00/week",
"on_exceed": "reject"
}
}
Step 2: Add overdrafts to a grant
Overdrafts live on the grant assignment, not on the bucket definition. You can add them either in the Aperture dashboard or by editing the configuration file directly.
Use the Aperture dashboard
Open the Aperture dashboard and go to Administration > Configuration.
Open the grant you want to change, or create a new one. Each quota bucket in the grant has an Add overdraft bucket control. Select an overflow bucket from the list of your defined quotas, then add more buckets to extend the chain. Drag the buckets to set the order Aperture draws from them, from first to last. The dashboard only lets you choose buckets that already exist and prevents a chain from including its own primary bucket or a duplicate.Edit the configuration file
Add an overdrafts list to a quota entry in a grant. The list names the buckets to fall back to, in order:
"grants": [
{
"src": ["*"],
"app": {
"tailscale.com/cap/aperture": [
{ "role": "user" },
{
"models": "**",
"quotas": [{"bucket": "daily:<user>"}]
}
]
}
},
{
"src": ["group:eng"],
"app": {
"tailscale.com/cap/aperture": [
{
"models": "**",
"quotas": [
{"bucket": "daily:<user>", "overdrafts": ["eng-team-pool"]}
]
}
]
}
}
]
In this configuration, every user draws from their own daily:<user> bucket. Members of group:eng additionally overflow into eng-team-pool once their daily bucket runs out. The same bucket can be a primary quota for one set of users and an overdraft for another, because the role comes from the assignment, not the definition.
You can combine parallel quotas and sequential overdrafts in the same grant: list several quotas entries to charge buckets in parallel, and give any entry an overdrafts list to make that bucket fall back sequentially.
The grant examples on this page use Aperture configuration syntax, where the dst field is not required because the destination is the Aperture device itself. If you define grants in the tailnet policy file instead, you must include a dst key specifying the Aperture device (for example, "dst": ["tag:aperture"]). Omitting dst in a tailnet policy file grant causes the grant to silently have no effect. For a full comparison and conversion steps, refer to Aperture grants vs. tailnet policy file grants.
Step 3: Layer grants for exceptions (optional)
Overdrafts let you grant a higher limit to specific users without touching the base policy. Layer grants from broad to narrow:
- A broad grant applies a standard quota to every user.
- A narrower grant adds an overdraft for a group that needs more capacity.
- An even narrower grant adds another overdraft for an individual.
Aperture merges the grants that apply to a user into one effective configuration, so the user inherits the standard policy plus any fallback capacity that applies to them.
How grants merge
Within a single grant, overdrafts apply in the order you list them. When separate grants contribute overdrafts for the same primary bucket, Aperture merges them into one deterministic order. That merged order can be hard to predict, so keep overdrafts that must run in a specific order together in one grant, and avoid defining multiple grants with the same primary bucket when order matters.
Aperture rejects grants whose overdraft orders contradict each other. If one grant lists pool-a before pool-b for a primary bucket while another grant lists them in the opposite order, the two orderings form a cycle and Aperture refuses to save the configuration, returning HTTP 400 with a validation error. Fix the ordering in one of the grants, or move both overdrafts into a single grant, and save again.
Step 4: Verify and troubleshoot
After saving the configuration, confirm the chain behaves as expected:
- Send test requests as a user whose grant includes overdrafts until the primary bucket is exhausted, then confirm that later requests keep succeeding and draw from the overflow bucket.
- Check bucket balances using the quota status on the Models page in the Aperture dashboard or through
GET /api/quotas. Buckets that are used only as overflow targets appear in a separate section from primary buckets.
When a user reports running out of credit, inspect the quotas and overdrafts that actually apply to that user. In the Aperture dashboard, an admin can review another user's effective configuration, or call GET /api/quotas?login_name=<user>. Use it to answer questions such as:
- Did the user receive only the base grant, or also the narrower grant that adds the fallback bucket?
- Which overdraft buckets apply, and in what order?
- Did the last bucket in the chain have enough balance to cover the request?
If a request exhausts the entire chain, Aperture rejects it with HTTP 429 and a body such as Aperture quota exceeded: daily:<user>, formatted to match the provider's native error format (for example, rate_limit_error for Anthropic, insufficient_quota for OpenAI). For more troubleshooting details, refer to Troubleshooting Aperture.
Next steps
- Set per-user spending limits to define the primary buckets an overdraft chain builds on.
- Check and refill budgets to monitor bucket balances and manually add funds.
- Refer to the quotas configuration reference for the complete field reference and additional examples.