Best Practice for Using Foundry Threads as Chat History + Session Resume

Anonymous
2026-06-22T19:48:33.7733333+00:00

Use Case: I'm building an app where users can have long-running conversations with agents. I need to:

  1. Resume chats across sessions
  2. Maintain durable chat history
  3. Use Foundry threads to invoke agents with prior conversation context

My Planned Architecture:

I'm planning to use a hybrid model:

  • Foundry threads for runtime agent invocation and automatic context management
  • App database (PostgreSQL) as the source of truth for:
    • Conversation metadata (user_id, conversation_id, created_at, agent_version)
      • Full message history (role, content, timestamps, sequence)
        • Thread ID mapping (conversation_id → thread_id)

Data Flow:

New chat:

  1. Create row in conversations table (conversation_id, user_id)
  2. Call Foundry: create_thread() → get thread_id
  3. Store thread_id in conversations table

Mid-chat message:

  1. Store user message in messages table immediately
  2. Call Foundry: messages.create(thread_id, user_message)
  3. Call Foundry: runs.create(thread_id, agent_id)
  4. Poll run to completion
  5. Fetch response from Foundry and store in messages table

Resume session:

  1. Query DB: SELECT * FROM conversations WHERE user_id = X
  2. User clicks conversation → load thread_id from DB
  3. Display chat history from messages table
  4. New user message → invoke agent on same thread_id
  5. Foundry automatically uses prior thread messages as context

Questions:

  1. Is this a standard/recommended pattern for Foundry agents?
  2. Are there any gotchas with long-running threads or version mismatches I should plan for?
  3. Should I store anything from traces/run metadata in my DB, or just message content?
  4. Is there a risk that threads expire or become inaccessible, and if so, what's the recommended fallback?

Thanks!Use Case:

I'm building an app where users can have long-running conversations with agents. I need to:

  1. Resume chats across sessions
  2. Maintain durable chat history
  3. Use Foundry threads to invoke agents with prior conversation context

My Planned Architecture:

I'm planning to use a hybrid model:

  • Foundry threads for runtime agent invocation and automatic context management
  • App database (Azure BLOB Storage account or CosmosDB) as the source of truth for:
    • Conversation metadata (user_id, conversation_id, created_at, agent_version)
    • Full message history (content, timestamps, sequence)
    • Conversation Thread ID to User mapping (conversation_id -> user_id)

Data Flow:

New chat:

  1. Create row in conversations table (conversation_id, user_id)
  2. Call Foundry: create_thread() → get thread_id
  3. Store thread_id in conversations table

Mid-chat message:

  1. Store user message in messages table immediately
  2. Call Foundry: messages.create(thread_id, user_message)
  3. Call Foundry: runs.create(thread_id, agent_id)
  4. Poll run to completion
  5. Fetch response from Foundry and store in messages table

Resume session:

  1. Query DB: SELECT * FROM conversations WHERE user_id = X
  2. User clicks conversation → load thread_id from DB
  3. Display chat history from messages table
  4. New user message → invoke agent on same thread_id
  5. Foundry automatically uses prior thread messages as context

Questions:

  1. Is this a standard/recommended pattern for Foundry agents?
  2. Are there any gotchas with long-running threads or version mismatches I should plan for?
  3. Should I store anything from traces/run metadata in my DB, or just message content?
  4. Is there a risk that threads expire or become inaccessible, and if so, what's the recommended fallback?

Thanks!

Foundry Agent Service
Foundry Agent Service

A fully managed platform in Microsoft Foundry for hosting, scaling, and securing AI agents built with any supported framework or model

0 comments No comments

Answer accepted by question author
Divyesh Govaerdhanan 11,805 Reputation points MVP Volunteer Moderator
2026-06-22T23:32:25.7766667+00:00

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_version per 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_id and 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!!

Was this answer helpful?

1 person found this answer helpful.

0 additional answers

Sort by: Newest

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.