Timer Stores | Rasa Documentation
Timer Stores in Rasa
Rasa maintains one active timer per conversation to track inactivity. To ensure timers persist across server restarts and work in multi-pod deployments, Rasa uses a timer store. Rasa provides built-in timer store implementations to suit different deployment scenarios and requirements.
InMemoryTimerStore (default)
Description
InMemoryTimerStoreis the default timer store and it stores timers in memory. Suitable for development and testing as timers are lost on server restart.Configuration
To use theInMemoryTimerStoreno configuration is needed.
RedisTimerStore
Description
RedisTimerStore maintains conversation timers using Redis as a persistence layer. This is the recommended option for production deployments as it supports persistence across server restarts and works in multi-pod environments.
With Redis:
- Timers survive server restarts.
- All pods in a horizontally-scaled deployment share the same timer state.
- Timers that expired while the server was down are recovered and processed on startup.
Configuration
To set up the timer store with Redis the following steps are required:
- Add required configuration to your
endpoints.yml
timer_store:
type: "redis"
host: <host of the redis instance, e.g. localhost>
port: <port of your redis instance, usually 6379>
username: <username used for authentication>
password: <password used for authentication>
db: <number of your database within redis, e.g. 0. Not used in cluster mode>
key_prefix: <alphanumeric value to prepend to timer store keys>
socket_timeout: <time in seconds after which redis commands time out, default 10>
poll_interval: <interval in seconds between polling for expired timers, default 1.0>
# transit encryption parameters
use_ssl: <whether or not the communication is encrypted, default false>
ssl_keyfile: <path to an ssl private key, only used if use_ssl is true>
ssl_certfile: <path to an ssl certificate, only used if use_ssl is true>
ssl_ca_certs: <path to a file of concatenated CA certificates in PEM format, only used if use_ssl is true>
# high availability parameters
deployment_mode: <standard, cluster, or sentinel>
endpoints: <list of redis cluster/sentinel node addresses in the format host:port>
sentinel_service: <name of the redis sentinel service, only used in sentinel mode>
Fallback Timer Store
If Redis is configured but becomes unavailable, Rasa automatically falls back to the InMemoryTimerStore. Sessions continue to be managed without crashing, and a warning is logged when the fallback is activated. When Redis recovers, Rasa resumes using it and logs that the fallback has been deactivated.
Custom Timer Stores
If you need a timer store which is not available out of the box, you can implement your own. To write a custom timer store, extend SessionTimerStore from rasa.core.timer_stores.timer_store. Your constructor must accept an endpoint_config parameter:
from rasa.core.timer_stores.timer_store import SessionTimerStore
from rasa.utils.endpoints import EndpointConfig
class MyCustomTimerStore(SessionTimerStore):
def __init__(self, endpoint_config: EndpointConfig = None):
...
Your custom timer store class must implement all of the following methods:
close: releases any resources (connections, file handles, etc.) held by the store.
Must respect the following signature:
def close(self) -> None:
"""Close and clean up the timer store."""
store_timer: persists a timer entry for a conversation. Must respect the following signature:
async def store_timer(
self,
sender_id: str,
session_id: Optional[str],
scheduled_time: float,
metadata: Optional[Dict[str, Any]] = None,
) -> None:
"""Store a session timer for the given conversation.
Args:
sender_id: The conversation ID.
session_id: The current session ID, used to validate the timer
has not been superseded when it fires.
scheduled_time: Unix timestamp (seconds) when the timer should fire.
metadata: Optional key-value data to attach to the timer.
"""
delete_timer: removes a timer entry. Must respect the following signature:
async def delete_timer(
self,
sender_id: str,
only_if_scheduled_time: Optional[float] = None,
) -> bool:
"""Delete the timer for the given conversation.
Args:
sender_id: The conversation ID.
only_if_scheduled_time: If set, delete only when the stored timer's
scheduled_time equals this value (for atomic multi-pod claiming).
If None, delete unconditionally.
Returns:
True if a timer was found and deleted, False otherwise.
"""
get_timer: retrieves the current timer for a conversation, or None if none exists.
Must respect the following signature:
async def get_timer(self, sender_id: str) -> Optional[SessionTimer]:
"""Get the timer for the given conversation.
Args:
sender_id: The conversation ID.
Returns:
The SessionTimer if one exists for this conversation, None otherwise.
"""
get_expired_timers: returns all timers whosescheduled_timeis at or beforecutoff_time.
Must respect the following signature:
async def get_expired_timers(
self, cutoff_time: Optional[float] = None
) -> List[SessionTimer]:
"""Return all timers that have expired.
Args:
cutoff_time: Unix timestamp threshold. Timers with
scheduled_time <= cutoff_time are returned.
Defaults to the current time if None.
Returns:
List of expired SessionTimer objects. Must not delete them.
"""
The base class provides two helpers that can be used by the get_expired_timers method:
_check_time_for_expired(cutoff_time): returnscutoff_timeif set, otherwisetime.time()._filter_expired(timers, check_time): filters an iterable ofSessionTimerobjects to those withscheduled_time <= check_time.
Another built-in helper method available for use in your custom timer store is:
SessionTimer.create_timer(sender_id, session_id, scheduled_time, metadata): constructs aSessionTimerfrom the arguments passed tostore_timer.
Configuration
Put the module path to your custom timer store class in endpoints.yml under the timer_store key. Any additional fields are passed through as part of the EndpointConfig and are accessible via endpoint_config.kwargs:
timer_store:
type: path.to.your.module.MyCustomTimerStore
a_parameter: a value
another_parameter: another value