Why Your HTTP Requests Keep Timing Out (And How to Fix It)

Dispatched Team

Dispatched Team

12/27/2024

#background-jobs#web-development#performance
Why Your HTTP Requests Keep Timing Out (And How to Fix It)

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

  1. Create an API key in your dashboard
  2. Configure your webhook URL to receive job results
  3. Start dispatching jobs via HTTP POST
  4. 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.