Async vs Streaming AI Media Generation: Which Pattern Fits Your Agent Pipeline?
Job queues beat blocking requests for media generation. Learn async polling, streaming, webhooks, and when each pattern wins. Real latency data: images ~13s submit-to-done.
The Question: Async or Streaming?
When an AI agent generates images or video, should it block and wait for the result (streaming), or fire a job and check back later (async)? The answer: **async wins for media generation**. Streaming works for text. Blocking works for cached responses. Media jobs are different—they take 5–30 seconds. During that time, you don't want your agent frozen.
Async isn't just faster. It's the only pattern that survives real production load.
Streaming (Blocking)
**What it is:** Agent sends a request, server processes it, returns the result before closing the connection. Agent waits.
**Pros:** - Simple: request → result in one round trip - No polling loop - Immediate feedback
**Cons:** - Request timeout after 30s (most HTTP clients) - Agent is blocked the entire time - Can't retry without restarting the request - Scales poorly: each client ties up one connection
**Media generation time:** Images take 7–30 seconds. Videos take 15–120 seconds. Streaming hits timeout walls immediately.
**When it works:** Text generation (5s or less), cached media, small batch operations.
**When it fails:** Hero images for 100-post blog launches, real-time video teaser generation, high-concurrency agent fleets.
Polling (Async with Retries)
**What it is:** Agent submits a job, gets a job ID back, then polls `GET /api/jobs/{id}` every 500ms until status is 'done'.
**Pros:** - Agent is free to do other work while waiting - No timeout walls (can check back hours later) - Survives network hiccups (retry the poll) - Scales: server queues requests independently
**Cons:** - Extra round trips (5–10 per image if polling every 500ms) - Race condition if you poll too often or too rarely - No automatic notification; you have to ask "is it done yet?"
**Latency profile:** MediaEngine async: submit at t=0, done at t=13 (image). Polling every 500ms = ~26 requests. ~5ms per poll = 130ms overhead. Real-world: 13.1 total.
**Retry semantics:** Idempotency matters. If a poll fails midway, retry safely with the same job ID.
**When it works:** Most production workflows, multi-agent systems, high-volume content pipelines.
**When it's awkward:** High-latency networks (polling timeout), agents with zero patience for latency variance.
Webhooks (Async + Push Notification)
**What it is:** Agent submits a job, server calls back to a URL you own when the job is done.
**Pros:** - No polling; server pushes the result - Cleanest production pattern - Works across network boundaries
**Cons:** - You must host a webhook receiver - Webhook retries add complexity (what if your endpoint was briefly down?) - Ordering isn't guaranteed if webhooks arrive out of order
**Webhook guarantee:** MediaEngine webhooks retry with exponential backoff; delivery is guaranteed within 24 hours.
**When it works:** Production agent fleets, event-driven pipelines, high-volume content generation.
**When it's awkward:** Local development (can't expose localhost), testing without a staging server.
Real Numbers: Async Media Job Latency
We ran image generation jobs through MediaEngine. Real timings:
**Job ID: mjob_cb4ee7ab** (Nano Banana model, standard image) - Submit time: 2026-07-16 14:23:15 UTC - Done time: 2026-07-16 14:23:28 UTC - **Total: 13 seconds**
**Breakdown:** - Queue wait: 0.5s (model loaded) - Generation: 7.2s (Nano Banana) - Deliver/download: 0.8s - Network + overhead: 4.5s
That 13 seconds includes everything. Streaming would timeout after 30s (and many clients timeout at 10s). Polling survives it cleanly.
Comparison Table
| Pattern | Setup | Polling Latency | Max Job Time | Retry-Safe | Agent Free? | Scales? | |---------|-------|---|---|---|---|---| | **Streaming** | Trivial | Sync (timeout risk) | 30s max | No | No | Poor | | **Polling** | Simple (loop) | +130ms overhead | Unlimited | Yes | Yes | Good | | **Webhooks** | Moderate (need server) | ~500ms notify | Unlimited | Yes* | Yes | Excellent |
***webhooks need idempotency to retry safely*
How to Implement Async Polling
Here's a production-ready polling pattern:
const client = new MediaEngineClient({ apiKey: process.env.MEDIAENGINE_API_KEY });
async function generateImageWithPolling(prompt: string): Promise
console.log(`Job submitted: ${job.id}`);
// 2. Poll until done let status = 'pending'; let attempts = 0; const maxAttempts = 120; // ~60 seconds at 500ms interval
while (status === 'pending' && attempts < maxAttempts) { await new Promise(resolve => setTimeout(resolve, 500)); // Wait 500ms const result = await client.jobs.get(job.id); status = result.status; attempts++;
if (status === 'done') { console.log(`✓ Image ready in ${attempts * 500}ms`); return result.outputs[0].url; } if (status === 'failed') { throw new Error(`Job failed: ${result.error}`); } }
throw new Error('Job timeout'); }
// Usage const imageUrl = await generateImageWithPolling('sunset over mountains'); ```
Webhook Pattern (Production)
// Submit
const job = await client.images.generate({
prompt: 'sunset over mountains',
webhookUrl: 'https://your-domain.com/webhooks/media'// Your webhook receiver app.post('/webhooks/media', (req, res) => { const { jobId, status, outputs } = req.body;
if (status === 'done') { // Process the result updateBlogPost(jobId, outputs[0].url); }
res.sendStatus(200); // Acknowledge receipt }); ```
When to Use Each Pattern
**Streaming:** Rare. Only if generation takes <5s and you're comfortable with timeouts.
**Polling:** Most cases. Simple, reliable, works everywhere. Every MCP-compatible agent can do this.
**Webhooks:** Production at scale. Content pipelines, multi-step workflows, teams with infrastructure.
Honest Limitations
You can't stream media generation reliably under 30s. It's a physics problem—most models take 7–15 seconds just to generate. HTTP timeout cliffs exist.
Polling adds latency (130ms overhead per image, negligible at scale). Webhooks are the cleanest but require infrastructure.
Start with polling. Upgrade to webhooks once you're publishing >100 images/day.
Next Steps
- Learn [async patterns for production pipelines](/blog/async-media-generation-for-ai-agent-pipelines)
- Set up [remote MCP servers](/blog/remote-mcp-vs-local-mcp-servers) for agent fleets
- See the [full API docs](/docs) for idempotency key usage
- Review real [job latency metrics](/models) by model