Batch API up to 50k requests per job: mega-catalog multi-job orchestration in Bubble with BIAIG
OpenAI’s Batch API allows up to 50,000 lines and 200 MB per job—but output JSONL does not preserve input order. How to choose one batch vs parallel jobs in Bubble backend workflows and merge results in BIAIG without losing row order for Merchant/ads.
Why now
Recent digest coverage reminded teams of the OpenAI Batch API operational ceiling: up to 50,000 image generation/edit requests per batch job, plus up to 200 MB per input JSONL file. This piece is not unit economics (batch discount / 24h vs Flare)—it’s planning mega-catalogs when Bubble/BIAIG workflows have historically used ~500-row spreadsheet chunking. A closer look: The ~500-row bulk-tools ceiling in. A closer look: The ~500-row bulk-tools ceiling in.

Scout summary: Bubble’s schedule-on-list limits (up to 100k unsorted / 50k sorted child workflows per official manual) are not usually what forces multiple OpenAI jobs. Multi-job orchestration is driven by OpenAI’s 50k/200 MB caps and payload shape (base64 vs image_url/file_id), unless your bulk tool (BIAIG) enforces a lower chunk size—the ~500-row “bulk-tools ceiling” from prior editorial thread is not verified in public BIAIG documentation. A closer look: Flare, Sunburst, and WaveSpeedAI: routing. A closer look: Flare, Sunburst, and WaveSpeedAI: routing.
What primary sources say (OpenAI)
- Endpoints: batch supports
/v1/images/generationsand/v1/images/edits(edits as JSON in batch, not multipart). - Per job: up to 50,000 JSONL lines and 200 MB input file.
- Timing: 24-hour processing target; batch creation rate limits (e.g. up to 2,000 batches/hour—tier/account-specific).
- Order: output JSONL order ≠ input order—correlate with
custom_id(unique within the batch; cookbook/API guidance: unique id per line). - Failures: separate
error_file_id;expiredstatus may leave partial completion—merge logic must handle both. - Image ops: DALL·E
urlresponses expire 60 minutes after generation; GPT image models oftenb64_jsononly—you may hit 200 MB before 50k lines. - Guidance: prefer
image_url/file_idover large base64 in JSONL for edits/multimodal payloads.
One OpenAI batch job vs many parallel jobs
| Scenario | Typical strategy |
|---|---|
| n ≤ 50k and JSONL < 200 MB | One OpenAI batch job for the catalog run. Bubble may still update catalog state in ~500-row chunks—internal pacing, not necessarily 1 OpenAI job per chunk. |
| n > 50k | At least ceil(n / 50k) jobs by line count; also validate 200 MB—heavy edits or b64 may require smaller jobs well before 50k lines. |
| Mega-catalog + ~500-row bulk tooling | Pattern A: many Bubble chunks (~500) folded into fewer OpenAI jobs (pack JSONL to caps). Pattern B: one batch per chunk for simpler retries → jobs ≈ ceil(n/500), more orchestration overhead. Be explicit in DB which pattern you use (batch_id, chunk index, row key)—Scout flagged missing public BIAIG schema proof. |

Parallelism in Bubble: scheduling an API workflow on a list fans out parallel child runs; use interval pacing for external rate limits (Bubble manual). Avoid zero-interval floods unless you mean to.
Avoid a single 300s workflow that builds 50k JSONL, uploads, and polls to completion—server workflows timeout at 300 seconds (documented hard limit). Use multi-step scheduling: submit → store batch_id → separate poll/merge workflows (inference from timeout docs, not BIAIG-specific).
Workflow API: synchronous list responses capped at 50 items—don’t return full bulk batch status in one sync response; use Data API / pagination for large reads.
Merge semantics and row order (Merchant / ads)
- Never rely on output JSONL line order for Merchant/ad exports.
- Encode a stable application key in
custom_id(e.g.catalogRunId:chunkIndex:rowIndex, or SKU + run id)—match whatever your export treats as authoritative (Scout open question: spreadsheet row vs SKU vs Bubble thing order). - After join: sort in app logic on that key, not file line number.
custom_idis not OpenAI HTTP idempotency: duplicate batch creates are separate jobs unless the app deduplicates on storedbatch_id+ business keys.- Partial completion: handle
error_file_idandexpiredwith subset success; retry policy for failed lines (new batch only vs sync fallback) and Merchant slot charging is your product decision. - DALL·E URLs in batch: delayed ingestion near the 24h window risks 60-minute URL expiry—persist immediately to durable storage or choose output formats/models that fit your pipeline.
Practical checklist (Bubble + BIAIG)
- Pre-submit: estimate line count + JSONL size (b64 vs references).
- DB fields:
catalog_run_id,openai_batch_id,chunk_index,row_key, per-row status. - Submit workflow: short—create batch, save ids, finish.
- Poll workflow: scheduled/recursive or list of in_progress batches—not one 24h loop in 300s.
- Merge workflow: parse output + error files; map by
custom_id; sort; refresh Merchant export queue. - Team doc: when you use one OpenAI job per run vs N parallel jobs (50k, 200 MB, account queued-token limits).

What we don’t claim
- Exact source of the ~500-row ceiling in the prior thread (plugin, WU, parser)—not found in public BIAIG docs.
- Whether BIAIG today always submits one OpenAI batch per spreadsheet chunk—requires your data model audit.
- How many parallel 50k image jobs your OpenAI tier allows before throttling—account-specific.
Sources (Scout packet)
OpenAI: Batch API guide, Create batch API reference, Batch FAQ, Create image API reference, Batch processing cookbook. Bubble: Hard limits, Scheduling API workflows, Workflow API, Bulk operation methods compared.