
ServiceNowのBusiness Ruleはいつ動く? before/after/asyncの違いを実機の件数で確認
保存したらフォームの値が勝手に書き換わった、あるいは保存自体が止まった経験はないでしょうか。多くの場合、原因はサーバー側で動くBusiness Ruleです。ServiceNowはこの処理をsys_scriptという1つのテーブルにまとめています。いつ動くか(when)・同じタイミングの中の順番(order)・動く条件(condition)を、1レコードのフィールドから読み取れます。Zurich PDIでBusiness Rule 5,719件を数え、構造を実機で確認しました。
検証環境:Zurich PDI / OOTB / 2026-08-08 確認
結論:Business Ruleは1レコードのフィールドで読み解ける
全体像を先に示します。
Business Ruleはsys_scriptという1つのテーブルに、1ルール=1レコードで保存されます。Client ScriptやUI Actionと同じsys_metadata(Application File)配下の「アプリ構成」として管理される仕組みで、業務データのテーブルではありません。
実行タイミングはwhenが決めます。before/after/asyncはDB保存に、displayはフォーム表示に絡み、全5,719件のうち約6割がbeforeでした。
同じwhen内の順番はorder、実際に動くかどうかはaction_*(反応するDB操作)→filter_condition→condition(Advancedタブ)の3段階で絞られます。
処理本体はadvancedフラグで2通りに分かれ、今回のPDIではほぼ全件(5,650件)がscriptを直接書くAdvancedモードでした。
incidentのBusiness Ruleを1件開くと、この構造が1フォームに集約されているのが分かります。

when(実行タイミング)を軸に、DB操作の前後でBusiness Ruleがどこに位置するかを整理すると、次の流れになります。

図の色は6種類の意味に固定しています。濃紺はデータベース書き込みという起点です。橙は件数が突出しているタイミング(before)、緑は保存後に同期で進む処理(after)を表します。紫は別トランザクションで動く処理(async)、水色はクライアントへの参照渡し(display)です。灰色は経路上の中継点を示します。before・display・DB書き込みが並ぶ縦の流れが本線で、DB書き込みの後にafterとasyncへ分岐します。
Business Rule(ビジネスルール)とは
Business Ruleとは、レコードが表示・挿入・更新・削除されたとき、またはテーブルが照会(query)されたときに、サーバー側で動くJavaScriptの処理です。「保存したらStateを変える」「条件を満たしたら通知を投げる」「ユーザーが見られるレコードを絞る」といった、データの整合性や自動化を担う中心的な仕組みです。
ServiceNowでは、このBusiness Ruleを格納する中心テーブルがsys_scriptです。画面ではSystem Definition > Business Rulesから一覧でき、各レコードが1つのルールに対応します。**「いつ(when)」「どの操作で(action_*)」「どんな条件で(condition)」「何を(script)」**するかを、1レコードの中のフィールドで定義します。
sys_scriptはどこに位置するテーブルか
最初に押さえたいのは、sys_scriptがincidentやcmdb_ciのような「業務データのテーブル」ではない、という点です。

今回のPDI(Zurich / OOTB)で確認すると、sys_scriptはsys_metadata(Application File)を継承するテーブルでした。sys_metadataはUpdate Setで持ち運べる「アプリ構成」の基底です。つまりBusiness Ruleは「設定・構成」側のレコードとして管理されます。Client Script(sys_script_client)やUI Action(sys_ui_action)も、同じsys_metadata配下の兄弟という位置づけです。いずれも「どのテーブルに対する処理か」という情報を持つ点は共通しています。
Business Ruleが「どの業務テーブルに効くか」は、sys_scriptの中のcollection(画面ラベル: Table)フィールドで決まります。incidentのBusiness Ruleならcollection=incident、という具合です。sys_script自体は1つのテーブルですが、collectionを通じてあらゆる業務テーブルに処理を差し込めます。接点は1つのフィールドです。
テーブル定義は、次のURLで確認できます(先頭の<YourInstance>は自分のインスタンスに置き換えてください)。
https://<YourInstance>/sys_db_object_list.do?sysparm_query=name=sys_script
Business Ruleはいつ動く? whenは4種類
Business Ruleで最初に決めるのがwhen(実行タイミング)です。同じ「保存時の処理」でも、DBに書き込む前なのか後なのか、同期か非同期かで意味がまったく変わります。
before … DBに保存する直前に動きます。currentの値を補正したり、current.setAbortAction(true)で保存自体を中断できます。入力値のチェックや自動補完に向きます。
after … DBに保存した直後に、同期で動きます。保存済みのレコードを前提に、関連レコードを更新するなどの後処理に向きます。
async … 保存後に非同期(バックグラウンド)で動きます。スケジュールキューに積まれて後追い実行されるため、ユーザーには素早く制御が戻りますが、反映までに時間差が出ます。重い後処理に向きます。
display … フォームを表示する前に動き、g_scratchpadを使ってサーバー側の情報をクライアント(ブラウザ)へ受け渡します。Client Scriptから使う値を準備する用途です。
before/after/asyncが「DB操作(保存)」に絡むのに対し、displayだけは「フォーム表示」に絡みます。同じwhenフィールドでも、トリガーになるイベントが違う点に注意が必要です。
実機でwhen別の件数を数えると、傾向がはっきり出ます。

