Sync, async і batch для image API (OpenAI/Google контекст): матриця режимів bulk-каталогу в Bubble через BIAIG
Один builder-facing вибір: sync burst у workflow, async з job-записом і polling, або mass-generation через Batch API / BIAIG — з урахуванням ~30s API Connector, 300s workflow і WU.
Навіщо одна матриця, а не ще один provider-post
Після жовтневих змін у лінійках OpenAI (GPT Image) і Google (Nano Banana / Gemini image) мені знову траплялось одне й те саме: окремий гайд під кожного вендора не тримається, коли треба один framework вибору режиму. У документації три патерни постійно перетинаються: sync (один HTTP-виклик → зображення в відповіді), async job (швидка відповідь → polling або webhook), provider Batch API (черга на години, окремий rate-limit pool, ~50% дешевше за standard/sync tier на OpenAI і Gemini Batch).
У Bubble я давно бачу, що обмеження платформи часто важливіші за фічі провайдера. Нижче — матриця для bulk-каталогу (десятки–тисячі SKU, прев’ю, варіанти), з прив’язкою до workload units (WU) і ризику «завислих» workflow. Failover-історію від 14.10 свідомо не повторюю.
BIAIG у редакційному контексті — shorthand для batch-job оркестрації масової генерації (найближчий публічний аналог у пакеті Scout: BulkImagen
POST /v1/batches+GET /v1/batches/{id}). Якщо у вас внутрішній плагін або worker з тим же API — логіка матриці та сама.
Три режими (що саме ви викликаєте)
| Режим | Типовий API | Коли завершується | Економіка (лише list price провайдера) |
|---|---|---|---|
| Sync burst | OpenAI POST /v1/images/generations / edits; Gemini generateContent з image output; legacy Vertex Imagen :predict |
Секунди, клієнт чекає на HTTP | Standard tier; sync обмежений IPM (напр. Build tier ~20 IPM на сторінках моделей GPT Image 2.5 Flare/Sunburst) |
| Async job | Провайдер або посередник повертає job_id; ви poll-ите або ловите webhook |
Хвилини | Як у standard, плюс ваші WU на polling |
| Batch (provider або BIAIG) | OpenAI Batch на /v1/images/generations; Gemini batchGenerateContent для Nano Banana image models; BulkImagen batches |
До ~24 год (документоване вікно OpenAI/Gemini Batch) | ~50% vs standard (OpenAI pricing: напр. image output ~$30/M vs ~$15/M batch для gpt-image-2.5; Gemini Batch — аналогічна позиція в docs) |
Термінологія: «batch» у вендора — продукт Batch API, не «запустив Schedule API workflow on a list на 5000 рядків». Плутати їх — типова помилка в порадах про WU і rate limits; я сам так ловив себе на ранніх каталогах.
Моделі (фіксуйте API ID, не лише nicknames): OpenAI — primary sync path через Image API (gpt-image-2.5-sunburst / flare); gpt-image-1 — shutdown 2026-10-23 (deprecations). Google — gemini-2.5-flash-image (Nano Banana, GA 2025-10-02), лінійка Nano Banana 2 / 2.1 (gemini-3.1-flash-image, gemini-nano-banana-2.1); GA Nano Banana 2 у changelog — 2026-05-28, не 2025-10-29 (останній запис — інший реліз). gemini-2.5-flash-image — shutdown 2027-03-15 з заміною на gemini-3.1-flash-lite-image.
Обмеження Bubble, які «ломають» naïve sync
Джерела: API Connector, hard limits, форум про ~30s (discussion — community signal).
- API Connector > ~30 с — автоматичний retry → ризик дублікатів (повторна генерація, повторне списання credits), якщо виклик не ідемпотентний.
- Workflow hard-stop 300 с — один «довгий» sync-ланцюг не масштабується на сотні картинок посередині одного run.
- Recursion через API Connector — depth cap (3 direct / 10 cross-app); naive «workflow викликає сам себе» швидко впереться.
- Schedule API workflow on a list — cap на fan-out (50k–100k залежно від sort); це не заміна provider Batch на тисячі image requests з окремим SLA.
- Response до 50 MB — повертати багато base64 inline часто погана ідея; у матриці закладайте URL / storage handoff.
Плагіни на кшталт Flux/Replicate документують той самий патерн: не блокувати client-side >30s; webhook або backend — приклад у marketplace. OpenAI plugin може мати Batch Operations — альтернатива сирому Connector (plugin page).
Матриця рішень для bulk-каталогу
| Сценарій | Обсяг / SLA | Режим | Де в Bubble | WU / stuck-risk |
|---|---|---|---|---|
| Прев’ю в адмінці, юзер чекає на екрані | 1–5 зображень, кожне стабільно < ~25–30 с | Sync у backend workflow (не на client) | API Connector або plugin action | Низький, якщо не впираєтесь в IPM провайдера |
| Каталог «на ніч», десятки–низькі сотні | Хвилини, можна без realtime UI | Async job: Thing ImageJob (status, external_id, sku_key) + scheduled backend poll (coarse interval) |
Опційно webhook endpoint, якщо посередник підтримує | Середній: кожен poll = run; потрібні max iterations і terminal states |
| Backfill / mass SKU, сотні–тисячі+, ціна і rate limits критичні | Години SLA ок | Provider Batch або BIAIG batch-job | Один workflow: submit batch → зберегти batch_id → рідкий poll → import JSONL/results |
Низький на fan-out, високий на помилки мапінгу |
| Vertex Imagen легасі | Sync :predict |
Лише footnote / міграція на Gemini Nano Banana | Окремий шлях від Gemini Batch API | Як sync burst |
Правила переходу (практичні пороги)
- Залишайтесь у sync, поки один image call + Bubble overhead вкладаються в < ~30 s і загальна кількість за сесію не вимагає IPM, якого у вас немає на tier.
- Переходьте на async job, коли sync дає retry/timeout або вам потрібно > ~10–20 зображень без блокування UI — але не poll-ите кожні 5 с: інтервал у хвилини + backoff.
- Переходьте на Batch / BIAIG, коли job триває годинами, потрібен batch discount, або standard pool вас душить; batch ID і
custom_id/ task id persist у БД (OpenAI: порядок output ≠ input). Поруч із цим: OpenAI Batch API для images.
BIAIG batch-job у Bubble (оркестрація, не magic)
Typical flow (BulkImagen API docs як референс патерну):
- Backend workflow: зібрати prompts + stable keys (SKU, variant) →
POST /v1/batches. - Записати
batch_id,submitted_at, expected model ID. - Scheduled workflow (напр. кожні 15–60 хв):
GET /v1/batches/{id}покиdoneабо failed/expired. - Import результатів у Things; зображення — у Storage/CDN, у Bubble лише URL + metadata.
Ключі лише server-side (BulkImagen вимагає server-side keys) — bulk-каталог не генеруйте з client workflow.
Календар cutover: digest vs vendor
Внутрішній digest згадував «23.10 gpt-image-1 / 29.10 Nano Banana 2». Я звірив це з публічними таблицями Scout на 2026-10-22 і отримав інші дати:
- OpenAI
gpt-image-1shutdown — 2026-10-23 (не «жовтень 2025»). - Nano Banana 2 GA — 2026-05-28 у Gemini changelog; 2025-10-29 — інший реліз (logging/datasets).
Дія для builder: орієнтуйтесь на OpenAI deprecations і Gemini deprecations, а не на дати без року в digest.
Checklist перед prod bulk
- Idempotency key на sync (або уникати sync для повільних моделей).
- Job table:
pending | running | done | failed | expired. - Poll guard: max attempts, alert на
batch_expired(24h window OpenAI). - Importer keyed by
custom_id/ task id, не by row order. - Великі binary — не через 50 MB Connector response.
- Окремо пораховані provider $ і Bubble WU (офіційний WU breakdown для poll vs one long call у Scout не знайдено — виміряйте на staging).
| Check | Requirement | Notes |
|---|---|---|
| Idempotency | Idempotency key on sync | Or avoid sync for slow models |
| Job table | pending | running | done | failed | expired |
— |
| Poll guard | Max attempts; alert on batch_expired |
24h window (OpenAI) |
| Importer | Key by custom_id / task id |
Not by row order |
| Large binary | Do not route via Connector response | 50 MB limit |
| Cost | Separate provider $ and Bubble WU | Official WU breakdown for poll vs one long call in Scout not found — measure on staging |
Джерела
OpenAI: Batch guide, pricing, image generation. Google: Gemini Batch, image generation, changelog. Bubble: API Connector, hard limits. Оркестратор: BulkImagen API.
Internal draft — not for external publication.