Product Catalog ยท Push API

Limits and throughput

Every number you can hit, what happens when you hit it, and how long a large feed really takes.

Limits

LimitValuePast it
Rows per batch1,000400 INVALID_REQUEST
Bytes per batch5 MiB (5,242,880 bytes)413 REQUEST_BODY_TOO_LARGE
Inventory request1,000 rows, 1 MiB413 REQUEST_BODY_TOO_LARGE
Batches per jobAbout 2,000 (roughly 2 million rows)409 JOB_FULL
Open jobs per caller3409 TOO_MANY_OPEN_JOBS
Waiting batches per caller2,000 received, not yet applied429 PUSH_QUEUE_FULL, Retry-After: 60
Job lifetime while open24 hoursExpires: JOB_EXPIRED
Request rate600 per 60 s per key (approximate)429 RATE_LIMITED with Retry-After
Idempotency-Key1 to 200 characters400 INVALID_REQUEST
Job CSV reportUp to 900 parts409 REPORT_TOO_LARGE
Report retention30 days after the run finishes410 REPORT_EXPIRED
Refs per archive, restore or assign call100400 INVALID_REQUEST
GET /products page size1 to 100, default 50400 INVALID_REQUEST
externalId length255 characters400 INVALID_REQUEST or a refused row
Idempotency-Key memory24 hoursAfter that the same key is treated as new
Stock adjust de-duplication (job rows)7 daysA repeated adjust row of the same delivery is not applied twice
Vendors per store / keys per vendor200 / 2 activeCreation is refused

The rate limiter is approximate: it is not an exact meter, so a burst can slip a little past 600 or be refused a little early. Treat 600 per minute as a design target, not an exact meter, and always honor Retry-After. A vendor key is limited on every route; the store key on jobs and products routes only.

Throughput: two measured runs

Two single runs, on one store, with images
These are two measurements made on 2026-11-01 on one production store, each run once. They are not a guarantee, a benchmark of your feed, or a target. The feed was 120,000 products (372,242 rows) in 373 batches, mode merge, four parallel senders, with images on 10% of the products.
MeasureRun 1 (Worker e844ed62)Run 2 (Worker e2f3c98a, after a read-path fix)
Upload (open to close)321 s354 s
Close to completed2,963 s (49 min)3,327 s (55 min)
Rows per minute while applying (close to completed)about 7,538about 6,713
Rows per minute end to endabout 6,707about 6,045
End to end (open to fully live)3,330 s (55 min)3,694 s (62 min)
Rows refused or failed00
  • Expect about 1 hour per 120,000 products with images, roughly 6.7k to 7.5k rows per minute on average, and plan on a feed with many new image URLs taking that long or longer.
  • The apply rate falls during a run (about 12k to 13k rows per minute at the start, about 3.5k in the middle) and recovers once the image copies drain. The fix between the runs cut database reads by half and made them independent of catalog size, but did not make the run faster.
  • Updates to existing products with no image changes run faster: a price update of about 150,000 rows on the same store applied at about 46,000 rows per minute (a single run on 2026-11-01, 195 s, Worker e844ed62).
  • The same 120,000-product feed ran in about 4 minutes on a local test stack. Do not read that as a production figure.

What to do about it

  • Split very large catalogs across jobs (for example by category or by 20,000 products), and keep at most 3 open at once.
  • Poll the job every few seconds, or use the webhook, rather than holding a connection open. Closing returns at once.
  • Send updates without images as a separate, small job so they are not queued behind a big image feed (lanes take turns, but a lane applies its own work in order).

Images

Image copies run in two phases. While a job applies, they run alongside it: about 200 to 285 copies per minute at peak in one production run (2026-11-01, Worker e2f3c98a, a single run on one store). Copies still waiting when the job ends are picked up by a sweep that runs every 5 minutes and publishes up to 100 jobs per run, about 20 copies per minute (in the first run, 1,607 leftover copies took about 40 minutes). Until a copy lands, the storefront serves the vendor's own image URL, so keep those URLs public and stable. A catalog also has a budget of 20,000 image resizes per calendar month (roughly 6,700 images), so a feed with more images than that stays partly on vendor URLs for longer. A completion event means rows are written, not that images are copied. See known limits.

How fresh is the storefront?

Rows are visible a few seconds after finishedAt (8.6 s and 39 s were measured on the two large runs). An archived product can still be served for up to 60 seconds from the edge cache.