
ServiceNowの深夜のアラートは誰が受ける? On-Call Scheduling(cmn_rota)の当番表を実機で読む
深夜に上がった重大インシデントが、結局どの担当者に飛ぶのか分からない。当番を交代したはずなのに、前任者へ通知が届く。こうした相談の裏には、ServiceNowの当番表がテーブルとして3階層に分かれている事情があります。cmn_rota(当番表の箱)・cmn_rota_roster(Primary/Secondaryの階層)・cmn_rota_member(メンバーと順番)の3つです。最終的には、営業時間と同じcmn_scheduleテーブルに展開されて「今の当番」が決まります。Zurich PDIのOOTBデータで、この3階層と展開先を実機で確認しました。
検証環境:Zurich PDI / OOTB / 2026-08-09 確認
結論:当番表は3階層のテーブルとcmn_scheduleへの展開で決まる
全体像を先に示します。
当番表はcmn_rota(当番表の箱・12件)、cmn_rota_roster(Primary/Secondaryの階層・21件)、cmn_rota_member(メンバーと順番・59件)という3階層のテーブルに保存されています。
同じ名前のorderフィールドが2箇所にありますが、意味は別です。roster.orderはエスカレーション順位、member.orderはローテーション位置を表します。
「今、誰が当番か」というカレンダーは、当番専用のテーブルではなく、営業時間と同じcmn_scheduleにrotation/roster型として展開されています。

グループ(sys_user_group)が持つ当番表(cmn_rota)の下に、Primary/Secondaryの階層(cmn_rota_roster)がぶら下がります。その階層に当番のメンバー(cmn_rota_member)が並び、メンバーはさらにsys_userを参照します。
On-Call Scheduling(オンコール・ローテーション)とは何か
ServiceNowのオンコール・スケジューリングは、「いつ・どのグループの・誰が当番か」をカレンダーとして定義する仕組みです。定義した当番表は、Incidentのエスカレーションや通知から参照されます。夜間のインシデントで「今の当番」へ自動通知されるのも、この当番表が「今は誰の番」と教えているからです。
公式のConfigure or update an On-Call schedule(Zurich)に、当番表(Rota)をグループとスケジュールから作る手順が説明されています。
テーブル定義は、次のURLで確認できます(先頭の<YourInstance>は自分のインスタンスに置き換えてください)。
https://<YourInstance>/sys_db_object_list.do?sysparm_query=nameSTARTSWITHcmn_rota当番表はどう3階層に分かれている?(cmn_rota / cmn_rota_roster / cmn_rota_member)
オンコールに関係するテーブルは、「当番表(箱)」「階層(順位)」「メンバー(人)」の3つに分けて見ると整理できます。3テーブルともsuper_classが空(ルート基底テーブル)で、taskなどを継承する構造ではありません。継承なしの独立系です。
cmn_rota(label: Shift)…当番表本体。group(→sys_user_group)で「どのグループの当番表か」を持ち、based_on(→cmn_schedule)は稼働の土台となる営業時間カレンダー(例24 x 7)への参照です。固有フィールドは27。
cmn_rota_roster(label: Roster)…当番の階層。rota(→cmn_rota)で親の当番表を参照し、orderでPrimary(1)/Secondary(2)/Tertiary(3)の順位を持ちます。固有フィールドは25。
cmn_rota_member(label: On-call Member)…メンバー。roster(→cmn_rota_roster)とmember(→sys_user)でロースターと人を結び、orderで「ローテーションの何番目か」を持ちます。固有フィールドは12。

当番表(cmn_rota)は1つの箱、ロースター(cmn_rota_roster)はその中の順位の段、メンバー(cmn_rota_member)はその段に並ぶ人です。1つの当番表に複数のロースターが付き、1つのロースターに複数のメンバーがぶら下がります。この構造が「Primaryが無理ならSecondary」「メンバーで週替わり」を表現する土台です。
実機で当番表のフォームを開くと、この構造がそのまま見えます。

当番表(cmn_rota)はグループ単位でどう設定される?
当番表は、グループ(sys_user_group)に対して1つ以上作られます。今回のPDI(Zurich / OOTB)のcmn_rota 12件は、いずれもグループに紐づいていました。Hardware / Network / Service Desk / Application Development / ITSM App-Dev / Nimsoft deskなどです。
実機のRotas一覧を見ると、グループごとに当番表が並んでいるのが分かります。

