Back to results for “Async”
Node.js › Async Patterns

What is 'fire-and-forget' async code, and why is it generally discouraged in production Node.js applications?

Advanced

Answer

Fire-and-forget means calling an async function without awaiting or attaching a .catch() to its returned promise -- the calling code moves on immediately without knowing whether the operation succeeded, failed, or is still in progress. This is discouraged because any rejection becomes an unhandled promise rejection (potentially crashing the process on modern Node.js), and because the calling code has no way to guarantee the operation actually completed before, say, the process exits or a response is sent.
// Fire-and-forget: risky, errors are silently unhandled
function handleRequest(req, res) {
  logAnalyticsEvent(req); // not awaited -- if this rejects, it's an unhandled rejection
  res.json({ status: 'ok' });
}

// Safer: explicitly handle the case where you intentionally don't want to block
function handleRequest(req, res) {
  logAnalyticsEvent(req).catch(err => logger.error('Analytics logging failed', err));
  res.json({ status: 'ok' });
}
Real-world example A team notices intermittent process crashes traced to a fire-and-forget analytics-logging call that occasionally rejected due to a network blip; adding an explicit .catch() to swallow and log that specific, genuinely non-critical failure resolves the crashes without needing to await the call and slow down the response.

Common follow-ups: In what situation is fire-and-forget actually the correct, deliberate choice rather than a bug?;How does this interact with Node's default unhandled-rejection termination behavior discussed earlier?