In the same tab I have:
- An input widget that takes a while to appear (specifically, a dataframe rows selection for a dataframe that needs quite some time to be generated).
- An unrelated heavy computation to run, the results of which should be displayed.
I want to run these unrelated parts concurrently.
The problem is when the user input changes (when the rows are selected) the script reruns and the heavy computation is restarted.
Is there a way to make it continue to compute between reruns?
Maybe store the event loop or the tasks in session_state?
Hey there, thanks for your thoughtful question! This is a classic challenge in Streamlit due to its top-to-bottom rerun model: every widget interaction (like selecting rows in a dataframe) triggers a full script rerun, which restarts any ongoing computations unless they’re cached or managed outside the main script thread.
Currently, Streamlit does not natively support persisting ongoing computations (like background tasks or event loops) across reruns. Each rerun starts with a clean slate, except for what you explicitly store in st.session_state or cache. However, you can work around this by offloading heavy computations to a background thread or process and storing only the results (or status) in st.session_state. This way, the computation continues independently, and your UI can poll for updates without restarting the task. You cannot persist an event loop or running task itself in session_state—only their results or references (like thread objects) can be stored, and even then, you must be careful to avoid thread-safety issues and ensure the thread outlives reruns safely. See the official multithreading guide and session state docs for patterns and caveats.
Would you like a step-by-step example of how to implement this pattern with code?
Sources: