Retry and Reprocess flow design with Anypoint MQ
In any MuleSoft project, when Anypoint MQ comes into the picture there is always a requirement of retry and reprocess mechanism. Based on my experience I have prepared this blog to show how easily we can design retry and reprocess mechanisms.
GitHub repository with the Mule project and the spring boot application can be found at the end of the post.
In any MuleSoft project, when Anypoint MQ comes into the picture there is always a requirement of retry and reprocess mechanism. Based on my experience I have prepared this blog to show how easily we can design retry and reprocess mechanisms.
Requirement
The main flow of the Mule app will subscribe to a queue and the payload has to be sent to the backend via an HTTP call. While sending the subscribed payload to the backend via HTTP. If the backed system is down (during sending the HTTP request), how are we going to define our flow to perform the retry and reprocess mechanism?
Step 1
Put the HTTP request inside an until-successful scope. Which is a default scope provided by MuleSoft for retrying any event. Define the below parameters in the scope:
- maxRetries: Number of retries the request will do to try to connect with the backend service.
- millisBetweenRetries: After the retry performs, how much time the application should hold for the next retry.
Code for backend call using until-successful:
<until-successful maxRetries="${api.retry.number_of_retry}" doc:name="Retry to connect" millisBetweenRetries="${api.retry.milliseconds_between_retry}">
<http:request method="POST" doc:name="API Request" config-ref="LOCAL_HTTP_Request_configuration" path="${api.path}" responseTimeout="${api.response_timeout}" target="backendResponse"/>
</until-successful>
Step 2
If we can’t connect to the backend even after using the until-successful scope (retry process), we have to introduce a reprocess mechanism. To enable the reprocess mechanism, we have to call a subflow (which will perform reprocess) from the “On Error Continue” of the main flow.
Important
We have to acknowledge the subscribed queue in both HAPPY or ERROR scenarios. If we don’t do that, the queue will hold the message and it may lead to a duplicate process.

Step 3
To introduce the reprocess mechanism we have to define two queues.
1. Dead letter queue
This queue will work as an intermediate queue. This means, after failing the retry process we will store the message in this queue for re-processing. While sending the message to DLQ, we are going to pass two values in MQ properties:
- reprocessCount: This value is going to be used as a counter of the reprocess call.
- qname: The main queue name from which our application is subscribing to the messages.
Apart from the above two MQ properties, we have to define a property in the properties file. Which will be the maximum re-process count.
- maxUserRegistrationReprocessAttempts: “3” - This means the reprocess will happen (Main Queue - DLQ) only three times.
2. Parking queue
This queue will be treated as the final destination of the processing message. This means if both mechanisms (retry and reprocess) fail, the message will be stored in this queue (which will reprocess again).
The reason for introducing the parking queue is 100% delivery/processing of each message (at any condition).
We can introduce an additional flow, which will reprocess the landed message from parking to the main queue. We can define this in many ways. One of the ways is: Once the parking queue is filled with a certain limit an email will trigger to the support team. After receiving the email, the support team can trigger an endpoint that will start pulling the messages from the parking queue and pushing them to the main queue (using parallel for each component).
How to test the POC
Deploy the Mule app in Anypoint Studio and the spring boot app in eclipse or CMD.
Define the main queue, dead letter queue, and parking queue according to your requirements and update the CI/CS of the Anypoint client app (by using the MQ portal).

Happy flow: After the successful deployment of both Mule and the backend application, send a message as shown below. The flow will execute without any error.

Error flow: To test the retry and reprocess flows, we have made the backend unavailable. So, we have to deploy only the Mule app (should not deploy the spring boot app) and send the message like above and observe the process in the log. After performing the retry and reprocess flows, the message will land in the parking queue as below.

Conclusion
This POC is just to give an idea about retry and reprocess design using Anypoint MQ. There will be a lot of scopes to enhance the POC and prepare as per your requirement.
Finally, I will be more than happy to receive your valuable feedback.
GitHub repository
Kindly find the complete Mule and backed (spring boot) application here.
Reader notes
Helpful comments preserved from the original post.
- Jefferson Sousa · May 25, 2022
Thank you for the content! I'd like to know why you use Remove Variables in this flow. I imagine to be because you want to help the Java Garbage Collection to clean objects in fliyng. But, it's a imagination. Could you help me with this doubt?
-
Reply to Jefferson Sousa
Alex Martinez · May 26, 2022Hi Jefferson! I'm not the author of this article, but yes indeed is to help the Garbage Collection and also to release memory. Maybe for small projects it's not a big deal to add them or not, but I've seen big projects where it is important to remove the variables manually
FAQs
Frequently asked questions about this post.
-
How do I retry an HTTP request to a backend in MuleSoft?
Put the HTTP request inside an
until-successfulscope, which is a default scope MuleSoft provides for retrying any event. You configure it withmaxRetries(the number of retries the request will make to connect to the backend) andmillisBetweenRetries(how long the application waits before the next retry). -
What's the difference between the retry mechanism and the reprocess mechanism?
The retry mechanism uses the
until-successfulscope to re-attempt the HTTP call to the backend a set number of times; if it still can't connect after those retries, the reprocess mechanism takes over by calling a subflow from the main flow's On Error Continue handler, which moves the message through queues so it can be processed again later. -
Why do I need to acknowledge the subscribed queue in both the happy and error scenarios?
You have to acknowledge the subscribed queue in both the HAPPY and ERROR scenarios because if you don't, the queue will hold the message and it may lead to a duplicate process.
-
What are the dead letter queue and the parking queue used for?
The dead letter queue works as an intermediate queue where a message is stored for re-processing after the retry process fails, passing two MQ properties:
reprocessCount(a counter for the reprocess call) andqname(the main queue name the application subscribes to), while a properties-file value likemaxUserRegistrationReprocessAttemptslimits how many times the reprocess happens. The parking queue is the final destination if both the retry and reprocess mechanisms fail, ensuring 100% delivery of each message; from there an additional flow can push the landed messages back to the main queue.