{"record":{"id":"f3a9b2de3d0e6371","repo":"phacility/phabricator","slug":"you-are-performing-too-many-actions-too-quickly","errorCode":null,"errorMessage":"You are performing too many actions too quickly.","messagePattern":"You are performing too many actions too quickly\\.","errorType":"exception","errorClass":"PhabricatorSystemActionRateLimitException","httpStatus":null,"severity":"warning","filePath":"src/applications/system/engine/PhabricatorSystemActionEngine.php","lineNumber":52,"sourceCode":"   * @{class:PhabricatorSystemActionRateLimitException}.\n   *\n   * @param list<string> List of actors.\n   * @param PhabricatorSystemAction Action being taken.\n   * @param float Score or credit, see above.\n   * @return void\n   */\n  public static function willTakeAction(\n    array $actors,\n    PhabricatorSystemAction $action,\n    $score) {\n\n    // If the score for this action is negative, we're giving the user a credit,\n    // so don't bother checking if they're blocked or not.\n    if ($score >= 0) {\n      $blocked = self::loadBlockedActors($actors, $action, $score);\n      if ($blocked) {\n        foreach ($blocked as $actor => $actor_score) {\n          throw new PhabricatorSystemActionRateLimitException(\n            $action,\n            $actor_score);\n        }\n      }\n    }\n\n    if ($score != 0) {\n      $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();\n        self::recordAction($actors, $action, $score);\n      unset($unguarded);\n    }\n  }\n\n  public static function loadBlockedActors(\n    array $actors,\n    PhabricatorSystemAction $action,\n    $score) {\n","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/system/engine/PhabricatorSystemActionEngine.php#L34-L70","documentation":"PhabricatorSystemActionEngine::willTakeAction() implements Phabricator's flood control: before an action executes it loads each actor's accumulated score for that PhabricatorSystemAction and, if the actor is already blocked, throws PhabricatorSystemActionRateLimitException. Scores decay over time, so the block is temporary and self-clearing.","triggerScenarios":"Calling willTakeAction() with a positive score for an actor whose recent score for that action exceeds the configured limit: bulk mail/mention/token actions, account creation bursts, or any per-row scripted action whose thresholds (Config > Actions) are set low relative to script volume.","commonSituations":"Scripts iterating thousands of records and firing one rate-limited action per row; a lowered threshold in PhabricatorSystemActionConfig; a shared bot actor whose budget is consumed by normal traffic plus scripted traffic.","solutions":["Slow down or pause the loop so scores decay below the limit, then resume","Raise (or disable) the specific action limit in Config > Actions","Batch work so a single action covers many objects instead of one action per object","Run flood-heavy scripted work under a dedicated actor with its own score budget"],"exampleFix":"// before: one rate-limited action per row, no guard\nforeach ($rows as $row) {\n  PhabricatorSystemActionEngine::willTakeAction(\n    array($actor_phid), new ExampleAction(), 1.0);\n  do_work($row);\n}\n\n// after: back off and retry when the actor is throttled\nforeach ($rows as $row) {\n  while (true) {\n    try {\n      PhabricatorSystemActionEngine::willTakeAction(\n        array($actor_phid), new ExampleAction(), 1.0);\n      break;\n    } catch (PhabricatorSystemActionRateLimitException $ex) {\n      sleep(60); // wait for scores to decay, then retry this row\n    }\n  }\n  do_work($row);\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"Wrap only the willTakeAction() call and catch PhabricatorSystemActionRateLimitException specifically (not Exception); read the exception's action/score, wait out the decay window with a sleep of tens of seconds, then retry the same item. Never widen the catch: real failures must still surface.","preventionTips":["Throttle loops that fire a rate-limited action per row","Tune action limits in Config > Actions to match legitimate bulk volume","Spread bursts through queue workers so actions occur over time","Give scripted actors their own account so floods do not block humans"],"tags":["rate-limit","flood-control","throttling","system-actions"],"backgroundTag":"rate-limit-exceeded","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}