---
schema_version: "1"
id: 1b2cbe8757b4891e6426560289a54fc7f65ebc872840883d18d351e795073864
title: App Design That Maximizes Process Performance
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/mule-runtime/4.4/tuning-app-design.md
canonical_url: https://docs.mulesoft.com/mule-runtime/4.4/tuning-app-design
source_site: docs.mulesoft.com
content_type: documentation
content_hash: 687197fcd91b3313d4a655eeab5d98ca7189265b3b030c4a255a47442d371a79
description: MuleSoft Documentation Site
release: "4.4"
latest: false
---
---
product: Mule Runtime
version: 4.4
---

# App Design That Maximizes Process Performance

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

As you design your applications, consider the following best practices for enhancing processing
performance. These practices include guidelines on choosing a Mule runtime engine (Mule) version,
avoiding certain app design issues, and specific settings for using Mule components and connectors.

## Mule Runtime Engine Version

Before you start tuning your application, review the following Mule version recommendations:

- Use the latest Mule version to create and run the application.

- Update your application dependencies to the latest version so you take advantage of the recent
  performance improvements and bug fixes.

- Update to the latest version of the Mule patch whenever possible.

- When developing and testing an application, use the same Mule version as used to deploy that
  application in your environments.

## Tips to Design for Enhanced Processing Performance

As you design your apps, consider the following recommendations to increase performance:

- Instead of repeatedly using the Java module to reuse code such as Java libraries, create an SDK
  module with operations that wrap Java invocations.

- Use DataWeave to transform or enrich data, and create payloads instead of custom scripting code
  such as Java and Groovy.

- Avoid sequences of `set-variable/set-payload` components such as in the following example:

  ```xml
  <set-variable value='"Hello"' doc:name="Set Variable" variableName="hello"/>
  <set-variable value='"world!"' doc:name="Set Variable" variableName="world"/>
  ```

  Instead, combine them into a single `ee:transform` operation that avoids generating a new event
  for each component:

  ```xml
  <ee:transform doc:name="Transform Message" >
  	<ee:variables >
  		<ee:set-variable variableName="hello" ><![CDATA[%dw 2.0
              output application/json
              ---
             "Hello"]]></ee:set-variable>

             <ee:set-variable variableName="world" ><![CDATA[%dw 2.0
              output application/json
              ---
             "world"]]></ee:set-variable>
  	</ee:variables>
  </ee:transform>
  ```

- Avoid using store transient values in `set-variable`, as shown in the following example:

  ```xml
  <flow name="FileComponentWithsetVariableFlow" doc:id="daa9e38a-bb8c-4c87-a4c0-ba2dd90316b2" >
         <set-variable value="#['file_path/' ++ attributes.queryParams['filename']]" doc:name="Set Variable" doc:id="cf876447-12a6-4267-9b26-5e849153142c" variableName="fileName"/>
         <file:read doc:name="Read" doc:id="e4ad1ad4-0edb-45c9-ab43-d7f07effa277" path="#[vars.fileName]"/>
  </flow>
  ```

  Instead, move these values into components that need them:

  ```xml
  <flow name="FileComponentWithoutsetVariableFlow" doc:id="0d44d155-cabe-4a79-99e4-81de22743edb" >
        <file:read doc:name="Read" doc:id="09dfb229-67fd-4508-862f-489c123527ba" path="#['file_path/' ++ attributes.queryParams['filename']]"/>
  </flow>
  ```

- Avoid creating property resolvers, which require using DataWeave for every event and thereby
  increase process overhead:

  ```xml
  <flow-ref name="#[p(someProp) default p(otherProp)]"/>
  ```

  Instead, place DataWeave logic in a property placeholder and use a static flow reference:

  ```xml
  <flow-ref name="${propertyContainer.propertyName}"/>
  ```

## Components and Connectors Best Practices

When designing your apps using Mule components and connectors, consider the following
recommendations to enhance the performance.

### APIkit

To improve performance, disable APIkit validations. If payload validations are required, APIkit
validates input requests against API specification.

### DataWeave

When using DataWeave, consider the following ways to improve performance:

- If payloads are large, include `indent=false` to improve client parsing and reduce response size.

- Define `content-type` to avoid verbose messages in the log.

- Use inline DataWeave scripts during development and then move them to an external file to have a
  clean XML and reusable scripts.

- Do not log complex DataWeave expressions with every request.

- Avoid patterns of iterating over a collection and then transforming each individual item:

  ```xml
  <foreach>
  	<ee:transform >
  		<ee:message >
  			<ee:set-payload ><![CDATA[%dw 2.0
  output application/json
  ---
  payload mapObject (value, key) -> {
  	(upper(key)): value
  }
  			]]></ee:set-payload>
  		</ee:message>
  	</ee:transform>
  	...
  </foreach>
  ```

  Instead, transform the entire collection and iterate later:

  ```xml
  <ee:transform>
  	<ee:message >
  		<ee:set-payload ><![CDATA[%dw 2.0
  output application/json
  ---
  payload map (item, index) -> {
  	book: item mapObject (value, key) -> {
  		(upper(key)): value
  	}
  }
  		]]></ee:set-payload>
  	</ee:message>
  </ee:transform>
  <foreach>
  	...
  </foreach>
  ```

### Validator

Use Validator Module instead of throwing exceptions with Groovy Scripts.

### HTTP and HTTPS

For HTTP and HTTPS, consider the following recommendations:

- Use the authentication mechanisms provided by Anypoint Connector for HTTP (HTTP Connector) instead
  using manual authentications such as manually generating the Basic auth header with a DataWeave
  expression.

- If HTTPS is required, use the HTTPS Listener with a TLS Context reference, configuring the
  keystore with key-pair values generated with Keytool.  
  You can avoid HTTPS configuration if the SSL can also be terminated at the Load Balancer level
  when using a dedicated load balancer in CloudHub or if there is an on-premises load balancer for
  hybrid scenarios:

  ```xml
  <tls:context name="TLS_Context" doc:name="TLS Context">
        <tls:key-store type="jks" path="company-keystore.jks" alias="${jks.alias}" keyPassword="${jks.key.password}" password="${jks.password}"/>
  </tls:context>
  ```

### Database

Use parameterized queries. If you must use dynamic queries, remember to validate inputs first. Using
dynamic queries could cause SQL-Injection vulnerability.

### File Connector

Instead of using a transform component for the transformation in the write operation, use a
DataWeave expression. This avoids message payload changes that occur after the write operation, as
shown in the following example:

```xml
<file:write path="output.csv">
 <file:content>#[%dw 2.0
                 output application/csv
                 ---
                 payload.customers.email
               ]
 </file:content>
</file:write>
```

Use the recursive parameter to list files and folders within subfolders:

```xml
<file:list config-ref="File_Config" directoryPath="relativePath" recursive="true" />
```

### Web Service Consumer Connector

To import WSDLs including all references (XSDs) in your project, use Anypoint Connector for Web
Service Consumer (Web Service Consumer Connector) and point the configuration to the local WSDL.

### AMQP Connector

Because the server constrains the performance and configuration of Anypoint Connector for AMQP (AMQP
Connector), when you investigate performance issues, explore the server-side configuration to
determine if consume or publish parameters have an impact on performance.

#### Consume Parameters

Review consume parameters that can have an impact on performance.

##### Number of Consumers

Setting the number of consumers for an AMQP configuration and the Listener source determines how
many consumers are spawned by the source and receive AMQP messages concurrently, as each consumer
creates and uses a different channel.  
Message throughput depends on the number of consumers, becoming greater as the number of consumers
increases. However, throughput is also affected by the performance characteristics of the flow.

##### ACK Mode Parameter

ACK mode determines the acknowledgment mode to use when consuming from the AMQP broker. You set
acknowledgment mode (ACK) at the configuration level (using the **Consumer** tab), but Listener and
consume operations can override this mode.  
There are three acknowledgment modes:

- `AUTO`  
  Use Automatic to acknowledge a received message automatically only if the flow execution finishes
  successfully.

- `MANUAL`  
  Use Manual if you want the app logic to control message acknowledgment.

- `IMMEDIATE`  
  Use Immediate when you want to acknowledge messages as your app consumes them, before processing
  them.

Note that if a transaction is opened in the channel, the ACK mode parameter is overruled and the
commit automatically process the message acknowledgment and the rollback automatically process the
recovery.

##### Quality of Service Tab

You set QoS parameters at the configuration level (using the **Quality of Service** tab), with 0
representing an unlimited value. A Listener operation can override this setting.  
These are the parameters:

- Prefetch Size  
  Defines a prefetch size window. The broker sends as many messages as possible without exceeding
  the prefetch size window in octets (bytes).

- Prefetch Count  
  Specifies a global prefetch window in terms of the maximum number of whole messages. You can use
  this parameter in combination with the `prefetch-size` parameter to send a message in advance only
  it both prefetch windows sizes allow it.

##### ACK Mode and Prefetch

The acknowledgment mode and QoS prefetch value that you choose have a significant effect on consumer
throughput. In general, increasing the prefetch value and choosing Immediate acknowledgment mode
yield the best possible rate of delivery. However, with both choices the number of delivered but not
yet processed messages also increases, thereby increasing consumer RAM consumption

Automatic acknowledgement mode or Manual acknowledgment mode with unlimited prefetch should be used
with care. Consumption of a lot of messages without acknowledgement leads to increased memory
consumption on the broker node. Finding a suitable prefetch value is a matter of trial and error and
can vary from workload to workload.

#### Publish Parameters

Set the following parameters at the configuration level, using the **Publisher** tab. Publish and
Publish-consume operations can override these parameters. Depending on your use case, you might need
to enable only one of these parameters.

##### Delivery Mode Parameter

Setting this parameter determines the delivery mode used to publish to the AMQP broker. Possible
parameters values are:

- `PERSISTENT`  
  Delivered messages to durable queues are logged to disk on the broker.

- `TRANSIENT`  
  Delivered messages are not logged.

The broker is responsible for the implementation of the recordable storage mechanism for persistent
messages. The impact of this feature on performance depends on the AMQP server.

##### Request Broker Confirm Parameter

If the broker provides no confirmation, setting this parameter determines whether the operation
fails. Using this parameter adds one extra communication between the broker and the client per
message published.

## See Also

- [Configure Property Placeholders](https://docs.mulesoft.com/mule-runtime/4.4/mule-app-properties-to-configure)

- [Getting Started with the Mule SDK for Java](https://docs.mulesoft.com/mule-sdk/latest/getting-started)

- [SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection)

- [Finding bottlenecks with RabbitMQ 3.3](https://www.rabbitmq.com/blog/2014/04/14/finding-bottlenecks-with-rabbitmq-3-3/)
