Architecture5 min read

Background Jobs Without Message Queues

The simpler pattern for durable execution.

When developers need to run a task in the background—like sending a welcome email, generating a PDF, or syncing data—the default answer is often "set up a message queue." We reach for RabbitMQ, SQS, or Redis-based solutions like BullMQ.

But for many applications, these queues introduce significant complexity and operational overhead. There's a simpler way: HTTP-based durable execution.

The Complexity of Traditional Queues

Setting up a traditional message queue involves several moving parts:

  • Infrastructure: You need to provision and manage the queue server (Redis, RabbitMQ, etc.).
  • Workers: You need to write, deploy, and scale separate worker processes that poll the queue.
  • Serialization: You have to handle serializing and deserializing job data.
  • Monitoring: You need specialized tools to see what's in the queue, what failed, and why.

This is a lot of "plumbing" to write before you can even start on your actual business logic.

The HTTP-Based Alternative

What if you could trigger a background job with a simple HTTP POST request? Instead of pushing to a queue, you send a request to a service that guarantees delivery.

This pattern is called Durable HTTP. It treats your existing API endpoints as the "workers." When you want to run a background job, you tell a relay service to call your endpoint. If your endpoint is down or returns an error, the relay service retries until it succeeds.

Background Jobs with FetchAPI

FetchAPI makes this pattern incredibly easy. You don't need to manage any infrastructure. You just POST to FetchAPI, and we handle the rest.

One of the most powerful features for background jobs is the X-Delay header. This allows you to schedule a task to run in the future.

Example: Sending a Delayed Email

Suppose you want to send a "How are you liking the app?" email 24 hours after a user signs up. With a traditional queue, you'd need a "delayed job" feature. With FetchAPI, it's one header:

await fetch('https://api.fetchapi.dev/v1/fetch', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer relay_sk_...',
    'X-Fetch-Url': 'https://api.myapp.com/jobs/send-welcome-email',
    'X-Delay': '24h', // Delay the request by 24 hours
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ userId: 'user_456' })
});

Why This is Better

  • No New Infrastructure: Use your existing web server and API routes.
  • Language Agnostic: Works with any language that can receive an HTTP request.
  • Unified Logging: Your background job logs are in the same place as your API logs.
  • Zero Scaling Issues: Your "workers" scale exactly like your web server.

When to Use This Pattern

This approach is perfect for tasks that take anywhere from a few seconds to a few minutes. It's ideal for:

  • Sending notifications (Email, Slack, SMS).
  • Webhooks and third-party API integrations.
  • Data synchronization and cleanup tasks.
  • Image processing or PDF generation.

Simplify Your Architecture

Ditch the complex message queues. Start running reliable background jobs with simple HTTP calls using FetchAPI.

Get Started Free