Missing timeout configuration for Reflex server-side component state
0 reputation · 13 Jul 2021, 07:49 UTC
0 reputation · 13 Jul 2021, 07:49 UTC
Goal: Enable automatic expiration of idle Reflex component state stored in server‑side sessions to bound memory usage during long‑lived WebSocket connections.
Constraint: Reflex does not expose a built‑in configuration option for state timeout; implementing expiration requires custom session‑store middleware, which may interfere with the framework’s internal reactivity guarantees and hot‑reload synchronization.
Uncertainty: It is unclear whether a timeout can be added through existing configuration hooks without breaking state consistency, or what safe limits and cleanup strategies are recommended.
Questions:
34775 reputation · 13 Jul 2021, 15:27 UTC
No — as of the Reflex 0.x series (formerly Pynecone), there is no supported configuration option such as a state-idle-timeout in rxconfig.py or on rx.App. State lives in the backend keyed by session token, and the framework retains it while the WebSocket connection is open. Expiration is something you add yourself, and the only safe place to do it is at connection boundaries, not mid-session.
Reflex's reactivity loop assumes the server-side state object for a connected session always exists. If a cleanup job deletes a session's state while its WebSocket is still open, the next frontend event arrives referencing state the server no longer has. Depending on version and store, that surfaces as a fresh default state (silently discarding user data) or an exception in the event handler. Neither is a graceful timeout — it is a consistency violation. This is the likely explanation for the interference you observed with custom middleware; treat it as expected behavior, not a bug you can configure around.
The reliable approach is to expire only disconnected sessions:
on_connect/on_disconnect style hook or middleware that observes the WebSocket close event).htop or a Prometheus process exporter that memory drops only after disconnects.Exact hook names and the pluggable state-store API have changed across Reflex releases, so verify against the changelog for your installed version (pip show reflex) before relying on any specific middleware signature. The one detail that would change this recommendation: whether your deployment is single-process or multi-worker — multi-worker setups effectively require the external-store-with-TTL route, since in-memory state is not shared.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.