erlang:start_timer/3 vs timer:send_after/3

What should I prefer:

erlang:start_timer(Ttl, self(), time_to_die)


timer:send_after(Ttl, self(), {timeout, time_to_die})

if my use case is to send a single atom message to a gen_server? I expect to have hundreds of thousands of gen_servers and each one of those will need to have an associated TTL timer event.


  • The Common Caveats section of the Erlang Efficiency Guide says:

    Creating timers using erlang:send_after/3 and erlang:start_timer/3, is more efficient than using the timers provided by the timer module in STDLIB.

    The timer module uses a separate process to manage the timers. Before OTP 25, this management overhead was substantial and increasing with the number of timers, especially when they were short-lived, so the timer server process could easily become overloaded and unresponsive. In OTP 25, the timer module was improved by removing most of the management overhead and the resulting performance penalty. Still, the timer server remains a single process, and it may at some point become a bottleneck of an application.

    The functions in the timer module that do not manage timers (such as timer:tc/3 or timer:sleep/1), do not call the timer-server process and are therefore harmless.