---
title: "Background Jobs: Keeping AI Chat Fast, Booking Async"
description: Flight bookings take seconds. Email confirmations take longer. Job queues keep the conversation snappy while heavy lifting runs in the background.
canonical: https://nowah.xyz/blog/background-jobs-ai-travel-booking
lastModified: "2026-08-07T03:46:15.565Z"
---

# Background Jobs: Keeping AI Chat Fast, Booking Async

Flight bookings take seconds. Email confirmations take longer. Job queues keep the conversation snappy while heavy lifting runs in the background.

Our AI agent responds with streamed content within a couple of seconds. That's the bar for conversational AI. Exceed it and the interaction feels sluggish. Fall below it and you've got something that feels like talking to a friend.

But some operations take longer than two seconds. Confirming a booking with an airline can take five to ten seconds. Generating a PDF confirmation takes a couple seconds. Sending an email confirmation takes a second or two. Processing a payment webhook and updating all related records takes several hundred milliseconds but involves multiple database writes.

If we blocked the conversation on these operations, the user would stare at nothing while we generate their confirmation email. That's dumb. The email can happen in the background. The user should immediately hear "Your flight is booked!" and move on.

This is why we built a job queue system. Keep the conversation fast. Let the heavy lifting happen asynchronously.

## Why async processing matters for AI chat

![Illustration for this section](https://pics.nowah.xyz/website-media/engineering-018-img-1.webp)

The constraint is simple: the conversation must never wait for operations the user doesn't need to see. The user needs to know their booking was confirmed. They don't need to wait for the email to send, the PDF to generate, or the analytics event to fire.

We draw a clear line between synchronous operations (things the user is waiting for) and asynchronous operations (things that happen as a consequence).

Synchronous: payment authorization, booking creation, confirmation message. These happen in the conversation flow. The user sees "Processing your booking..." then "Confirmed! Your flight to Barcelona is booked."

Asynchronous: confirmation email, booking PDF, notification push, analytics events, trip record creation, document storage. These get dispatched to job queues and processed in the background. The user never waits for them.

External travel API latency is unpredictable and often exceeds five seconds. We can't control that, but we can control how much of it blocks the conversation.

## Job queue architecture

We use a queue-backed job queue system with multiple worker queues, each dedicated to a specific type of work.

**Booking queue.** Handles post-booking operations: finalizing records, storing confirmation details, updating trip state. These jobs have high priority and strict delivery guarantees because a lost booking record is a serious problem.

**Email queue.** Processes transactional emails: booking confirmations, itinerary summaries, receipt delivery. These are important but tolerant of short delays.

**Notification queue.** Handles [push notification](/blog/push-notification-travel-alerts) delivery to mobile devices. Similar priority to email with separate retry logic because push delivery has different failure modes.

**Document queue.** Generates PDFs, stores [boarding passes](/blog/launching-document-management-boarding-passes), creates itinerary documents. These are CPU-intensive but not time-sensitive.

**Analytics queue.** Fires analytics events, updates dashboards, processes metrics. Lowest priority. These can tolerate minutes of delay without impact.

Separate queues let us tune priority, concurrency, and retry behavior independently for each job type. A slow document generation job shouldn't delay a booking confirmation email. A spike in analytics events shouldn't affect notification delivery.

## Retry strategies

![Supporting diagram](https://pics.nowah.xyz/website-media/engineering-018-img-2.webp)

Jobs fail. APIs time out. Email servers reject connections. Push notification services rate-limit you. The retry strategy determines whether a transient failure becomes a permanent one.

We use exponential backoff with jitter. The first retry happens after a short delay. Each subsequent retry waits longer, with randomized jitter to prevent thundering herd problems when multiple failed jobs retry simultaneously.

Different job types get different retry limits. Booking-related jobs retry aggressively: up to five or six attempts over several minutes. A failed booking record update is a data integrity issue that must be resolved. Email jobs retry moderately: three or four attempts over a longer window. If the email server is down for ten minutes, we'll catch it on a later retry.

Jobs that exhaust their retries go to a dead letter queue. We monitor the dead letter queue with alerts. Any job that lands there needs human attention, because it means a background operation permanently failed and needs manual resolution.

## Keeping the user informed

The trickiest part of async processing in a conversational interface is keeping the user informed about operations happening in the background.

On a traditional website, you'd show a "processing" indicator or an email with "Your booking is being confirmed." In a conversation, the agent can provide natural-language status updates.

"Your flight is booked! I'm sending you a confirmation email and preparing your trip documents. Those should arrive in the next few minutes."

If a background job affects something the user asks about, the agent knows to check. "Can I see my booking confirmation?" If the document is still being generated, the agent says: "Your confirmation PDF is still being prepared. Give me a minute and I'll have it ready for you." If it's done, the agent delivers it immediately.

This is the conversational equivalent of a progress bar, but it feels more natural because the agent handles it within the flow of conversation rather than through a separate UI element.

## Monitoring and alerting

Job queues are easy to build and hard to monitor well. The standard metrics:

**Queue depth.** How many jobs are waiting? A growing queue means workers aren't keeping up with incoming jobs. This could be a traffic spike (normal) or a worker failure (not normal).

**Processing latency.** How long does each job take from enqueue to completion? Gradual increases suggest degrading performance in downstream services.

**Failure rate.** What percentage of jobs fail? A sudden spike indicates a systemic problem (API outage, misconfiguration).

**Dead letter queue size.** Any non-zero value is worth investigating. Zero is the target.

We alert on all of these. Queue depth exceeding thresholds triggers a scaling alert. Failure rate spikes trigger on-call pages. Dead letter queue entries trigger investigation tickets.

Automated testing reduces regression incidents by 60 to 80 percent. We include job processing in our test suite: integration tests verify that booking operations correctly dispatch background jobs, and that those jobs process correctly with mocked external services.

## How this compares to traditional OTAs

Many traditional travel platforms process everything synchronously. You click "Book," and you wait. The page shows a loading animation for ten, fifteen, sometimes thirty seconds while the system processes your payment, confirms with the airline, generates your confirmation, sends your email, and updates your account.

Some of these platforms even block navigation. You literally can't leave the page or close the tab without risking a lost booking. That's a terrible experience driven by an architecture that doesn't distinguish between synchronous requirements and asynchronous consequences.

Our approach decouples these concerns. The conversation stays responsive. The booking confirms quickly. Everything else happens in the background, and the user is informed if and when they need to know about it.

The AI agent keeps chatting while jobs process. The user might ask "What should I know about Barcelona?" while their confirmation email is being sent. The agent handles the new question immediately because nothing about the email delivery is blocking the conversation thread.

That responsiveness is the difference between AI chat that feels like a conversation and AI chat that feels like a slow terminal. Background jobs make conversational speed possible even when the underlying operations are slow.

---

Nowah is an AI travel agent that searches and books real flights and hotels through conversation — no filters, no thirty open tabs. [Plan your next trip](https://app.nowah.xyz).
