---
schema_version: "1"
id: f5e0e22f5357865ba8e6a8bc446c5ae56111d565c5283305358c40bd2088db9f
title: Batch Job Performance Tuning
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/mule-runtime/4.11/tuning-batch-processing.md
canonical_url: https://docs.mulesoft.com/mule-runtime/4.11/tuning-batch-processing
source_site: docs.mulesoft.com
content_type: documentation
content_hash: d7e16a80d4b02a90a1f71e12d4730a4af2b3dde7cd306f2ddfe403569601ce0a
description: MuleSoft Documentation Site
release: "4.11"
latest: false
---
---
product: Mule Runtime
version: 4.11
---

# Batch Job Performance Tuning

> For the full documentation index, see: https://docs.mulesoft.com/llms.txt

Mule runtime engine (Mule) possesses the ability to process messages in batches. Within an
application, you can initiate a batch job which is a block of code that splits large messages into
individual records, performs actions upon each record, then reports on the results and potentially
pushes the processed output to other systems or queues.

Consider having 1 million records processed by a batch application with three steps. Several I/O
operations occur as Mule processes each record as it moves through the job’s phases. The disk
characteristics, along with the workload size, play a key role in the performance of the batch job,
primarily because during the input phase, an in-disk queue is created of the list of records to be
processed, which is constantly read and written by the flow, resulting in heavy I/O utilization.

Additionally, batch processing requires having enough memory available to process the threads in
parallel, which means moving the records from persistent storage into RAM in a fixed-size block. The
larger your records and their quantity, the more available memory you need for batch processing.

## Batch Block Size

By default, the batch block size is set to 100. It is a good balancing point between performance and
working memory requirements based on analysis across a set of representative batch use cases with
various record sizes. However, the optimal value for each application depends on its use case.  
You can configure this property for the batch job. If you believe that in your particular case,
custom size is best suited, make sure to run comparative tests with different values to find the
optimum size in your use case. The following example shows the batch block size:

```xml
<batch:job jobName="test-batch" blockSize="${batch.block.size}">
```

## Max Concurrency

The maximum number of threads used for processing within a Batch scope defaults to 2 times the
number of cores that the JVM detects. On fractional core deployments, such as CloudHub and Anypoint
Runtime Fabric, the JVM detects a _non-fractional_ number of cores. You can manually increase or
lower the automated concurrency setting. The Max Concurrency setting enables you to set an upper
limit on the number of threads to use for a batch job instance that, for example, has insufficient
records to warrant more threads.

The following example overrides the automated `maxConcurrency` default to a setting that is loaded
from a property:

```xml
<batch:job jobName="an-example-batch" maxConcurrency="${batch.block.maxConcurrency}">
```

## Batch Aggregators

One million round trips across a network impacts performance, whether on single or multiple threads.
Communication with SaaS systems can easily consume the quota of API calls. Instead of processing
records one by one, you can improve performance by using the Batch Aggregator scope to perform bulk
operations on arrays of records. The scope uses an Aggregator Size setting to limit the number of
records in each array.

When determining the number of records to process in an array of records, you must take into account
the maximum number of records permitted by operations on the system with which the communication
takes place. It is important to conduct performance testing on your Aggregator Size setting _and on
lower values_. Your logic must handle any number of records up to and including the value of your
setting because the number of records that the system receives can be lower than your specified
value. For example, if there are 120 records, and your Aggregator Size setting is 50, the last
submission is 20 records.

The following example shows a Batch Step scope with a Batch Aggregator scope that is set to a fixed
size of `50`:

```xml
<batch:step name="Batch_Step_PushToXYZ" >
  <batch:aggregator doc:name="Batch Aggregator" size="50">
     <!-- code for an array of 50 (or fewer) records -->
  </batch:aggregator>
</batch:step>
```

If the aggregator contains an operation that streams data, you can activate the scope’s Streaming
option (`streaming="true"`) instead of using an Aggregator Size setting (`size="50"`).

## Multiple Concurrent Instances of a Batch Job

Many use cases for Batch Job scopes process only one request (batch job instance) at a time, but
some cases simultaneously execute two or more batch job instances. To tune the thread pool sharing
in such cases, you can set one of these scheduling strategies, each of which is tracked separately
by its batch instance ID:

- `ORDERED_SEQUENTIAL`: Default scheduling strategy that limits the impact of concurrent instances
  by processing the instances in the order they are triggered. This strategy is useful if
  nonsequential processing of the same batch job can cause issues, such as data inconsistency, or
  when resource limitations are reached.

- `ROUND_ROBIN`: Scheduling strategy that shares the threads with batch job instances that are "in
  flight".

## See Also

- [Batch Processing](https://docs.mulesoft.com/mule-runtime/4.11/batch-processing-concept)
