batch-job-error-recovery · EN · 2026-10-21

A Batch Job Halfway Through: Resuming Without Double-Charging USDC

Learn practical checkpointing and idempotency patterns to resume a crashed batch job without double-charging USDC. This guide covers atomic commit protocols, idempotency keys, reconciliation, and audit trails, tailored for API aggregators where you pay per call.

Why Resuming a Batch Job Is Tricky

Batch jobs that call paid APIs often crash mid-run. When you restart, you must avoid re-processing records that were already billed. Without careful design, you risk double-charging your USDC balance or leaving gaps in your output. The core challenge is coordinating two independent systems: your job's progress and your payment ledger.

Checkpointing: Record Your Progress Atomically

A checkpoint is a snapshot of which records have been successfully processed and billed. To be reliable, checkpoints must be atomic—they should update only after both the API call succeeds and the billing event is recorded.

Pattern: Write-ahead log with commit markers

  • Before calling the API, write a "pending" entry to your log with a unique job ID and record ID.
  • After a successful API response, update the entry to "committed" and include the response metadata (e.g., usage tokens, cost).
  • On restart, scan the log: records with "committed" entries are skipped; "pending" entries are retried only if you can guarantee idempotency (see below).

This log becomes your single source of truth for both progress and billing.

Idempotency Keys: Prevent Duplicate Charges

Even with checkpoints, retries can cause duplicate API calls. Idempotency keys let you safely retry without double-billing.

How to use them:

  • Generate a deterministic key for each logical operation, e.g., hash of batchid + recordid + attempt_number (but attempt number should not change on retry—use a stable key).
  • Include this key in the API request header (e.g., Idempotency-Key).
  • If the request times out, retry with the same key. The server should return the original response if it already processed the request.

Important: Not all APIs support idempotency keys. For those that don't, you must rely on your own ledger and reconciliation (next section).

Reconciliation: Prove What Was Billed

Reconciliation compares your internal ledger with the actual billing records from your provider. This step is crucial for proving no double-charges occurred.

Steps:

  • Periodically fetch billing statements or usage logs from your API provider (if available).
  • Match each billed call to a record in your checkpoint log.
  • Flag discrepancies: missing calls, duplicate charges, or amount mismatches.

If you use an aggregator that credits contributors (e.g., at official price × 1.1 or × 1.2), reconciliation also ensures you receive the correct credit.

Audit Trail: Document Everything

An audit trail is your defense against disputes and a tool for debugging. Store:

  • Timestamps of each API call (start and end).
  • Request and response payloads (or hashes).
  • Idempotency keys used.
  • Billing amounts and currency (USDC).
  • Checkpoint updates.

Keep this log immutable and append-only, e.g., using a database with write-once semantics or a distributed ledger.

Practical Workflow for Resuming

  1. On job start, load the latest checkpoint and audit log.
  2. For each record, check if it has a committed entry. If yes, skip.
  3. For pending entries, attempt to reconcile with provider billing first. If the call was billed, mark as committed and skip; otherwise, retry with the same idempotency key.
  4. After each successful call, atomically update the log to committed and record the billing amount.
  5. On completion, run a final reconciliation to ensure all records are accounted for.

Handling Partial Failures

If a batch fails partway, some records may have been billed but not marked committed. Use the audit trail to identify these: if the API call succeeded (response received) but the commit failed, you can safely mark as committed without re-calling. If the call status is unknown, reconciliation with the provider's billing data is the only reliable way to avoid double-charging.

Conclusion

Checkpointing, idempotency keys, and reconciliation form a robust triad for resuming batch jobs without double-charging USDC. By treating your checkpoint log as the source of truth and reconciling against provider billing, you can prove exactly what was billed and resume with confidence—even when using a pay-per-call API aggregator where every call costs USDC.