> For the complete documentation index, see [llms.txt](https://docs.getmesa.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.getmesa.com/best-practices/avoid-infinite-loops.md).

# Avoid Infinite Loops

If your workflow triggers an infinite loop, it could flood your message queue, slow down workflow processing, or worse, result in large overage charges.

Workflows with an Update trigger can be at risk of causing an infinite loop in a couple different situations:

## Bi-directional sync

Consider a scenario to copy orders and keep inventory levels in sync with two workflows:

* When a Shopify order is created, create an order in Salesforce
* When a Salesforce order is created, create an order in Shopify

When a Shopify order is placed, the first workflow will run which will create a Salesforce order. This will trigger the second workflow, which will in turn trigger the first workflow. Now you have a never-ending loop of new orders.

## Workflows affecting the same object

Consider this workflow that begins with a Product updated step and contains an Update product step:

<figure><img src="https://3425906282-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1H6u1HQc3Iew7ATmmiCi%2Fuploads%2FSAjszlGp1hfOJVXa0yrL%2Finfinite-loop-update-product.png?alt=media&amp;token=00b2e08d-5cca-4599-9211-a7d2206017ac" alt="Screenshot of a MESA workflow that begins with a Product updated trigger and contains an Update product step. Spotlight the Update product step."><figcaption><p>Uh oh, how do I make it stop?!</p></figcaption></figure>

When a Shopify product is updated, this workflow will be triggered and the same product will be updated. This will in turn trigger the workflow again, which could cause he product to be updated, and so on. MESA has special handling for duplicate messages which works in most cases, but not all, depending on the updates you are making.

## Suggested structure

To avoid infinite loops, we always recommend adding a unique identifier to the object that was updated and then filtering by that identifier in the second step of your workflow. In the above example, you would add a Shopify add tag step to the end of the workflow that adds a "AI Update" tag:

<figure><img src="https://3425906282-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1H6u1HQc3Iew7ATmmiCi%2Fuploads%2Fk0JpaP8t5U4s0Ky9yVwl%2Finfinite-options-ai-update.png?alt=media&amp;token=56f09539-e23f-4569-b982-3fb2f046fd04" alt="Screenshot of a MESA workflow with a Shopify Add Tag step at the end that adds an AI Update tag. Spotlight the Add Tag step."><figcaption><p>Now I know that MESA has updated the product!</p></figcaption></figure>

And then confirm that the product does not contain that tag in the second step of the workflow:

<figure><img src="https://3425906282-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1H6u1HQc3Iew7ATmmiCi%2Fuploads%2F5Kgp7093kQ2bpDP5lCei%2Finfinite-loop-filter.png?alt=media&amp;token=3afa95e4-88fd-4afb-8f4c-6306805660c9" alt="Screenshot of a MESA workflow Filter step confirming that the product does not contain the AI Update tag. Spotlight the Filter step condition."><figcaption></figcaption></figure>

The remedy for a bi-directional sync would be similar, but you would want to check that the tag does not exist in both workflows.

{% hint style="info" %}
This would result in your automation running twice every time the product is updated (once to make the update, and a second time to hit the filter), which should be accounted for when selecting a plan.
{% endhint %}

## Suggested structure using specific fields

If you're updating an object and don't need to read it, you can select **Only when specific fields change** to avoid infinite loops. For example, if you're updating tags but don't need to read them in the workflow, use the **Only when specific fields change** feature to include all the fields you're reading and exclude those you're not using, like tags. Doing so prevents the workflow from getting triggered when the only change is a tag modification.

In the example below, we have set a value for **Fields**. The workflow will only be triggered when the title, body html, or variants are updated. Because tags are not included in the Include Fields value, updates to the product tags will not trigger the workflow. This structure prevents the workflow from being executed twice.

<figure><img src="https://3425906282-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1H6u1HQc3Iew7ATmmiCi%2Fuploads%2FpPDqxW8lW3j4Fs5nzaKe%2Finfinite-loop-fields.png?alt=media&amp;token=54ce098e-ec91-4292-bac2-04f04cf9b4cd" alt="Screenshot of a MESA trigger with the Only when specific fields change option enabled. Spotlight the Fields value listing title, body html, and variants."><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.getmesa.com/best-practices/avoid-infinite-loops.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
