ConversationInactive event is emitted automatically.
For each active conversation:
- A timer is scheduled when a session starts.
- The timer resets every time a user message is received.
- When the timer fires,
ConversationInactiveis emitted. - If
SessionEndedis received (via custom action or REST API), the timer is immediately cancelled.
Configuring the timeout
Setsession_expiration_time in session_config in domain.yml to control how long user inactivity is allowed before the timer fires:
start_session_after_expiry
In both cases (true or false), when the timer fires, the ConversationInactive event is emitted and the tracker is marked as inactive.
The difference is what happens when the next user message arrives.
true (default — existing behaviour):
When the next user message arrives after expiry:
- A session boundary is created (
SessionStartedis emitted,action_session_startruns). - A new
session_idis generated as part of the session boundary and stamped on all subsequent events.
false (new in 3.16):
When the next user message arrives after expiry:
- No session boundary is created (
SessionStartedis not emitted, andaction_session_startdoes not run). - A new
session_idis still generated on theUserUtteredevent and stamped on all subsequent events.
carry_over_slots_to_new_session has no effect when start_session_after_expiry is false.
No session boundary is created, so slots are preserved as-is.
Rasa will log a warning if both are set to false together.start_session_after_expiry to false to retain the conversation uninterrupted and avoid unnecessary session boundaries.
Timer store
Because Rasa maintains one active timer per conversation, those timers need somewhere to live — especially across restarts and in multi-pod deployments. Thetimer_store in endpoints.yml controls where they are stored. Read more about timer store options in the Timer Stores documentation.