Why Your HTTP Requests Keep Timing Out (And How to Fix It)
Dispatched Team
12/27/2024
#background-jobs#web-development#performance
The 30-Second Problem
Your users start the file upload, wait patiently, and then... timeout error. Sound familiar? Modern web browsers enforce a 30-second timeout limit on HTTP requests. This means any operation taking longer - processing large files, sending bulk emails, or heavy data crunching - will fail.
Common Scenarios That Break
// DON'T: This will timeout
app.post('/process-video', async (req, res) => {
const video = req.files.video;
const options = req.body.options;
await processLargeVideo(video, options); // Takes 2-3 minutes
res.json({ success: true });
})
Three common cases where timeouts hurt:
- Video/image processing
- Bulk email sending
- Large data imports
The Background Job Solution
Here's how to handle it properly:
// 1. Upload video and queue processing job
app.post('/process-video', async (req, res) => {
const video = req.files.video;
// First, upload the raw video to storage
const videoUrl = await uploadToStorage(video);
const apiKey = process.env.DISPATCHED_API_KEY;
// Then queue the job and pass the uploaded video url
const response = await fetch('https://dispatched.dev/api/jobs/dispatch', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
payload: {
task: 'process_video',
videoUrl,
options: req.body.options
}
})
});
const { jobId } = await response.json();
res.json({ jobId });
})
// 2. Process it when webhook is called
app.post('/webhooks/dispatched', express.json(), (req, res) => {
const webhookSecret = process.env.DISPATCHED_WEBHOOK_SECRET;
if (req.headers.authorization !== `Bearer ${webhookSecret}`) {
return res.status(401).json({ error: 'Unauthorized' });
}
const { jobId, attemptId, payload } = req.body;
try {
console.log(`Processing job ${jobId} with attempt ${attemptId}`);
// Download video from storage
const video = await downloadFromStorage(payload.videoUrl);
// Process it
await processLargeVideo(video, payload.options);
// Cleanup
await deleteFromStorage(payload.videoUrl);
res.status(200).json({ status: 'success' });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
Implementing With Dispatched
- Create an API key in your dashboard
- Configure your webhook URL to receive job results
- Start dispatching jobs via HTTP POST
- Listen to webhooks and process the job
Performance Impact
Our customers report:
- 40% decrease in API timeouts
- 60% faster response times
- Zero lost tasks due to browser limitations
Start handling long-running tasks properly. Get started with Dispatched today.