How we made AI generation survive anything, with Backblaze B2
MediaMint Engineering
The worst experience a generative app can offer: you wait four minutes for a video, the tab hiccups, and the result is just… gone. The credits aren’t, though. We designed MediaMint’s pipeline so that once a job is accepted, it finishes and lands in your library — no matter what happens to your browser, your connection, or even our servers, and this post is the tour of how.
Every generation is a durable job
When you hit generate, the API doesn’t call the model and hope. It writes a job row first — model, inputs, credit quote, state queued — and only then returns. A background worker picks the job up and walks it through a small state machine:
queued → submitted → running → uploading → done (or failed, with the reason).
Each transition is persisted before the work it describes proceeds. That ordering is the whole trick: the job store, not any process’s memory, is the source of truth. If the worker dies mid-job, the next worker reads the store, sees a submitted job with a provider request id, and resumes polling instead of resubmitting — so a crash can’t double- charge you or lose the render.
Why the client is allowed to disappear
Because the browser is just a viewer of job state, it holds no responsibility for the job’s life. Close the laptop mid-render; when you come back, the board replays job state and the finished clip is sitting where the placeholder was. This also means generation keeps working from a phone that sleeps every thirty seconds — a surprisingly common way people use the canvas.
B2 is the system of record for media
Model providers host outputs briefly, on URLs you don’t control. The uploading state exists because we treat those as scratch: the worker streams every output straight to Backblaze B2, and only the B2 object counts as done. Your library, boards, and share links all serve from B2 — a model provider deleting its copy an hour later is invisible to you.
Serving is done with signed, time-limited URLs (seven days), minted fresh whenever you load a board. Buckets are private; a leaked link goes stale in a week; and none of your media ever transits our application servers — the browser talks to B2 directly, which keeps downloads fast and our egress bill honest. Storage this cheap is also why we can afford to keep originals at full quality on every plan, including free.
Credits are settled by the same machine
The quote is computed before the job (per-megapixel for images, per-second for video — flat fees would lose money on a 4K render), held while it runs, and settled on the terminal state. done commits the spend; failed releases the hold automatically. Refunds aren’t a support ticket — they’re a state transition.
What this buys in practice
- Deploys are boring: workers drain, restart, and resume in-flight jobs.
- Provider hiccups retry with backoff instead of failing the user.
- A board is reconstructible from the job store + B2 alone.
- “It vanished” is a bug class we simply don’t have.
None of this is exotic — it’s a job queue, a state machine, and object storage, assembled so that the expensive thing (your generation) is never in RAM alone. The exotic part is how rarely generative apps bother.
Try it on the canvas
100 free credits a day. Every model. No card.