beforeが3,441件と最多で、全体(5,719件)の約6割を占めていました。afterが1,456件、displayが601件、asyncが148件です。保存前に値を整える処理が、もっとも多く使われていることが件数からも読み取れます。なお内部値としては、旧仕様のasync(非推奨)が別に64件残存していましたが、現在の有効な選択肢はbefore/after/async/displayの4種です。
whenの選択肢は、次のURLで一覧できます。
https://<YourInstance>/sys_choice_list.do?sysparm_query=name=sys_script^element=when^inactive=false^ORDERBYsequence
公式のBusiness rules(Zurich)に、Business Ruleが「表示・挿入・更新・削除・照会のときに動くサーバー側スクリプト」であることと、各タイミングの考え方が説明されています。
同じwhen内の順番はどう決まる? order
whenが同じBusiness Ruleが複数あるとき、どちらが先に動くかを決めるのがorder(実行順)です。orderの数値が小さいほど先に実行され、同じwhen・同じテーブルの中で順番に処理されます。
今回のPDIでは、orderを持たない(空の)BRは0件で、全件がorderを持っていました。値の分布を見ると、既定値の100が4,840件(全体の84.6%)と圧倒的です。ほかはorder未満の値が265件(うちorder=0が15件)、100超が614件でした。多くのBusiness Ruleはorder=100のままにし、特定の前後関係が必要なものだけ値をずらす、という使われ方が読み取れます。
複数のBusiness Ruleが同じwhenで動くとき、実行順の食い違いはバグの原因になりやすいところです。「値を補正するbefore BR」と「補正後の値を前提にチェックするbefore BR」があるなら、補正側のorderを小さくして先に動かす、といった設計になります。順番は偶然ではなく設計で決めるものです。
動く条件はどこで絞られる? filter_conditionとcondition
Business Ruleは、いつでもscriptを実行するわけではありません。「この操作・この条件のときだけ動く」というフィルタが、複数段で効きます。

sys_scriptのフィールドを見ると、条件は大きく次の段階で評価されます。
action_insert / action_update / action_delete / action_query … そのBRが反応するDB操作。複数をONにでき、insertとupdateの両方に反応、といった指定が可能です。実機ではaction_update=trueが3,825件、action_insert=trueが3,670件でした。action_delete=trueが961件、action_query=trueが84件です(フラグは独立なので合計は総数と一致しません)。
filter_condition(画面: When to RunのFilter Conditions) … 「stateが3に変わったら」のような宣言的な条件。コードを書かずにUIで組み立てます。設定しているBRは1,856件(32.5%)でした。
condition(画面: AdvancedタブのCondition) … advanced=trueのときに使う、JavaScriptの追加条件。filter_conditionを満たした上で、さらにこの式がtrueのときだけscriptが動きます。設定しているBRは1,550件(27.1%)でした。
filter_conditionが先に評価され、それを満たした場合にのみcondition(JavaScript)が評価される、という二段構えです。無条件(フラグのみ)で動くBusiness Ruleの方がまだ多いものの、3割前後は宣言的フィルタや追加条件で対象を絞り込んでいました。重いJavaScript条件をいきなり全レコードで走らせず、まず宣言的フィルタで絞る設計になっています。無駄打ちを減らす工夫です。
scriptは書く?書かない? advancedで分かれる処理本体
Business Ruleには、処理の書き方が2通りあります。それを切り替えるのがadvanced(高度モード)フラグです。

