How to Deploy an AI Agent to Production in 2026 A hands-on guide to running AI agents in production found that resuming a crashed Claude Agent SDK agent required persisting the session transcript in both `~/.claude` and `~/.claude.json`, or setting `CLAUDE_CONFIG_DIR` to a volume, after a test agent built on Claude Sonnet 5.5 in Docker was killed mid-task. In the mid-send crash case, the resumed agent recognized the outcome was uncertain and asked a person, but without the transcript the job restarted and sent the email again; the guide recommends idempotency keys on tools that change things so agents can continue on their own. The guide also notes LangGraph's in-memory checkpointer loses everything on restart, so production setups use the Postgres checkpointer, and that LangGraph restarts the interrupted node from the beginning. All guides https://www.omnara.com/guides How to Deploy an AI Agent to Production in 2026 What changes when an agent serves real users, and what we saw when we crashed one On this page In production, an agent serves other people, runs for hours, waits on approvals, spends money, and gets killed by deploys while nobody is watching. We crashed one on purpose to see what survives. The Short Version What Happened When We Crashed an Agent We ran the Claude Agent SDK https://code.claude.com/docs/en/agent-sdk/overview in Docker with Claude Sonnet 5.5. The agent had two tools: one that sends an email to a customer and logs it, and one that waits on a slow report job. We told it to send one email, wait for the report, and finish. Then we killed the container at different points, started a new one, and told the agent to continue. In the mid-send case, the resumed agent recognized that the outcome was uncertain and asked a person. Without the transcript, our job started over and sent the email again. Saving the transcript took more than one folder. Claude Code keeps sessions in ~/.claude , but its config lives in ~/.claude.json , outside that folder. Mount both, or set CLAUDE CONFIG DIR to a volume so Claude Code keeps everything under it. The hard case is a crash between doing something and recording it. In our run, the agent stopped and asked, but the job still needed a person. Give tools that change things an idempotency key that the receiving service checks, or a way to check whether the action already happened, so the agent can continue on its own. This was one run of each case, so other models and versions may behave differently. Sessions That Survive Restarts The agent's state has to live outside the process running it. There are a few ways to do that: - A durable execution engine, like Temporal https://docs.temporal.io/develop/python/integrations/openai-agents or the Workflow SDK https://ai-sdk.dev/docs/agents/workflow-agent , records each step so a run resumes after a crash. - A checkpointer in your own database. LangGraph's in-memory checkpointer loses everything on restart, so production setups use the Postgres checkpointer https://github.com/langchain-ai/langgraph/tree/main/libs/checkpoint-postgres . It doesn't clean up old checkpoints, so plan for that. - The harness's own session store. The Claude Agent SDK can mirror transcripts https://code.claude.com/docs/en/agent-sdk/session-storage to S3, Redis, or Postgres, but the mirror is best-effort and doesn't cover files on the machine. - A managed agent platform. Claude Managed Agents, OpenAI's Agents API, and Omnara https://github.com/omnara-ai/omnara keep the session log for you, outside the machine the agent runs on. Omnara saves each finished step to Postgres, and if a worker dies, another worker continues from the last saved step. It's open source, so you can also run the whole platform on your own servers, with the session log in your own Postgres. Resuming usually runs some code again. LangGraph restarts the interrupted node from the beginning https://docs.langchain.com/oss/python/langgraph/interrupts , so anything before the pause has to be safe to repeat. Sandboxes and Isolation Run untrusted code in a sandbox, usually one per session. You can keep the agent loop in your backend and have it run code through sandbox tools, which is how Vercel's Open Agents https://github.com/vercel-labs/open-agents template works. The Claude Agent SDK also supports running the whole loop inside a container. Permission prompts don't contain what the agent runs, so put a container or microVM around anything it executes, limit where it can connect to, and keep credentials out of it. Stripe's coding agents run on dev machines https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents that are cut off from production and the internet, so they run without approval prompts at all. On GitHub-hosted runners, GitHub's agent runs behind a firewall https://docs.github.com/en/copilot/how-tos/use-copilot-agents/cloud-agent/customize-the-agent-firewall and can only push to its own branch. Cold starts matter once people are waiting. Ramp keeps a pool of warm sandboxes https://builders.ramp.com/post/why-we-built-our-background-agent and starts one as soon as a user begins typing. Many Users: Identity and Credentials When an agent acts for a user, it needs that user's access, not yours. On their managed agent platforms, Claude https://platform.claude.com/docs/en/managed-agents/vaults and OpenAI https://developers.openai.com/api/docs/guides/agents-api/tools/vaults can keep each user's credentials in a vault and inject them outside the sandbox, so the agent only sees a placeholder. That injection doesn't work with self-hosted sandboxes yet. In other setups, tokens reach your tool code or the runtime directly, so check where credentials become readable before running untrusted code. On AWS and Azure, AgentCore Identity and some Foundry tools can run the OAuth sign-in and store tokens for you. Your app still has to connect each sign-in to the right user. None of this checks who owns what. AgentCore, for example, doesn't enforce https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-security-best-practices.html which user a session belongs to, and leaves that mapping to your backend. Whatever platform you use: - Take the tenant from the authenticated request, not from anything the client sends. - Check ownership when someone starts, reads, streams, resumes, or approves a run. - Test that one tenant can't reach another tenant's sessions, files, memory, or credentials. - Set concurrency and spending limits per tenant. Memory needs the same care. Check which memory stores each user can attach to a session, and mount shared reference material read-only. A prompt injection can write to memory the agent can change, and later sessions read it as trusted https://platform.claude.com/docs/en/managed-agents/memory . Approvals That Can Wait for Days Use a pause that outlives the process, like LangGraph interrupts or the Claude Agent SDK's defer decision https://code.claude.com/docs/en/hooks defer-a-tool-call-for-later from a PreToolUse hook. Then someone can approve hours later and a different process can resume the run. defer only works when Claude makes one tool call in that turn, and Claude Code deletes saved sessions after 30 days by default. If you use a managed agent platform, check how it handles this. In Omnara, a tool set to ask first https://docs.omnara.com/tools/permissions pauses the agent on that exact call until someone approves or denies it, and the pause survives worker restarts and deploys. Save these alongside each pending approval: - The run state at the pause, in durable storage - The exact pending call, with its tool name and arguments, so the reviewer approves what will run - Who decided, what they decided, and when - An approval record that only one worker can claim, plus a stable action ID the tool uses to reject a duplicate - The version of your code, since a run paused on Monday may resume into Friday's deploy Don't rely on notifications to find pending approvals. Claude Managed Agents drops a webhook https://platform.claude.com/docs/en/managed-agents/webhooks after three failed deliveries, so keep a list you can poll. When a reviewer says no, record it and enforce it in the tool, then tell the model so it can pick another approach. Cost Limits Set explicit limits on model turns, tool retries, and elapsed time for every agent. Framework defaults range from a handful of turns to none, they change between versions, and a framework "step" isn't always a model call. Test your limits on the version you deploy. Stripe lets its coding agents fix CI failures once https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents and then stop, because more rounds rarely help. Provider spend caps lag behind usage. OpenAI says its spend limits aren't instantaneous https://developers.openai.com/api/docs/guides/spend-limits , Gemini's billing data can lag https://ai.google.dev/gemini-api/docs/billing behind its project caps, and calls already running can push past any cap. Claude Managed Agents has a per-session dollar cap https://platform.claude.com/docs/en/managed-agents/budgets that stops a session between model calls. Stop accepting new work before a budget runs out. One startup was charged $82,314 in 48 hours https://www.theregister.com/2026/03/03/gemini api key 82314 dollar charge/ after a Gemini key was stolen. Keep keys on the server, restrict them to the APIs they need, and alert when the cost per finished task goes up. Tracing Trace every model call and tool call, with the user, the agent version, and the cost attached. The OpenTelemetry conventions for AI https://github.com/open-telemetry/semantic-conventions-genai are still in development, and the defaults differ. The Claude Agent SDK's telemetry https://code.claude.com/docs/en/agent-sdk/observability leaves out conversation content unless you opt in, though its local transcripts still keep it. The AI SDK https://ai-sdk.dev/docs/ai-sdk-core/telemetry records inputs and outputs by default once telemetry is on, and the OpenAI Agents SDK sends traces to OpenAI https://openai.github.io/openai-agents-python/tracing/ by default. Set what gets recorded and where it goes on purpose, especially if users' data passes through. Ways to Deploy The first decision is whether you're deploying an agent you already built, or adopting a platform that brings its own agent loop. Self-host a framework agent Run your agent on a framework with a durable layer under it: - LangGraph with the Postgres checkpointer behind your own API and worker. LangChain's own server needs an Enterprise plan to self-host https://docs.langchain.com/langsmith/deploy-to-self-hosted-overview . - OpenAI Agents SDK inside Temporal https://docs.temporal.io/develop/python/integrations/openai-agents , where model calls become retried, recorded steps. - Vercel AI SDK with WorkflowAgent https://ai-sdk.dev/docs/agents/workflow-agent on the Postgres backend https://workflow-sdk.dev/worlds/postgres outside Vercel. We crash-tested this setup in How to Run Vercel AI SDK Agents in Production https://www.omnara.com/guides/vercel-ai-sdk-agents-production . - Mastra with durable agents https://mastra.ai/docs/harness/durable-agents for runs that have to survive restarts. They're in beta, so pin the version and test recovery before upgrading. Some of these include authentication or sandbox integrations, but you still configure them and check the access rules and spending limits for your app. Self-host a harness Run a harness like the Claude Agent SDK or Codex on your own machines. Anthropic's hosting guide https://code.claude.com/docs/en/agent-sdk/hosting is clear that this isn't like hosting a normal API. Each active session runs its own CLI process, and its transcript stays in local files unless you add a session store. You can give each session its own container or run several in one, depending on what those processes can reach. Everything from the crash test applies here. If you use Pi, Pi Durable https://www.omnara.com/guides/deploy-pi-durable-agents saves its sessions as they happen, on Cloudflare, Vercel, or your own servers. Host your agent on a platform If you already build on LangChain, Google Cloud, or AWS, LangSmith Deployment https://docs.langchain.com/langsmith/deployment , Google's Agent Runtime https://docs.cloud.google.com/gemini-enterprise-agent-platform/build/runtime/quickstart-adk , and AWS AgentCore can host an agent you built with a framework. They run it and scale it, while the agent's logic stays yours. Use a managed agent platform Claude Managed Agents, OpenAI's Agents API, and Omnara bring their own agent loop, session log, sandboxes, and approvals behind an API. You configure the agent instead of writing the loop. Omnara's core platform is open source, so you can use it hosted or self-host it https://docs.omnara.com/self-hosting/deployment , which also means owning upgrades, backups, and recovery. I compared these platforms in more detail in Claude Managed Agents alternatives https://www.omnara.com/guides/claude-managed-agents-alternatives . Even with a platform, check who maps your users to their credentials, what happens when a webhook is missed, and where the transcripts are stored. Cloud Agent APIs Compared https://www.omnara.com/guides/cloud-agent-apis goes through how each API handles users, credentials, and webhooks. Claude Managed Agents and OpenAI's Agents API are the quick start for a prototype or an internal tool if you only use Claude or only OpenAI models. Both run on an account you already have, and on their hosted sandboxes, the agent sees only a placeholder for each user's credentials. In exchange, you're limited to one lab's models, the agent loop and transcripts stay on that lab's servers, and the credential placeholders don't work with self-hosted sandboxes yet. For agents going to production, Omnara holds up better. It already handles the restart and approval problems above: if a worker dies, another continues from the last saved step, and an approval waits for a person as long as it takes. It works with any model on your own keys, and you can self-host the whole platform, with the session log in your own Postgres. You can also change a running agent's model, tools, or instructions through the API without a redeploy. It runs its own agent loop, so it isn't a way to run Claude Code or Codex. A Setup to Start From If you build it yourself, this is the architecture I'd start with. Ramp https://builders.ramp.com/post/why-we-built-our-background-agent and Stripe https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents describe similar setups. 1. An API that authenticates users, starts runs, and streams progress, with a way to reconnect to a stream. 2. A durable run layer, either a workflow engine or a job queue in your database, with step and spend limits per run. 3. A session log outside the worker, holding events, checkpoints, and pending approvals. 4. A sandbox per session for anything the agent executes, with limited network access. 5. Credentials kept out of the sandbox, injected at a proxy or in your tool code. 6. Tracing from the first day, with the user and version on every run. For a small team, deploy an authenticated API and one worker, with Postgres as both the session log and the job queue. Save each job before you return its run ID, and store checkpoints outside the worker. Add a hosted sandbox provider if the agent runs code. Before launch, test a worker crash, a stream reconnect, a duplicate tool call, and recovery after a deploy. Keep a small set of real tasks with checks you wrote yourself https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents , and run them before changing the model, prompt, tools, or harness. FAQ How do I make an AI agent survive restarts? Store the agent's state outside the process and resume from it. You can put a durable execution engine like Temporal around your own loop, save checkpoints in your database with something like LangGraph's Postgres checkpointer, or use a managed agent platform like Claude Managed Agents or Omnara that keeps the session log for you. Whichever you choose, kill it mid-task before launch and check what runs twice. How do I deploy a LangGraph agent without LangSmith? You can deploy the open-source LangGraph library on its own. Run it behind your own API and worker with the Postgres checkpointer, and check that the caller owns a thread before resuming it. Paused approvals resume from the saved checkpoint. Add a job that deletes old checkpoints. LangChain's ready-made server, LangSmith Deployment, needs an Enterprise plan to self-host. How do I run the Claude Agent SDK in production? Keep each session's transcript and config on a volume or in a session store, put the sessions in containers with limited network access, and keep credentials out of them. Set your own turn, retry, and spend limits. Use the defer decision if approvals can take longer than the process stays up. How do AI agents wait for human approval? The framework saves the paused run, including the exact tool call waiting for approval, and resumes it when someone decides. The run can resume in a different process days later, as long as the saved state, the pending call, and your code version are all still there. Managed agent platforms like Omnara do this for you: the agent pauses on the tool call, and someone approves or denies it later through the API or Omnara's dashboard. How do I stop an agent from running up a huge bill? Set limits on turns, retries, and time for every run, and a budget per user if users can start agents. Use provider spend caps as a backstop, since they lag. Keep API keys on the server and restricted to the APIs they need. What are my options for a self-hosted AI agent platform? Omnara is open source under Apache 2.0 and self-hosts as a whole platform, with its own agent loop, approvals, and an API, on any model. When you self-host it, agent history lives in your own Postgres, with files and memory in storage you run. If you have a LangGraph agent and want LangChain's server for it, LangSmith's self-hosted deployment needs an Enterprise license. For each, check the production setup, the upgrade process, backups, and which APIs it supports before choosing. Self-Hosted Managed Agents https://www.omnara.com/guides/self-hosted-managed-agents covers more options, including OpenHands and Coder, and what Claude, OpenAI, and AWS let you run on your own machines.