各当番表は、based_onで営業時間カレンダー(cmn_schedule)を土台にします。今回のPDIでは、Hardware系の多くが24 x 7でした。Office Hours / Working HoursはWorkday 8:00 - 5:00やWorkday 9:00 - 5:00を土台にしていました。
当番表本体の状態を表すstateフィールドは、choiceがdraft(Draft)の1値しか定義されていません。今回のPDIでは、12件すべてでstateは空(未設定)でした。send_reminders(当番リマインダ送信)は12件すべてでtrueです。use_custom_escalationがtrueなのはHardware (US)の1件だけでした。
state(State)…choiceはdraft 1値のみ。実データは空。
send_reminders(Send on-call reminders)…全12件true。
use_custom_escalation(Use custom escalation)…1件(Hardware (US))のみtrue。
https://<YourInstance>/cmn_rota_list.do?sysparm_query=ORDERBYgroupPrimary/Secondaryの順番はどこで決まる?(roster.orderとrotation_interval_type)
当番表の中には、Primary / Secondary / Tertiaryという階層(ロースター)が入ります。これが「Primaryが応答しなければSecondaryへ」というエスカレーションの順位になります。
order という名前のフィールドは2か所にあり、それぞれ意味が違います。名前は同じでも中身は別物です。
cmn_rota_roster.order…ロースターの順位。1=Primary / 2=Secondary / 3=Tertiaryのように、エスカレーションでどの段から呼ぶかを表します。
cmn_rota_member.order…メンバーのローテーション位置。同じロースター内で当番を回す順番(0, 1, 2…)を表します。

今回のPDI(Zurich / OOTB)のcmn_rota_roster 21件は、ほとんどがPrimary / Secondaryで、Tertiaryを持つのはGlobalの1件だけでした。rotation_interval_type(当番が交代する周期)は21件すべてがweekly(毎週)で、daily(毎日)は0件でした。

ロースターが「いつ交代するか」を決めるのは2つのフィールドです。rotation_interval_type(daily / weekly)とrotation_start_dow(交代開始曜日:1=Sunday〜7=Saturday)です。今回のPDIでは全件weeklyでしたが、dailyを選べば毎日交代の当番表も作れます。

https://<YourInstance>/cmn_rota_roster_list.do?sysparm_query=ORDERBYrota^ORDERBYorder公式のConfigure a roster(Zurich)に、ロースターの命名(Primary/Secondary)とローテーション間隔の設定方法が説明されています。
誰が何番目に回る? cmn_rota_memberのorderと実際のローテーション
ロースターの中に並ぶのが、メンバー(cmn_rota_member)です。member(→sys_user)で人を指し、orderで「ローテーションの何番目か」を持ちます。
今回のPDI(Zurich / OOTB)のcmn_rota_memberは59件でした。例えばHardware (US)のロースターを見ると、Primaryの1番目がBeth Anglin、2番目がDavid Loo。Secondaryの1番目がDavid Loo、2番目がBeth Anglinでした。同じ2人がPrimaryとSecondaryの両方に入り、段によって順番が入れ替わる構成です。折り返しの当番です。

メンバーの主なフィールドは次のとおりです。

member(Member → sys_user)…当番に入るユーザー。
roster(Roster → cmn_rota_roster)…所属するロースター。
order(Order)…ロースター内のローテーション順(0, 1, 2…)。
from / to(From / To)…メンバーの有効期間。期間を区切って交代要員を入れられます。
rotation_schedule(Rotation schedule → cmn_schedule)…このメンバーの当番期間を表す生成スケジュール(後述)。
実機の辞書一覧を見ると、これらのフィールドと参照先が並んでいます。公式のData dictionary tables(Zurich)にも、sys_dictionaryでフィールド定義を管理する仕組みが説明されています。

https://<YourInstance>/sys_dictionary_list.do?sysparm_query=name=cmn_rota_member^elementISNOTEMPTY「今、誰が当番か」はどこで解決される? cmn_scheduleへの展開
オンコールの3テーブルが持つのは「設定」までです。「誰がいつ当番か」という実際のカレンダーは、専用テーブルを持たず、cmn_schedule(営業時間と同じテーブル)に展開されていました。

今回のPDI(Zurich / OOTB)で確認した対応は、次のとおりでした。
cmn_rota_memberは59件すべてがrotation_schedule(→cmn_schedule)を持っていました。
cmn_schedule側でtype=rotationのレコードは59件でした。メンバー59件とrotation型スケジュール59件が一致します。各メンバーの当番期間が「Hardware: Beth Anglin: Primary」のような名前のスケジュールとして1件ずつ生成されているわけです。
同様に、cmn_schedule側でtype=rosterのレコードは12件で、当番表(cmn_rota)12件と一致しました。
オンコールの最終的な「いつが当番か」は、SLAの営業時間と同じcmn_scheduleテーブルにrotation / roster型として落ちます。当番カレンダーを調べたいときに「専用テーブルを探しても見つからない」のはこのためです。探す場所が違ったのです。cmn_scheduleのtypeで絞るのが正解でした。
https://<YourInstance>/cmn_schedule_list.do?sysparm_query=type=rotation
https://<YourInstance>/cmn_schedule_list.do?sysparm_query=type=rostercmn_scheduleのtype分布は、営業時間を扱った別記事でも同じ数字(rotation 59 / roster 12)を確認しています。本記事のオンコール側(member 59 / rota 12)と表裏で一致する数字です。
応答がなければ誰に回す? カスタムエスカレーション(escalation_set / esc_step_def)
オンコールは「誰が当番か」だけでなく、「応答がなければ次に誰へ」というエスカレーションの仕組みも持っています。標準ではrosterのorder(Primary、Secondary…の順)で呼び出す設計です。use_custom_escalation=trueの当番表なら、独自のエスカレーション手順を組めます。

