GeekHub Learn
Module
Lesson 6.44 of 7 in this module2 min read Module 6: Building Your First AI Chat App

Session state and conversation memory

Real apps need memory that survives reloads, multiple users, and budget caps. Streamlit gives you the first tools to learn this properly.

A diary on your nightstand vs a journal app that syncs. Both are memory. One is fragile, one is durable.

st.session_state lives in memory per browser tab. Refresh = gone. For real persistence:

  1. Save chat history to a file (json) keyed by user.
  2. Save to a database (Supabase, SQLite, Firebase).
  3. Use Streamlit's st.experimental_user for SSO-style auth.

Memory strategies from Module 3.4 (full, window, summary, retrieval) all apply here.

Add a 10-message rolling window:

MAX_HISTORY = 20  # 10 user + 10 assistant
if len(st.session_state.messages) > MAX_HISTORY + 1:  # +1 for system
    st.session_state.messages = (
        [st.session_state.messages[0]]  # keep system
        + st.session_state.messages[-MAX_HISTORY:]
    )

Add reset and export:

col1, col2 = st.sidebar.columns(2)
if col1.button("Clear"):
    st.session_state.messages = []
    st.rerun()
if col2.download_button("Export", data=str(st.session_state.messages), file_name="chat.json"):
    pass

Visualize it

A diagram with three layers: browser session (tab) -> server memory (Streamlit session) -> persistent storage (file or DB).

Try it now

Have a 30-turn conversation. Note when older messages get truncated. Add a banner that warns when truncation happens.

Hands-on lab

Add rolling window, reset, and export to your app.

Try it now

How would you scope memory per user when multiple people use the same deployed app?

Common mistakes

  • Sharing state across users (Streamlit isolates per session but logged-in apps need explicit user keys)
  • Letting memory grow forever and crashing on context limit
  • Persisting raw chat including sensitive info without encryption

Debugging tip

If users see each other's chats, you forgot to scope by user id. Always key memory by an explicit user identifier in any multi-user deployment.

Challenge

Save and load chat history to/from a local JSON file. On refresh, the conversation resumes.

Where this shows up

  • Tutor apps with returning students
  • Customer support apps with ticket-level memory
  • Personal assistants with cross-session memory

From the field

The 2026 winning pattern: store conversation in Supabase or Firebase, key by user_id, and load on session start. This single change moves your app from "demo" to "product".

Recap

Session state is the start. Persistent storage is the finish. Scope by user, cap memory size, save what matters.


Quick recall

3 prompts · think before you flip

Prompt 1 of 3

What is the scope of `st.session_state`?

Quiz time

1 question · tap an answer to check it

  1. 1. To persist chat across refreshes you need

Finished lesson 6.4?

Mark complete to update your module progress and unlock the streak.

Loading