Skip to Content
AutomationsLoop Protection

Loop Protection

A data-change automation can update the same records that woke it up. Without a stop, that write starts the automation again, and the next write starts it again.

Loop protection is Flexkit’s built-in brake for that path. It applies to automations that run when your data changes. Scheduled, manual, and webhook runs are not rate-limited this way.

Skipped runs appear in Studio with status skipped. They do not use AI credits and do not count toward the automation’s run total.

Why it exists

The risky setup is an automation that:

  1. Listens for creates, updates, or deletes on an entity.
  2. Has Auto-approve mutations enabled.
  3. Writes back to records that match its own trigger.

One misconfigured automation like that can keep starting new runs until the team’s prepaid AI credits are gone.

What Flexkit stops

When an automation writes data, Flexkit remembers that it caused the change. The next data-change dispatch then applies these rules:

  • Self-trigger. The same automation does not run again from its own write.
  • Cycle. An automation already involved in this chain of writes does not run again.
  • Chain length. After three automations have run in one chain, further data-change automations are skipped.

Unrelated automations still run. If automation A updates a product status and automation B only sends a notification, B is not blocked.

Human edits, API writes, and chat-agent writes have no automation origin, so they always start a new chain.

Example: an automation that would trigger itself

Imagine a catalog with product records (name, sku, description, urlPath, and so on).

You create SEO Enricher:

  • Trigger: product is updated
  • Mutations: Auto-approve
  • Instructions: “When a product changes, rewrite description and set urlPath from name.”

An editor changes the name of Vitamin C 1000mg (sku: VITC-1000). That edit is a normal Studio save, so SEO Enricher is allowed to run.

The run updates the same product:

mutation {
  updateProducts(
    where: { sku: { eq: "VITC-1000" } }
    update: {
      description: { set: "Vitamin C 1000mg — daily antioxidant support." }
      urlPath: { set: "vitamin-c-1000mg" }
    }
  ) {
    products {
      sku
    }
  }
}

That write is another product update, so it matches SEO Enricher’s trigger again. Loop protection skips the second run as a self-trigger.

In Studio you will see:

Skipped because this automation caused the data change that would re-trigger it.

Without that skip, the second run would rewrite description again, start a third run, and continue until credits ran out.

What is still allowed

A second automation, Review Moderator, can listen for review creates or updates and set review.status to moderated or rejected. That write belongs to Review Moderator, so it does not start SEO Enricher.

You can also chain automations across entities. For example:

  1. A teammate creates a review.
  2. Review Moderator sets review.status to moderated.
  3. Rating Rollup updates the related product from the new reviews.
  4. SEO Enricher rewrites that product’s description and urlPath.
  5. SEO Enricher’s own product write would start SEO Enricher again — that run is skipped as a self-trigger.

If a fourth data-change automation tried to run from that last product write, it would be skipped because the chain is already three automations long.

If two automations keep writing records that wake each other — Rating Rollup updates a product, SEO Enricher updates that product, Rating Rollup would run again — the second pass is skipped as a cycle.

Many records, one run

When many matching records change together, Flexkit groups them. A bulk update of 40 products does not start 40 SEO Enricher runs. You get one run whose trigger payload lists every affected id.

Changes that arrive in a short window for the same automation, entity, and event are grouped the same way. Design instructions to handle a list of ids, or use a bulk GraphQL action when the list is large.

Rate and concurrency limits

Data-change runs also have caps so a burst of writes cannot start unlimited work:

  • 20 data-change runs per minute per automation
  • 60 data-change runs per minute per project
  • 3 runs of the same automation at once (running or waiting for approval)

If a cap is hit, Flexkit records a skipped run instead of starting another. Manual Run now, schedules, and webhooks are not included in these caps.

When Flexkit disables the automation

If the same automation is skipped 10 times in 10 minutes for a self-trigger, cycle, or chain-length reason, Flexkit turns it off. Rate and concurrency skips are still recorded in Studio, but they do not disable the automation. One write that would re-trigger the same automation across several entity types counts as a single skip, not one skip per entity type.

  • The automation’s Enabled switch is set to off.
  • The project activity log records that loop protection disabled it.
  • Billing recipients on the team get an email with the automation name, project, and skip reason.

Fix the trigger or instructions so the automation no longer writes the records that start it — or turn off Auto-approve so each write is reviewed — then enable it again in Studio.

How to design data-change automations

Prefer triggers that do not match the records you write. Review Moderator updating review.status is safer if a follow-up automation, not the same one, updates the related product.

Use Require approval while you are still shaping the instructions. Auto-approve is convenient, and it is also the setting that can loop without a person in the middle.

If a run is skipped, open it in Studio and read the summary. The reason tells you whether the automation wrote its own trigger, closed a cycle, hit the chain limit, or hit a rate cap.

Last updated on

© 2026