Load Throughput & Retries

Batch sizing, load timing, the ingest backlog and 429, and how to retry inbound submits safely with an idempotency key.

This page explains how fast GAINS Connect takes in and loads your data, how to size batches, what a 429 means, and how to retry a submit without loading the same records twice. Read it before you schedule large or frequent loads.

How long a load takes

A load goes through two stages, and only the first one happens while you wait for the response:

  1. Accepting. GAINS Connect checks the records, creates the task and answers 202 or 207.
  2. Loading. GAINS loads the batch at its next scheduled load for that kind of data.

The schedule is set in GAINS, separately for each kind of data. GAINS Connect reports it on the task:

StatusWhat it tells you about timing
QueuedA load is scheduled. StatusMessage gives its time, for example Expected processing time is 2026-05-22 02:00:00.
ReceivedNo load for this kind of data is scheduled yet. The task waits until GAINS schedules one.
ProcessingThe scheduled load is running.

A task does not move between these points, so the expected processing time is the earliest moment worth checking again. Ask your GAINS representative to change how often a kind of data is loaded.

Batch size

A request holds 1 to 1000 top-level records; see Sending a batch. GAINS Connect does not limit how many requests you send; it refuses a load only when its backlog is full.

Send full batches: 10 requests of 1000 records cost less than 100 requests of 100.

The ingest backlog and 429

When GAINS Connect is still taking in earlier batches, a load answers 429:

HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/json

{
  "Reason": "The service is busy ingesting previously submitted data. Retry this batch shortly."
}

After a 429:

  • Nothing from the request was saved and no task was created.
  • An Idempotency-Key on the request was released, so resend with the same key.
  • Wait at least the number of seconds in Retry-After, then send the same batch again.

Only data loads, including POST /custom/{ApiRoute}, can answer 429; deletes, POST /supply-transactions/link-order and the task endpoints never do.

Sending more requests in parallel does not help: slow down, or send fewer, fuller batches.

Retrying safely

Send an Idempotency-Key with every load, use the same key after a 429, a timeout or a 5xx, and a new key once you have changed the records. The full rules, and what to do when a resend answers that the key is a duplicate, are in Retry safely. POST /custom/{ApiRoute} ignores the key; see Custom Schema.

When a task fails

A task in Failed stopped on an unexpected error. Send the batch again under a new key. If the new task fails too, contact your GAINS representative with both TaskId values.

A task in RejectedFailedProcessing was loaded, but GAINS refused every record. Resending it unchanged gives the same result: read Batch.RejectedRecords and correct the records first. See Rejected Records.

Recommended client pattern

  • Send loads for one kind of data one after another. Wait for each response before sending the next batch. It keeps the backlog short, and you never have two attempts of the same batch in flight.
  • Load what other records refer to first. Load SKUs and locations before SKU-locations, and customers and vendors before the transactions that name them. Wait until the earlier task is Completed before you send records that depend on it, since each kind of data loads on its own schedule.
  • Back off on errors. Honour Retry-After on 429. On 500, 503 and 504, or when you get no response, wait before retrying and double the wait on each attempt, for example 30 seconds, 1, 2, 4 and 8 minutes, then stop and alert someone. Never retry 400, 403 or 422 unchanged.
  • Follow tasks without polling hard. Check a Queued task after its expected processing time, or subscribe to the TaskStatusUpdate webhook (see Webhooks). To follow many tasks, list them with GET /tasks filtered by Status and TaskType instead of reading each one.
  • Store the TaskId with your own record of the batch. Tasks are kept for 30 days.
key = new UUID
send batch with key
  202 / 207 -> store TaskId; resend corrected rejects under a new key
  429       -> wait Retry-After; send again with the same key
  timeout / 5xx -> wait with backoff; send again with the same key
     400 duplicate key -> GET /tasks: task found -> follow it
                                      no task    -> new key, send again
  400 / 422 -> fix records; new key
follow TaskId until Completed, RejectedFailedProcessing, Cancelled or Failed

Related guides


Did this page help you?