今回のPDI(Zurich / OOTB)では、use_custom_escalation=trueの当番表はHardware (US)の1件のみでした。その下には次のテーブルが紐づいていました。
cmn_rota_escalation_set(Shift Escalation Set)… 3件:Hardware (US) - Default escalation set / High Priority Incident / Critical Incident。インシデントの重大度ごとに別の手順を用意していました。
cmn_rota_esc_step_def(Shift Escalation Step Definition)… 9件:各セットの「Notify Primary」「Notify Secondary」「Notify Group Manager」「Notify System Administrator」「Notify All Roster Members」といったステップ。
cmn_rota_escalation(Rotation Escalation)… 0件:これは実行(ログ)側で、今回のPDIでは発火実績がなく0件でした。実行ログはまだ空です。
カスタムエスカレーションは、セット(重大度別)とステップ(誰に通知)の2段で組み立てます。標準のPrimary、Secondaryの順で足りない場合に、重大度に応じて呼ぶ相手と順序を変えられます。
周辺機能はどれくらいある? Business Rule・UI Action・Notificationの実測
オンコールの動きも、フィールド定義だけでは決まりません。保存時のサーバ側処理はBusiness rules(Zurich)、項目の出し分けはUI Policyが担います。

特徴的なのは、cmn_rota側にUI Action(Zurich)が12件、Notification(Zurich)が3件ある点です。当番表は「今すぐ通知」「当番を見る」といった操作(UI Action)と、当番者へのメール通知(Notification)が厚くなっています。一方、メンバー(cmn_rota_member)は固有フィールド12と少なく、データの器に近い役割でした。役割分担がはっきりしています。
ここで数えているのはオンコール側に直接紐づく設定だけです。実際のエスカレーション挙動は、Incident(assignment_group→当番表)や通知、On-CallのAPIとも合わさって決まります。オンコール単体だけを見て全体を判断しないようにします。
Business Rules : https://<YourInstance>/sys_script_list.do?sysparm_query=collection=cmn_rota^active=true
UI Policies : https://<YourInstance>/sys_ui_policy_list.do?sysparm_query=table=cmn_rota
UI Actions : https://<YourInstance>/sys_ui_action_list.do?sysparm_query=table=cmn_rota実機で気づいたこと
Hardware (US)の当番は、Beth AnglinとDavid Looの2人だけで組まれていました。最初はPrimary/Secondaryにそれぞれ別の担当者が並ぶと思っていましたが、実際はこの2人がPrimaryとSecondaryの間で順番を入れ替えて、お互いのバックアップになる構成です。担当者が少ないグループでは、大人数を並べるより、この折り返し構成の方が現実的だと分かりました。
state フィールドは、choiceがdraft(Draft)の1値しか定義されていないのに、12件すべてで空でした。フィールドは存在するのに実質使われていない状態です。当番表が有効かどうかの管理には、代わりにActive(有効/無効フラグ)が使われているのだと考えられます。ここは推測です。
当初は、当番のカレンダーを持つ専用テーブル(cmn_rota_scheduleのようなもの)があると想定していましたが、このPDIには存在しませんでした。当番の実体はcmn_schedule(営業時間と同じテーブル)にtype=rotation / rosterとして混ざっていて、テーブル名だけで探しても見つかりません。オンコールのカレンダーを調べるときは、まずcmn_scheduleのtypeで絞り込む発想を持っておくと早く辿り着けます。
実務では何に使える? 通知トラブルを調査するときに見る場所
深夜のインシデントが「想定と違う人に飛んだ」「通知が来ない」といったトラブルを調べるときは、次の順に見ると早く原因に辿り着けます。
cmn_rota…対象グループの当番表を開き、based_on(土台のスケジュール)とuse_custom_escalationを確認する。
cmn_rota_roster…rota配下をorder順に確認し、Primary/Secondaryのどちらが先に呼ばれる設定かを確認する。
cmn_rota_member…roster配下のorderとfrom/toを確認し、「今の日時」がどのメンバーの担当期間かを特定する。
cmn_schedule(type=rotation)…該当メンバーのrotation_scheduleを開き、実際のカレンダー表示で当番期間を目で確認する。
use_custom_escalation=trueの当番表では、cmn_rota_escalation_set / esc_step_defも合わせて確認します。重大度に応じた独自の手順が、標準のPrimary→Secondary順の代わりに動いている可能性があるためです。
さらに詳しく知りたい人へ
SLAが土日を飛ばす理由:営業時間(cmn_schedule) — 当番表が最終的に展開される先であるcmn_scheduleを、営業時間の切り口で掘り下げます。
ユーザー・グループ・ロールは中間表でつながる — cmn_rota.groupが参照するsys_user_groupの構造を扱います。
メール通知が飛ぶまでの4段階(Notification) — 当番表に紐づく3件のNotificationが、実際にどう送信されるかを追います。
まとめ
当番表はcmn_rota(Shift)/ cmn_rota_roster(Roster)/ cmn_rota_member(On-call Member)の3階層です。今回のPDIでは12 / 21 / 59件でした。cmn_rotaはグループ単位で、based_on(→cmn_schedule)の営業時間を土台にします。orderは2種類あり、roster.orderがエスカレーション順位、member.orderがローテーション位置という違いです。「今、誰が当番か」は最終的にcmn_scheduleにrotation / roster型として展開されます。今回はmember 59=type=rotation 59、rota 12=type=roster 12と一致しました。カスタムエスカレーションはescalation_set(重大度別)とesc_step_def(誰に通知)の2段です。
オンコールを調べるときは、まず当番表そのものを読みます。「このグループの当番表はどれか(group)」「ロースターの順位(Primary/Secondary)はどうか」「メンバーのorderでどう回るか」「交代周期はdailyかweeklyか」。そのうえで、当番カレンダーの実体はcmn_schedule(type=rotation/roster)に展開される、という対応関係を押さえておきます。通知が飛ばない・順番がずれるといった調査が、これで早くなります。
用語
PDI…Personal Developer Instance(無料の検証用インスタンス)
OOTB…Out of the Box(初期設定のまま)
Rota / Shift(cmn_rota)…当番表(ローテーション)の本体。グループ単位
Roster(cmn_rota_roster)…当番表の中の階層(Primary/Secondary…)。orderでエスカレーション順位
On-call Member(cmn_rota_member)…ロースターに並ぶユーザー。orderでローテーション位置
rotation_schedule…メンバーの当番期間を表す生成スケジュール(cmn_schedule, type=rotation)
escalation set / step…カスタムエスカレーションのセット(重大度別)とステップ(通知先)
実機で調べるときに開いたURL
テーブル定義 : sys_db_object_list.do?sysparm_query=nameSTARTSWITHcmn_rota
固有フィールド一覧 : sys_dictionary_list.do?sysparm_query=name=cmn_rota_member^elementISNOTEMPTY
Rotas一覧 : cmn_rota_list.do?sysparm_query=ORDERBYgroup
Rosters一覧 : cmn_rota_roster_list.do?sysparm_query=ORDERBYrota^ORDERBYorder
交代周期グループ表示 : cmn_rota_roster_list.do?sysparm_query=GROUPBYrotation_interval_type
当番スケジュール : cmn_schedule_list.do?sysparm_query=type=rotation参考リンク
検証環境と未検証範囲
確認した範囲(PDI/Zurich/2026-08-09再確認のOOTBで取得。初回確認は2026-06-21):
cmn_rota / cmn_rota_roster / cmn_rota_memberの階層(いずれもルート基底)と固有フィールド数(27 / 25 / 12)
主要フィールドと参照先(group→sys_user_group、based_on/schedule→cmn_schedule、rota→cmn_rota、roster→cmn_rota_roster、member→sys_user、rotation_schedule→cmn_schedule)
cmn_rota.state(draft1値)・rotation_interval_type(daily/weekly)・rotation_start_dow(7値)のchoices
レコード件数(12 / 21 / 59)とrotation_interval_type分布(全21 weekly)
rotation_schedule充足(59件)とcmn_scheduleへの展開(rotation 59 / roster 12)
エスカレーション件数(escalation_set 3 / esc_step_def 9 / escalation 0、custom利用1件)
周辺設定件数、Hardware (US)ロースターのメンバー構成(Beth Anglin / David Loo)
確認していない範囲(断定しません):
cmn_rota_scheduleテーブルは当PDIに存在せず確認できませんでした
オンコールの実時間展開エンジン(誰が「今」当番かを解決する内部ロジック)
エスカレーションの発火経路(Incident → On-Call Notificationの全経路)
Notify Now / Who's on callウィジェットの内部
コミュニケーションチャネル(SMS/メール)連携
各Business Rule / UI Policyの内部スクリプト
本番でのカスタムローテーション、On-Call Schedulingプラグインのバージョン依存差
これらは別記事で扱います。実環境では、既存のカスタマイズによって当番表の定義・フィールド・件数が変わります。