Node.js › Email & Notifications

Why should sending an email typically happen in a background job rather than synchronously within an HTTP request handler?

Intermediate

Answer

Sending an email involves a network call to an external mail provider that can be slow or occasionally fail -- doing this synchronously inside a request handler makes the user wait for that external call to complete (or fail) before getting a response, and ties the success of the user's core action (like registering an account) to the reliability of the email provider; enqueuing the email send as a background job lets the main request return immediately while a worker handles the actual sending, with its own independent retry logic.
// Blocking: the user waits for the email to send before getting a response
app.post('/register', async (req, res) => {
  const user = await createUser(req.body);
  await sendWelcomeEmail(user); // slow, and a failure here fails the whole request
  res.json(user);
});

// Better: enqueue and respond immediately
app.post('/register', async (req, res) => {
  const user = await createUser(req.body);
  await emailQueue.add('welcome-email', { userId: user.id });
  res.json(user);
});
Real-world example A registration endpoint that occasionally timed out during a third-party email provider's brief outages was fixed by moving the welcome-email send into a background job queue, so registration succeeds independently of email-provider availability, with the email itself retried automatically by the worker.

Common follow-ups: How would you notify a user if their welcome email ultimately fails after all configured retries?;What's the tradeoff of this asynchronous approach for genuinely time-sensitive emails, like a login verification code?