Limits of st.cache_data isolation in multi-user environments
0 reputation · 05 Jul 2021, 04:13 UTC
0 reputation · 05 Jul 2021, 04:13 UTC
@st.cache_data decorator to persist function results across script reruns. While this significantly improves performance for expensive computations, the framework operates a global cache shared across all active sessions on the server instance.
When multiple users interact with an application that uses similar parameters, the caching mechanism identifies matches based on the hashed input arguments. However, if the logic incorporates user-specific data or session-dependent variables, there is a risk of data leakage or incorrect state if the cache is not explicitly scoped to individual sessions.
There is currently a lack of native configuration to partition the cache by user ID or session token without manually including those identifiers in the function's arguments.
34775 reputation · 05 Jul 2021, 15:46 UTC
Developers can reliably ensure user-specific data isolation in @st.cache_data by explicitly including session identifiers as function parameters. This creates per-user cache partitions through hash-based key differentiation.
The @st.cache_data decorator maintains a global in-memory cache shared across all server sessions. Cache keys are computed from hashed input arguments with no native support for user-scoped partitioning. Thread-safety is handled internally, but concurrent access to identical keys returns the same cached result regardless of session context.
session_id or user_id as the first parameter of cached functionsst.session_state.session_id or pass through authentication contextIncluding unique session identifiers as cache keys creates per-user cache partitions, which:
st.cache_data.max_entries to prevent unbounded growthThe cache has no built-in TTL or per-session eviction. Stale data persists until manual cache clearing. In high-concurrency environments, consider:
max_entries limitssession_id values to the same cached functionst.cache_data.get_semaphore()._cache to inspect cache contentsst.runtime.exists() to measure performance impactThread Safety: While Streamlit handles concurrent cache access internally, race conditions can occur if session state changes during cache computation. Ensure cached functions are pure or handle state changes gracefully.
Cache Invalidation: The framework provides no mechanism to clear cache entries per-user. All invalidation requires st.cache_data.clear(), which affects all sessions.
@st.cache_data
def expensive_computation(session_id: str, param: int) -> dict:
# Session-specific computation
return result
# Usage
result = expensive_computation(st.session_state.session_id, user_input)
This analysis assumes Streamlit's cache implementation remains unchanged from documented behavior. The exact internal cache structure and eviction policies would require runtime verification in your specific Streamlit version.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.