Skip to content

Workers and parallelism

Mogens Heller Grabe edited this page May 16, 2019 · 7 revisions
Clone this wiki locally

Since everything in Rebus is async, one single worker can perform a ridiculous amount of work in parallel if that work can be awaited.

Therefore – to avoid doing too much work – the "max parallelism" concept is present, which puts a global max cap on how many messages to process in parallel.

You can configure those options by going

    .Options(o => {

Which values to use for the settings depends on the type of work you want to perform. The following are some reasonable settings that maybe can give you some food for thought:

  • Work is predominantly asynchronous – use a few worker threads and fairly high parallelism, e.g. o.SetNumberOfWorkers(2); o.SetMaxParallelism(20);
  • Work is fast and synchronous – use a few worker threads and a matching parallelism, e.g. o.SetNumberOfWorkers(5); o.SetMaxParallelism(5); (although setting the parallelism higher will not affect anything in this case)
  • Work is slow and synchronous – use more worker threads and a matching parallelism, e.g. o.SetNumberOfWorkers(15); o.SetMaxParallelism(15); (again: setting the parallelism higher will not affect anything in this case)
  • Work must be performed in a synchronous manner, effectively serializing access to some particular resource (or to make an endpoint easier to debug during development) – use one single worker thread and a matching parallelism: o.SetNumberOfWorkers(1); o.SetMaxParallelism(1);

Since the parallelism setting puts an absolute upper cap on how many messages can be handled in parallel, it does not make sense to set the parallelism lower than the number of threads. It does not create any problems on the other hand though, it is just a waste of resources.


Rebus will default to 1 worker thread and a max parallelism of 5.

Worker threads

Rebus will actually spawn the number of worker threads as dedicated threads. The threads will be used for polling the transport for messages.

Depending on whether the transport is asynchronous or not, the continuation after having received a message will either execute on the worker thread or on the thread pool.