
long-running agent email status update patterns compared
Your agent finished the job, but the user closed the app. Here are four patterns for delivering status updates from long-running AI agents.
Your agent kicks off a 20-minute research task. The user closes their laptop and goes for a walk. When the work finishes, how does the agent tell them?
This is the core problem behind every long-running agent email status update pattern. Most agent frameworks assume a persistent connection between agent and user: a chat window, a terminal session, a browser tab. That assumption holds for tasks that finish in seconds. It falls apart the moment your agent needs more than half a minute.
Four common patterns exist for delivering status updates from long-running agents. Each one solves a different piece of the problem, and picking the wrong one means your user either drowns in noise or never learns the job is done.
Comparing long-running agent status update patterns#
| Pattern | Trigger point | Delivery method | Best for | Key drawback |
|---|---|---|---|---|
| Background worker + polling | Client requests status | API endpoint | Dashboard UIs | Requires open client |
| Email push notification | Agent milestone reached | Email delivery | Async, offline users | Deliverability setup |
| Webhook callback | Agent state change | HTTP POST | Server-to-server | Needs receiving server |
| Streaming + continuation token | Continuous or reconnect | SSE / WebSocket | Real-time UIs | Breaks on disconnect |
The right choice depends on two things: whether the user is actively watching, and how long the task takes. Let's walk through each one.
The background worker pattern#
This is the default in most agent frameworks. Your agent runs as a background process. The client polls a status endpoint, or subscribes to a queue, to check on progress.
Microsoft's Agent Framework uses this approach for operations exceeding 30 seconds. The agent returns a 202 Accepted response with a status URL, and the client polls that URL until the work completes. Convex's agent library follows a similar model, storing agent state in a database that the frontend queries.
// Simplified polling loop
const statusUrl = response.headers.get("Operation-Location");
let result;
do {
await sleep(5000);
result = await fetch(statusUrl).then(r => r.json());
} while (result.status === "running");
The pattern works well when your user has a UI open. It breaks when they don't. If the user closes the tab, the polling stops. You can mitigate this with service workers or browser push notifications, but those require the browser to be running in the first place. For truly offline delivery, you need a different channel.
Email push notifications#
Email is the delivery channel nobody thinks of first but almost every user actually checks. When your agent hits a milestone, fails, or needs approval, it sends an email directly to the user.
This approach works well for long-running agents because no open connection is required. The user can close everything and still get the update on their phone or laptop hours later. Email also creates a paper trail: the user can search their inbox for agent updates six months from now. And the part most people overlook is that email opens a reply channel. The user can respond to the status update with new instructions, turning a one-way notification into a conversation.
We covered several of these use cases in 7 things your ai agent can do with its own email, including status reporting, approval workflows, and error escalation.
The catch is that email delivery requires proper infrastructure. SPF and DKIM records, domain reputation, and a throttling strategy so your user doesn't receive 47 messages from an agent that changes state every 12 seconds.
Webhook callbacks#
Webhooks flip the direction. Instead of the client asking "are you done yet?", the agent POSTs to a callback URL when something changes. This is the standard pattern for server-to-server communication, where the "client" is another service rather than a human with a browser.
Webhooks are fast and efficient. No wasted polling requests, no persistent connections. But they assume the receiving server is always available, which isn't true for personal projects, serverless functions with cold starts, or any system behind a firewall. They also don't reach humans directly. A webhook can trigger a downstream notification (Slack message, email, SMS), but that adds one more integration to maintain.
Streaming with continuation tokens#
Streaming via Server-Sent Events or WebSocket gives the user real-time updates as the agent works. Progress bars, step-by-step logs, live token generation: streaming makes all of this feel immediate.
The problem is disconnection. The user's network drops, or they switch tabs, or the browser crashes. When they reconnect, where does the stream pick up?
Continuation tokens solve this. The agent periodically checkpoints its state and issues a token. When the client reconnects, it passes the last token it received, and the stream resumes from that point. Both Microsoft's Agent Framework and LangGraph support this pattern.
// Reconnecting with a continuation token
const stream = await agent.stream({
task: "analyze-competitors",
continuationToken: lastKnownToken,
});
The limitation is architectural. Streaming requires server resources for every connected client. At scale, maintaining thousands of persistent connections gets expensive. And if the user never reconnects, the work is done but they don't know it.
When to pick email#
The decision tree is simpler than it looks.
If the task finishes in under a minute and the user is watching, stream it. If the task takes longer and the user might walk away, send an email at major milestones. If the user is another service rather than a human, use webhooks. If you want the best of both worlds, combine streaming with email fallback: stream while connected, email if the connection drops and doesn't return within a reasonable window.
Email works particularly well for agent workflows that need human decisions mid-execution. "I found three candidates. Want me to proceed?" The user replies, the agent continues. This turns email from a one-way notification into a two-way control plane that works on the user's schedule, not your agent's.
For more on how email fits alongside chat, voice, and other channels, see the agent communication stack.
Reply-triggered resumption#
One pattern that gets almost no coverage in agent framework documentation is reply-triggered resumption. Your agent sends a status email: "I found three suppliers matching your criteria. Should I proceed with outreach or do you want to review them first?" The user replies "proceed with the top two." The agent parses the reply and continues execution.
For this to work, the agent needs its own inbox. Not a shared noreply address. It needs to receive mail, parse the reply content, and map the response back to the correct running workflow. The payoff is significant: users interact on their own schedule, and the agent keeps working without anyone opening a dashboard.
Deduplication and throttling#
Agents that retry failed steps or enter high-frequency state changes will flood a user's inbox without proper safeguards. Two patterns handle this.
For deduplication, attach an idempotency key to each status email, tied to the agent's execution step. If the agent retries step 4 three times, the sending infrastructure checks the key and the user gets one email. Not three.
For throttling, set a minimum interval between status emails (60 seconds works for most cases) and batch intermediate changes into a single digest. If the agent burns through steps 5 through 8 in 20 seconds, the user gets one message: "Steps 5-8 complete. Currently on step 9."
Without these controls, the first agent that hits a retry loop will train your user to ignore every future status email. An ignored notification channel is worse than no channel at all.
What belongs in a status update email#
A good agent status email answers five questions in as few words as possible. What the agent just completed: "Your research agent finished analyzing 340 LinkedIn profiles." What comes next: "Compiling results into a ranked shortlist, about 8 minutes." Whether the user needs to act: "Reply APPROVE to send outreach, or PAUSE to review first." Where to see full details: a link to the dashboard or results page. And if something broke, what went wrong: "API rate limit hit. Will retry in 5 minutes."
Skip everything else. No greetings, no sign-offs, no filler. The user wants signal. Give them signal.
Infrastructure for agentic email#
Sending status emails from an agent pipeline differs from sending marketing newsletters in ways that matter.
Volume is unpredictable. A marketing campaign sends a known number of emails at a scheduled time. An agent pipeline might send zero emails today and 2,000 tomorrow, depending on how many tasks users trigger. Your infrastructure needs to handle both without manual warm-up cycles.
Timing matters more than throughput. A status email that arrives 30 minutes late is almost useless. The user has already assumed something broke, or they've moved on entirely.
Bounce handling affects agent logic directly. If a status email bounces, the agent needs a fallback. Should it retry with a different address? Switch to Slack? Pause execution until the user is reachable? These decisions should live in the agent's workflow, not in a separate ops layer.
If your agent needs its own inbox for sending updates and receiving replies, LobsterMail handles the provisioning. Your agent hatches an inbox with a single SDK call and starts sending immediately, no DNS configuration required on the free tier. For custom domain sending, the Builder plan at $9/month covers that. if you want to try the reply-triggered pattern from earlier.
Picking the right pattern#
The long-running agent email status update pattern isn't one technique. It's a decision about how your agent reaches the person waiting for results. Stream when they're watching. Email when they're not. Use continuation tokens to bridge the gap between the two. And whatever you choose, build in deduplication from day one. Retrofitting throttle controls after your users start muting notifications is a much harder problem than adding them upfront.
The agents that keep users informed are the ones users trust enough to keep running.
Frequently asked questions
What is a long-running agent email status update pattern?
It's a design pattern where an AI agent sends email notifications at key milestones during a task that takes more than a few seconds to complete. The email reaches the user even if they've closed the app or walked away from their computer.
When should an AI agent send an email update instead of relying on a polling endpoint?
Email is the better choice when the user might not have your app open, when the task runs longer than a few minutes, or when the agent needs a human decision before continuing. Polling only works while the client is actively connected.
How do you prevent duplicate status emails when an agent retries a failed step?
Assign an idempotency key to each email, tied to the specific execution step. Your sending infrastructure checks the key before delivering and silently drops duplicates. Three retries of step 4 produce one email, not three.
What information should an automated agent status email include?
What the agent just completed, what it will do next (with a time estimate), whether the user needs to take action, a link to full results, and error details if something went wrong. Keep it under ten sentences.
How do you handle email delivery failures inside a long-running agent workflow?
Build a fallback into the agent's logic. If the status email bounces, the agent can retry with an alternate address, switch to a different channel like Slack, or pause execution and wait for the user to become reachable again.
What is a continuation token in agent frameworks?
A continuation token is a checkpoint marker issued periodically during a long-running task. If the client disconnects, it can reconnect and pass the last token it received to resume the stream from that point, rather than restarting the entire operation.
Can a user reply to an agent status email to approve or redirect next steps?
Yes, if the agent has its own inbox capable of receiving mail. The agent sends a status update with options like "Reply APPROVE or PAUSE," the user replies, and the agent parses the response to continue execution accordingly.
How do you throttle email notifications for agents that change state rapidly?
Set a minimum interval between emails (60 seconds is a reasonable default) and batch intermediate state changes into a single digest. If the agent completes five steps in 20 seconds, the user gets one summary email instead of five separate messages.
Should status emails fire at every agent step or only at major milestones?
Major milestones and completions only. Emailing every minor step creates noise that trains users to ignore your notifications. Reserve emails for task completion, errors that need attention, and moments where the agent needs human input to proceed.
What is the async agent pattern for operations longer than 30 seconds?
The agent accepts the request and immediately returns a 202 Accepted response with a status URL or job ID. Work continues in the background. The client can poll the status URL, wait for an email notification, or receive a webhook callback when the work finishes.
How do you scale email status updates across thousands of concurrent agent instances?
Use a message queue between your agent pipeline and your email sending service. Agents push status events to the queue, and a dedicated service handles deduplication, throttling, and delivery. This decouples agent execution speed from email sending capacity.
What is the difference between polling and webhooks for agent status updates?
Polling has the client repeatedly ask "are you done?" at intervals, which is simple but wasteful. Webhooks have the agent push a notification when state changes, which is efficient but requires the receiving server to be always available. Polling is better for browser clients; webhooks suit server-to-server workflows.
How do you write a clear status update email for an automated agent process?
Lead with what happened, state what's next, flag any required action, and include a link to full details. Skip greetings and filler. The user should understand the current state within five seconds of opening the email.
What is the recommended fallback if an agent's status email bounces or goes unread?
Implement timeout-based escalation. If the email bounces, try an alternate contact method. If it's delivered but not opened within a set window (two hours, for example), send a follow-up through a different channel. If the agent needs user input to continue, pause execution rather than proceeding blindly.


