Blog

Workflow2 min read

Webhooks vs Polling: When Each Pays Off

Webhook setup cost versus polling cost. The crossover point is lower than you think for fal video jobs.


Both work. Both cost you time, either in waiting on polls or in wiring up a handler. The math is simpler than people make it, and the crossover point is lower than you think.

What polling actually costs

A poll every two seconds on a 60-second job means 30 status calls. Status calls are cheap, but not free, and your code is blocked the whole time. Thirty clips at 60 seconds each, polled in parallel, is 900 status calls. Your code spends all that time awake and holding a TCP connection.

Polling loop versus a single webhook fire
Polling loop versus a single webhook fire

What a webhook costs

One public URL. One endpoint handler. Signature verification, if you care about replay attacks. Idempotent writes in your handler. That is it. Setup is a day, including tests. Runtime cost is a single inbound request per completed job.

The crossover

If your pipeline runs more than 10 generations per day, and your jobs average 30 seconds or longer, a webhook pays for itself in the first month. Polling still wins for small shell scripts and one-off experiments, because you can write a polling loop in four lines. But for any production job, webhooks are the default.

The polling pattern, done right

Exponential, not linear. Cap the interval. Stop after a timeout.

JAVASCRIPT
1async function pollUntil(requestId, modelId, { timeoutMs = 600000 } = {}) {
2 const start = Date.now();
3 let interval = 2000;
4 while (Date.now() - start < timeoutMs) {
5 const status = await fal.queue.status(modelId, { requestId });
6 if (status.status === "COMPLETED") return status;
7 if (status.status === "FAILED") throw new Error("job failed");
8 await new Promise(r => setTimeout(r, interval));
9 interval = Math.min(interval * 1.3, 15000);
10 }
11 throw new Error("poll timeout");
12}

The webhook pattern, done right

Submit with a webhookUrl. Return 200 fast from your handler. Write to your DB. Never do heavy work in the handler itself.

JAVASCRIPT
1await fal.queue.submit("fal-ai/wan/v2.7/text-to-video", {
2 input: { prompt, duration: 5 },
3 webhookUrl: "https://your.app/api/fal-webhook"
4});
A webhook endpoint with a bell icon
A webhook endpoint with a bell icon

Security

Do not trust the inbound request until you verify it. Every webhook handler should confirm the sender, check a shared secret or signature header, and reject duplicates by request_id. Without that, you are writing an open public endpoint.

Choosing

Polling when: fewer than 10 jobs a day, short one-shots, interactive CLI use. Webhook when: production, multiple users, async jobs that exceed 30 seconds. The fact that fal exposes both is not an invitation to argue; it is an invitation to use each for what it is good at.