Skip to main content

Polling vs Webhooks

We-Link offers two methods to retrieve results from async operations. Here's how they compare and when to use each.

Comparison

AspectWebhooks ✅Polling ⚠️
LatencyInstant (pushed on completion)Depends on poll interval
Server LoadMinimal (event-driven)High (repeated requests)
ReliabilityAt-least-once deliveryYou control retry logic
ComplexityRequires public endpointSimpler to implement
Real-timeYesNear-real-time at best

Choose webhooks when:

  • You need real-time updates
  • You're running in production with a public server
  • You manage multiple accounts (polling doesn't scale)
  • You want to minimize API calls and bandwidth
// Webhook: data comes to you
app.post("/webhook", (req, res) => {
res.status(200).send("OK");
processResult(req.body);
});

When to Use Polling

Choose polling when:

  • You're prototyping or testing locally
  • You can't expose a public URL
  • You need to check a specific request's status
  • As a fallback if a webhook was missed
// Polling: you go get the data
async function pollForResult(requestId, maxAttempts = 10) {
for (let i = 0; i < maxAttempts; i++) {
const response = await fetch("https://api.we-link.ai/api/v1/get_response", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": API_KEY,
"x-api-secret": API_SECRET,
},
body: JSON.stringify({ request_id: requestId }),
});

const data = await response.json();

if (data.status === "SUCCESS" || data.status === "FAILED") {
return data; // Task complete
}

// Wait before next poll (randomize to avoid patterns)
await sleep(randomBetween(15000, 45000));
}

throw new Error("Polling timeout");
}

Hybrid Approach (Best Practice)

Use webhooks as the primary delivery method with polling as a fallback:

// Save requestId with timestamp
await db.savePending(requestId, Date.now());

// Cron job: check for stale requests (no webhook after 5 mins)
async function reconcileStale() {
const stale = await db.getPendingOlderThan(5 * 60 * 1000);

for (const { requestId } of stale) {
const result = await pollForResult(requestId, 1);
if (result) {
await processResult(result);
await db.markComplete(requestId);
}
}
}
tip

The hybrid approach gives you the best of both worlds: real-time delivery via webhooks with guaranteed delivery via polling fallback.