Many useful AI features follow the same shape: something happens (a call ends, a document arrives, a form is submitted), a service fetches some context, asks a model to produce something and then delivers the result. Wiring that together is simple. Making it dependable, so that no event is silently lost, is the real engineering work.

Key takeaways

  • Decouple receiving an event from processing it, with a durable queue in between.
  • Persist the state of every unit of work so a restart never loses track of it.
  • Make each step safe to repeat, then retry freely with backoff.
  • Run a reconciliation sweep that finds anything missing, stuck or failed and re-triggers it.

Why AI steps change the reliability picture

A model call is slow compared with a database query, it can be throttled, it can fail intermittently and the input it needs may not be ready when the event arrives. If you process the event inline in the web request that received it, any of those problems turns into a lost or duplicated event. The fix is architectural, not a matter of adding more try/catch.

Pattern 1: accept fast, process later

The endpoint that receives the event should do the minimum: validate it, record it durably and acknowledge. Processing happens from a queue or event stream by separate workers. This keeps the receiver responsive, lets you absorb bursts and gives you a natural place to scale and to pause.

Pattern 2: persisted state per item

Give every unit of work a record with an explicit status, for example PENDING, PROCESSING, COMPLETED and FAILED, plus attempt counts and timestamps. If an input is not ready yet, leave the record PENDING and let the next cycle pick it up. Because state lives in a database, a crash mid-process leaves a record you can find and resume, not a mystery.

Pattern 3: idempotent steps and bounded retries

Most queues deliver at least once, so your handlers will sometimes see the same event twice. Design each step so repeating it is harmless: use a stable identifier as a key, check whether the work is already done and make side effects such as sending an email conditional on a recorded outcome. With that in place you can retry confidently, using exponential backoff with jitter and a maximum attempt count. Items that exceed the limit go to a dead-letter queue or a FAILED state for inspection, not into an infinite loop.

Pattern 4: a reconciliation sweep

Even a well-built pipeline can miss something: a dropped webhook, a bug, an outage during deployment. A reconciliation job periodically compares the source of truth (what events should have been processed) with your processing records, finds items that are missing, pending too long or failed and re-triggers them. It turns "we hope nothing was lost" into "we check, regularly, that nothing was lost."

  • Stream identifiers page by page instead of loading everything into memory, with a bounded queue connecting reader and workers, so memory use stays flat as data grows.
  • Make the sweep triggerable on a schedule and on demand through an authenticated endpoint.
  • Tune parallelism per environment, and apply backoff so the sweep does not overwhelm upstream APIs.

Pattern 5: reliable hand-off with an outbox

When a service must both update its database and publish an event, doing the two separately risks one succeeding without the other. Write the event to an outbox table in the same transaction as the data change, then publish from the outbox. Downstream consumers see every change exactly because it was recorded atomically.

Make it debuggable

Attach correlation identifiers (for example the business identifier plus a request identifier) to every log line and message, and use structured logging. When something goes wrong in production, you should be able to follow a single item from receipt to delivery in one query.

A short checklist

  • Is every event durably recorded before it is acknowledged?
  • Does every item have a visible status, attempts and timestamps?
  • Can every step be repeated safely?
  • What happens after the last retry?
  • Would you know, within a day, if something had been missed?

This article offers general engineering perspective. It does not describe a specific client engagement.