Demystifying Dispatchers in Akka

Reading Time: 2 minutes

As the name suggests ‘dispatch‘ decides when the actor should dispatch a message and when it does not have to. In the situation in which you think that your actor system must get faster but it’s not working as per expectation then dispatchers are the first place, you should look at.

Props[SomeActor] withDispatcher("my-dispatcher") 
// within the brackets you can give the name of your dispatcher

It’s up to the Dispatchers to decide when to allow the actor to process a message. Dispatchers are in control of the threads time that actor use and also in control of the threads themselves:

  • Dispatchers are Akka’s engine, they make actors “tick” by
    • implementing scala.concurrent.ExecutionContext and
    • registering an actor’s mailbox for execution
  • Dispatchers determine execution time and context and therefore provide the physical capabilities for scaling up. They provide the threads that are to be run to the CPU in order to do the process.
  • Each actor system has a dispatcher used as a default for all actors, configured as Here .default-dispatcher is used when you don’t provide explicitly any dispatcher.
  • You can set an externally configured dispatcher for an actor.

Dispatchers provided by Akka

  • Dispatcher (default): It has a collection of a limited number of threads and actors share those threads time to time. Event-driven dispatcher, sharing threads from a thread pool for its actors.
  • PinnedDispatcher: When you have such an actor that you don’t want to compete with other actors. Dedicates a unique thread for each actor. But this is expensive and would result in an explosion.
  • CallingThreadDispatcher: Takes a multithreaded actor system and turns into a single-threaded actor system. For testing, runs invocation on the current thread only
  • To use your own dispatcher, provide a MessageDispatcherConfigurator it’s relatively complex and used for the highly specialized use cases:
akka {
 actor {
  default-dispatcher {
   fork-join-executor {
   throughput=5 //default

Provide a name of the dispatcher (in this case we are modifying the default dispatcher)

Then provide a executor (can also provide thread pool):

  • min number of minimum threads we will allow to run in parallel.
  • factor gives the actual number of threads multiplied by CPU. ex-> We have parallelism factor 2 here and a core of 4 then the total number of threads is 2 x 2= 4 threads in total.

Throughput gives how many messages a single actor could process before it has to yield the thread to another actor


  • The whole actor system should not be given in a single dispatcher.
  • Try to use default dispatchers in most of the cases instead of making your own dispatchers. If you have to use long-running blocking expressions in that case you could customize your dispatchers.