Automation Script Error - Mutations Quota

I have a script that I am testing on a CRM system we use and I’ve run into an issue. The basic automation workflow looks like this:

A new record is added to a form which shows up in a view called “unprocessed.” This view is filtered on a linked record field, and any new record entered via a form will be missing the linked field data and so will automatically show up in this view.
As soon as the record drops into the view, the automation script fires

The trigger is “When a record enters into a view”
The action is to run a script.

The script itself loops through a second table to find matching records - and updates the appropriate linked records field for any matching records it finds. As a result, the record no longer appears in the unprocessed view since it now has a value in the linked record field.

The script runs well when there is one record in the view, but when multiple records enter the view at near the same time I believe it causes conflicts as the script runs for each record. The specific error message I’m seeing is:

Error: Exceeded quota of 15 mutations per second.

I’m thinking either the script needs to be optimized to run more quickly/smoothly, or I need to have the automation pause somehow before it processes each new record.

Given that I’m not sure what the mutations error means I’m not sure which direction to head.

Any thoughts?

Yep, one thought. It’s unlikely anyone here can help you without seeing code.

Understood - guess I wanted to start with getting a handle on what a mutation quota is.

It’s probably a race condition where the script is inadequately paced for the dependent processes.

Thanks Bill. That’s what I kind of figured but couldn’t find that phrase in the help docs. The script is below. I adapted it from another community post. It works, but with obviously some high overhead. I am basically processing new records in an unmatched view in one table, then updating the linked record field for all instances in another table where two fields match. I think I would run a lot faster and with fewer resources if I just processed one record at a time using an automation, but since I’m a script novice I’m not exactly sure how to edit this code accordingly.

//This script updates plan records with
//the link to a person’s scores.

//Set the tables we need for the script
let PlansTable = base.getTable(“Plans”);
let ScoresTable = base.getTable(“Scores”);
let ScoresView = ScoresTable.getView(“Unprocessed”)
let PlansQuery = await PlansTable.selectRecordsAsync();
let ScoresQuery = await ScoresView.selectRecordsAsync();

//Loop through the plan name records in the Plans table
for (let Plans of PlansQuery.records){
let LatestScore = Plans.getCellValue(“LatestScore”) || ;
//Loop through plan name records of the Scores table
for (let Scores of ScoresQuery.records) {
//Call out the column names we will use for matching
let PlanPerson = Plans.getCellValueAsString(“PlanPerson”);
let PlanActivity = Plans.getCellValueAsString(“PlanActivity”);
let ScorePerson = Scores.getCellValueAsString(“ScorePerson”);
let ScoreActivity = Scores.getCellValueAsString(“ScoreActivity”);

    if (PlanPerson == ScorePerson && PlanActivity == ScoreActivity) {
        LatestScore.push({id: Scores.id});
    }
}
//update the Latest score column in the plans table with Score linked record
await PlansTable.updateRecordAsync(Plans, {"LatestScore":LatestScore})

}

Should have added - not sure how to edit this to remove the loop that applies to the source table (Scores) and only start with one record when it enters the Unprocessed view using an automation trigger.

A mutation is basically every time you call any of the following:

updateRecordAsync
updateRecordsAsync
createRecordAsync
createRecordsAsync
deleteRecordAsync
deleteRecordsAsync

If you call one of the above inside a loop, you are calling the function multiple times.

The easiest method of reducing the number of mutations is to refactor your code to use the batch operations (the ones with the s) after your loop, instead of the single record operations inside the loop.

1 Like

@Tom_Glatt It should also be noted that a new automation trigger was added yesterday: when a record matches conditions. This provides the same condition setup as a view’s filters, but without the need to make a custom view that only serves to trigger an automation. If your “Unprocessed” view is being used anyway, there’s no need to change your setup, but I wanted to throw this out in case you, like me, have been making views simply for the sake of triggering automations.

1 Like