advanced=false … scriptを書きません。template(Set field values)で「このフィールドにこの値を入れる」といった単純な値セットや、メッセージ表示だけを宣言的に行います。
advanced=true … script(サーバー側JavaScript)を直接書くモード。Advancedタブが現れ、conditionとscriptを編集できます。current / previous / g_scratchpadなどのオブジェクトを使った自由な処理が書けます。
今回のPDIでは、advanced=trueが5,650件、advanced=falseが69件でした。OOTBのBusiness Ruleは、ほぼすべてがscriptを直接書く高度モードで、宣言的な値セットだけのBRはごく少数です。実務でも、少し凝った処理になればすぐadvancedをONにするため、この偏りは自然な結果に見えます。テンプレートより書く方が速いからです。
beforeタイミングのBRでは、abort_action(操作中断)も使えます。実機ではabort_action=trueが157件あり、保存をブロックして整合性を守る用途で使われています。
主な固有フィールドを役割で整理すると次のとおりです。ラベルは画面上の表示名で、実機どおり記載します。

どのテーブルに効く? collectionと継承の関係
Business Ruleが「どのテーブルに効くか」はcollection(Table)で決まります。incidentに紐づくBR、cmdb_ciに紐づくBRというように、対象テーブルごとにsys_scriptのレコードが束ねられます。
今回のPDIでは、collection=incidentのBusiness Ruleは39件(active 38件)でした。collection=taskのBRは37件(active 35件)です。テーブルを指定しない(collectionが空の)BRも5件あり、これらは特定テーブルに限らず動く扱いです。

