LLM Chat Input Causing Multiple Full Page Reruns - How to Prevent?

I’m building a stock analysis dashboard with a chat feature using st.chat_input(). When a user submits a message, the entire page reruns twice, which is causing performance issues because my dashboard has:

  • Multiple API calls (yfinance, Reddit API, Groq AI API)

  • Heavy data processing (technical indicators, sentiment analysis)

  • Multiple interactive charts and visualizations

This makes the chat experience very slow and inefficient, as all the stock data gets refetched and recalculated with every chat message.

Here’s my chat section code structure:
with chat_col:
st.markdown(“Chat”, unsafe_allow_html=True)

# Initialize chat history
if f'chat_history_{ticker}' not in st.session_state:
    st.session_state[f'chat_history_{ticker}'] = []

# Display messages
messages_container = st.container(height=395)
with messages_container:
    for message in st.session_state[f'chat_history_{ticker}']:
        with st.chat_message(message['role'], avatar="👤" if message['role'] == 'user' else "🤖"):
            st.markdown(message['content'])

# Chat input
user_question = st.chat_input("Ask a question about this stock...")

if user_question:
    # Add user message
    st.session_state[f'chat_history_{ticker}'].append({
        'role': 'user',
        'content': user_question
    })
    
    # Get AI response (API call to Groq)
    with st.spinner("Thinking..."):
        assistant_response = get_chat_response(context, user_question, st.session_state[f'chat_history_{ticker}'])
        
        # Add assistant message
        st.session_state[f'chat_history_{ticker}'].append({
            'role': 'assistant',
            'content': assistant_response
        })
    
    # Force rerun to display new messages
    st.rerun()

What I’ve Observed:

  1. User enters a chat message

  2. First rerun: Page updates, spinner shows “Thinking…”

  3. Second rerun: After st.rerun() is called, entire page reloads again

  4. All stock data, charts, and visualizations are recalculated unnecessarily

I want the chat section to update independently without triggering a full page rerun and without refetching all the stock market data.

use @st.cache_data for all stock data so it will not be refetched .

I think you can wrap it in a function with the @st.fragment decorator. That will isolate its execution from the rest of the app so it does not trigger a full app rerun.

@st.fragment
def llm_interaction():
Your code here.