A fully managed platform in Microsoft Foundry for hosting, scaling, and securing AI agents built with any supported framework or model
Hello Abanes, Cameron A,
Welcome to Microsoft Q&A,
Your hybrid pattern is correct, treating your own database as the source of truth and using Foundry purely for runtime context is the right design. One thing to note first: the Threads/Runs/Messages API in your code samples is part of the Assistants API, which is deprecated and retires August 26, 2026. Since you're building fresh, build directly on the new Conversations/Responses model instead. Your architecture barely changes, just the API surface:
| Your plan | Maps to |
|---|---|
create_thread() |
conversations.create() |
| -------- | -------- |
create_thread() |
conversations.create() |
messages.create(thread_id, ...) |
conversations.items.create(conversation_id, ...) |
runs.create(thread_id, agent_id) |
call the Responses API against that conversation |
thread_id stored in your DB |
store conversation_id instead, same pattern |
1. Is this standard/recommended? Yes. Keeping conversation metadata and full message history in your own store, using Foundry conversations purely to invoke the agent with context, is exactly what Microsoft's resiliency guidance recommends.
2. Gotchas to plan for:
- Conversations persist until you explicitly delete them, no silent expiry
- Large conversations add latency. For long-running chats, rotate to a new conversation periodically rather than letting one grow indefinitely
- If you update your agent's tools or instructions mid-conversation, the conversation doesn't pin itself to the agent version it started with, new responses use whatever the agent looks like at call time. Storing
agent_versionper message like you planned is the right mitigation - If you attach files for file search, the underlying vector store expires 7 days after last activity by default. Calls referencing that knowledge start failing once it expires, you'd need to recreate the vector store and reattach it
3. What to store from traces/run metadata: Message content plus a few IDs is enough:
-
response_idand status (full trace stays queryable from Foundry by that ID later) -
agent_version - Token usage if you're tracking cost Conversations store tool-call and tool-output items as part of the conversation itself, so you don't need to duplicate that into Postgres separately.
4. Conversation expiration/inaccessibility risk: Conversations don't auto-expire, but they can become unreachable in two scenarios: a destructive reset of the Agent Service capability host (a documented last-resort recovery action that permanently orphans all data), or a regional outage affecting the underlying Cosmos DB/AI Search dependencies in Standard setup. Since your DB already holds full message history, your fallback is simple: if a stored conversation_id comes back invalid, create a fresh conversation, replay the stored messages into it, and continue. You don't lose data either way since Postgres is your source of truth, not Foundry.
A migration tool is also available to convert classic agent code constructs (agent definitions, thread/message/run creation) to the new pattern automatically, worth using now before you've accumulated state on the old API.
Reference:
Migrate to the new agents developer experience,
Build with agents, conversations, and responses,
High availability and resiliency for Foundry Agent Service
Please Upvote and accept the answer if it helps!!