ここで注意したいのは、incidentはtaskを継承するテーブルだという点です。incidentのレコードを保存すると、incidentに紐づくBRだけでなく、親のtaskに紐づくBRも対象になり得ます。継承時の実行マージ順の実測は検証範囲外ですが、「incidentの挙動」を調べるときは、incidentだけでなくtaskのBusiness Ruleも合わせて見る必要があります。片方だけでは足りません。
特定テーブルのBusiness Ruleは、次のURLで確認できます。
https://<YourInstance>/sys_script_list.do?sysparm_query=collection=incident^active=true^ORDERBYwhen^ORDERBYorder
全フィールドは、次のURLで一覧できます。
https://<YourInstance>/sys_dictionary_list.do?sysparm_query=name=sys_script^elementISNOTEMPTY
実機で気づいたこと
この記事を最初に書いたときのsys_scriptの総数は5,500件でした。約7週間後に同じPDIで数え直すと5,719件に増えていました。カスタマイズは何も加えていません。219件、4%の増加です。パッチや自動アップグレードで標準のBusiness Rule自体が増減することが分かります。OOTBの件数は確認した時点のスナップショットであり、固定値だとは考えない方が安全です。件数は生き物です。
whenの値を数える過程で、有効な4つの選択肢(before / after / async_always / before_display)のどれにも一致しない値を持つレコードが1件見つかりました。名前は「OnCallEscalation」、Globalスコープでcollectionは空、whenの値はactionです。sys_choiceの選択肢一覧にこの値は登録されておらず、フォームのドロップダウンからは選べないはずです。おそらく過去のバージョンで許可されていた値が、アップグレードをまたいで残存したものと考えられます。件数を単純にwhenでグループ化しただけでは、こうした非標準の値を見落とします。
もう1つ意外だったのは、非推奨の内部値async(ラベル「旧async」)が54件から64件に増えていたことです。非推奨のはずの選択肢を使うBusiness Ruleが、標準機能のアップデートによって今も新規に増える余地がある、ということになります。非推奨だから0件に向かっていくとは限りません。
実務では何に使える? 新しいBusiness Ruleを作るときに見るフィールド
新しくBusiness Ruleを作るとき、あるいは既存のものを読み解くとき、見るフィールドは実質4つに絞れます。
when … 保存前に止めたい・直したいならbefore、保存後に他のレコードへ連携したいならafter、応答を待たせたくない重い処理ならasync、クライアントに値を渡すだけならdisplay
order … 既定の100のままで足りることが多く、他のBRとの前後関係が必要になったときだけ意図的にずらす
**action_* / filter_condition / condition** … まず反応するDB操作を絞り、宣言的フィルタで対象を絞り、必要なときだけJavaScriptの追加条件を書く
advanced … 単純な値セットで足りるならfalseのままtemplateを使い、条件分岐や計算が要るならtrueにしてscriptを書く
既存のBusiness Ruleを調べるときは、対象テーブルのsys_script一覧をwhen・order順に並べれば、実行される順番のままフィールドを追えます。前述のsys_script_list.do?sysparm_query=collection=<テーブル名>^active=true^ORDERBYwhen^ORDERBYorderは、そのままチェックの起点として使えるURLです。
まとめ
Business Ruleは、sys_scriptという1つのテーブルに、1ルール=1レコードで保存されています。sys_metadata(Application File)配下の「アプリ構成」として管理される点が出発点で、業務データそのものではありません。
いつ動くかはwhen、同じwhen内の順番はorder、実際に動くかどうかはaction_*→filter_condition→conditionという3段階のフィルタが決めます。今回のPDIではbeforeが全体の6割を占め、orderは84.6%が既定の100のままでした。処理本体を書くかどうかはadvancedフラグ次第で、ほぼ全件がscriptを直接書く高度モードです。
次にBusiness Ruleを1件読み解くときは、まずwhenとcollectionで「いつ・どのテーブルに効くか」を確認します。そのうえでaction_*とfilter_condition / conditionから「どんな条件で動くか」を追えば、フォーム1枚から仕組みを読み切れます。答えは1レコードの中です。
用語
PDI … Personal Developer Instance(無料の検証用インスタンス)
OOTB … Out of the Box(初期設定のまま)
Business Rule … レコード操作・照会時にサーバー側で動く処理の定義
sys_script … Business Ruleを格納するテーブル
collection … そのBRが紐づく対象テーブル名(画面ラベル: Table)
g_scratchpad … display BRでサーバー→クライアントへ値を渡すオブジェクト
実機で調べるときに開いたURL
sys_db_object_list.do?sysparm_query=name=sys_script … テーブル定義
sys_choice_list.do?sysparm_query=name=sys_script^element=when^inactive=false^ORDERBYsequence … whenの選択肢
sys_dictionary_list.do?sysparm_query=name=sys_script^elementISNOTEMPTY … フィールド一覧
sys_script_list.do?sysparm_query=collection=incident^active=true^ORDERBYwhen^ORDERBYorder … incidentのBR
sys_script_list.do … 全BR一覧
次に読むなら
Business Ruleはどの順番で動くか:incidentの39本を並べて確かめる — 本記事のwhen・orderの理解を前提に、incidentの39本を実行順で並べ直す実務編
ServiceNowで処理を書くならどこ? Business Rule・Client Script・ACLの使い分けを実機の件数から考える — ACLやScript Includeまで含めた6つの仕組み全体の地図
Client ScriptとUI Policyの違い(フォーム挙動) — 画面側で動く2つの仕組みとの役割分担を整理
参考リンク
検証環境と未検証範囲
確認した範囲(PDI/Zurich/2026-08-08 再測定のOOTBで取得。初回確認は2026-06-21):
sys_scriptの継承(sys_metadata配下)
固有フィールド数(34)
whenの選択肢(before/after/async/display)と件数、非標準の値(action・空欄)
advanced分布、action_*フラグ件数、abort_action件数
filter_condition / conditionの設定率
order分布
collection紐づき(incident / task / 空)
確認していない範囲:
各Business Ruleの内部スクリプトの実際の挙動
継承テーブル(task→incident)での実行マージ順の実測
current / previous / g_scratchpadの実行時挙動
Client Script / UI Policyとの連携、Flow Designer / Script Includeとの実行順序
ドメイン分離環境での差異
件数は2026-08-08時点の値です。本番環境やカスタマイズ済みの環境では、ルールの数・内容・実行順が異なります。