BulkImagen async batches with nano-banana-2-1: Bubble workflow before NB2 cutover (29 Oct) without blocking WUs
A production Bubble pattern: create a BulkImagen batch on the backend, poll until done, map public resultUrls back to catalog rows—with an honest NB2.1 cutover checklist and scoped “non-blocking” UX.
Why this matters now
I run bulk catalog image generation. A long page workflow on the button click hits page timeouts and bad UX fast. BulkImagen gives async batches: POST /api/v1/batches with model slug nano-banana-2-1, credits charged at create, immediate response, completion via GET /api/v1/batches/{id} polling (~every 5s until batch.done is true). Their OpenAPI describes no webhook—poll only.
Google shipped gemini-nano-banana-2.1 to GA on 6 Oct 2026; gemini-3.1-flash-image (Nano Banana 2) is deprecated with recommended replacement NB2.1. In primary deprecations/changelog material in the Scout packet, no NB2 shutdown date is announced. Editorial use of 29 Oct as a hard cutover may be outdated—I verify Gemini deprecations before I ship countdown copy, not an internal digest. A closer look: 29 Oct 2026 Nano Banana.
Imagen 4 GA endpoints are deprecated with shutdown 17 Aug 2026—already in the past relative to 12 Oct 2026. Any remaining Imagen 4 paths are a separate emergency migration, not just swapping BulkImagen model slugs.
What “without blocking WUs” actually means
Scope it honestly:
- Yes: avoid blocking the user’s page workflow with synchronous API chains after a button click.
- No: backend Schedule API Workflow polling still consumes workload units; tight recursive polls can cost more than list-based scheduling patterns.
The title targets UX and architecture, not zero backend WU spend.
Bubble production pattern
1. Minimal data model
- Catalog row — prompt, status (
pending/ready/failed), optional stored image. - Batch job Thing —
batchId, provider = BulkImagen, status, timestamps, link to rows.
Keep a stable row id on your side. BulkImagen’s documented schema (Scout pass) does not show a per-task custom key—mapping is usually by submission order, task.id, or one task per row via smaller batches.
2. Short page workflow
- User selects rows / clicks generate.
- Set rows to
pending. - Schedule API Workflow now—do not call BulkImagen synchronously on the page.
- Show job id or “processing”.
Use API Connector for outbound calls; BulkImagen keys server-side only.
3. Backend: create batch
POST /api/v1/batcheswithnano-banana-2-1and prompts from catalog rows.- Persist
batchId; set jobsubmitted. - Schedule Poll batch ~5s later (aligned with vendor guidance).
Handle rate_limited and concurrent_limit_exceeded with backoff—do not poll every 5s through 429s.
4. Backend: poll loop
GET /api/v1/batches/{id}.- If not
batch.done, recursive API workflow: schedule self at Current date/time + delay (5–30s under load). - When done, read tasks:
status,resultUrls(public, no auth).
Bubble default: new apps since Jul 2024 often cap recursive iterations at ~10—long batches stop early unless you raise the limit. Put this in your runbook.
Alternative: Google Batch API for gemini-nano-banana-2.1 (~50% batch pricing vs standard, ~24h target turnaround, polling plus optional batch.succeeded / batch.failed webhooks to HTTPS). Inbound webhooks land on Workflow API, not API Connector. This article focuses on BulkImagen poll-only; direct Gemini is a sibling path if you own Google keys and want webhooks instead of recursive poll.
5. Map results to catalog rows
- Simplest: one prompt per row in one batch.
- Repeated prompts or fan-out: do not map by prompt text alone; store
(rowId, prompt)on the job and match by submission index if order is stable—prove on staging. - Partial failures: failed tasks → row
failed; job →completed_with_errors.
6. Storage
BulkImagen resultUrls are public third-party links. For private catalogs, fetch into Bubble file storage on the backend; avoid exposing URLs unnecessarily. A closer look: The ~500-row bulk-tools ceiling in.
Cutover checklist (NB2 → NB2.1, plus Imagen 4)
- Read deprecations—any shutdown date for
gemini-3.1-flash-image? - Confirm BulkImagen batches use
nano-banana-2-1(vendor routing to Google’sgemini-nano-banana-2.1is not guaranteed transparent). - Inventory other connectors still on NB2 or Imagen 4.
- Staging: small batch, validate task ↔ row mapping.
- Production: enable job + poll; watch WU and recursive caps.
- Tariff math (~50% Google batch tier)—separate articles; this piece is orchestration only. Worth reading next: Imagen 3 GA endpoints discontinued:.
| Step | Task | Notes |
|---|---|---|
| 1 | Read deprecations | Check for any shutdown date for gemini-3.1-flash-image |
| 2 | Confirm BulkImagen batches use nano-banana-2-1 |
Vendor routing to Google’s gemini-nano-banana-2.1 is not guaranteed transparent |
| 3 | Inventory other connectors | Find connectors still on NB2 or Imagen 4 |
| 4 | Staging | Small batch; validate task ↔ row mapping |
| 5 | Production | Enable job + poll; watch WU and recursive caps |
| 6 | Tariff math | ~50% Google batch tier—separate articles; this piece is orchestration only |
Risks (short)
- Timeline: internal digest vs Google primary docs.
- Vendor boundary: BulkImagen credits and behavior ≠ Google batch SLA.
- WU: polling costs money in Bubble—backoff helps.
- Security: public URLs—mirror to private storage when needed.
What I ship
Pattern: thin page workflow → backend batch create → store batchId → recursive scheduled poll until batch.done → map tasks to catalog rows → optionally mirror files. Migrate toward nano-banana-2-1 / gemini-nano-banana-2.1 using the deprecations checklist, not an unverified calendar date. “Non-blocking WUs” means non-blocking for the user on the page—plan backend WU and recursive limits explicitly.