The decision
Several jobs can each read a sufficient balance and start against the same credits (HYVIRAL’s prepaid units), and a rejected charge cannot undo provider costs already incurred. So billing sets the credits aside before paid work and settles the actual amount afterwards.
A hold reduces the amount available to other jobs without immediately charging the wallet. Placement shares a transaction-scoped wallet lock with credit consumption. An active reference is reusable, so retrying placement does not create a second reservation.
The cost is lifecycle management: held credits are temporarily unavailable, and unsuccessful or abandoned work needs release or expiry handling.
The lifecycle: place an active hold → run the admitted paid work → capture the actual amount, or release or expire the hold. Repeating a completed capture returns its first result; a failed consumption leaves the transaction uncommitted.
From the source
Placement SQL. One lock key serializes placement and consumption for the same wallet:
-- Same lock key as consume_credits_with_priority: placements and consumes for
-- one user serialize against each other, which is what makes the check below
-- authoritative rather than advisory.
PERFORM pg_advisory_xact_lock(
hashtextextended('billing.wallet:' || p_user_id::text, 0)
);
Capture SQL. Failed consumption raises inside the transaction, rolling back the captured-state update:
IF NOT v_consume.success THEN
-- Surface rather than swallow: the hold guaranteed this could be paid, so
-- a denial here means the guarantee was violated and the caller must see
-- it. Raising rolls back the status update too, leaving the hold active
-- for the reaper rather than stranding it as captured-but-unpaid.
RAISE EXCEPTION 'capture_credit_hold: consume denied (%)',
COALESCE(v_consume.error_message, 'unknown');
END IF;
Concurrency test, as reported in the 12 August 2026 specification:
- The Problem Statement's scenario, reproduced and closed. Available squeezed to exactly 3,000; three concurrent
place_credit_hold(2400)calls. Exactly one succeeded; the other two were denied withInsufficient available credits.
What this shows
The mechanism is in the SQL: a shared advisory lock makes the balance check authoritative, and capture cannot leave a hold marked captured without the matching charge. The reported test shows the admission behavior under contention: one admission and two denials for 2,400 credits each against 3,000 available.