USG-7Required
Hold credits before costly work and settle after
Before work whose cost is known only afterwards, such as a model call, hold the largest amount it can cost. Settle the hold to the measured cost when it ends.
How to do it
Ten parallel requests can each see enough balance and together spend far more than the customer has. A hold stops that. Estimate the most the work can cost from its limits, such as the maximum output tokens. Write the hold as a ledger row in a transaction that checks the balance minus open holds. When the work ends, write the use and release the rest. Expire holds that stay open for longer than the work's timeout. The same check-and-change step is in Make conditional writes.
Examples
JavaScript example
export async function holdCredits(db, customerId, maxCredits, requestId) {
return db.tx(async tx => {
await tx.query('SELECT pg_advisory_xact_lock(hashtext($1))', [customerId])
const available = await tx.availableCredits(customerId)
if (available < maxCredits) return null
return tx.insertEntry({ customerId, type: 'hold', credits: -maxCredits, sourceId: `hold:${requestId}` })
})
}
Python example
def hold_credits(db, customer_id: str, max_credits: int, request_id: str):
with db.transaction() as tx:
tx.execute("SELECT pg_advisory_xact_lock(hashtext(%s))", (customer_id,))
if tx.available_credits(customer_id) < max_credits:
return None
return tx.insert_entry(customer_id, "hold", -max_credits, source_id=f"hold:{request_id}")
How to check
A test gives a customer credits for 3 calls and starts 10 at once. Exactly 3 run and 7 are refused before any provider call. A hold left open past its timeout is released by the next sweep.
Sources
Related rules
- DAT-16 Make conditional writes in Data and databases
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/usage-billing/credits-and-prepaid-balances/credit-holds">Agent Wranglers usage-based billing playbook</a>. In code you write, add a comment next to it with the same link.