EventBridge Scheduler は、決めた時刻や間隔で AWS の API(Lambda の呼び出し、SQS への送信、ECS タスクの起動など)を呼ぶサービスです。 スケジュール1つにターゲット1つを持ち、cron・rate・at(1回だけ)の3種類の式と、Asia/Tokyo などのタイムゾーンを指定できます。AWS のドキュメントでは、時刻で何かを動かすときは EventBridge のスケジュールルールより Scheduler を使うよう勧められています。

# 平日の 9:00(日本時間)に Lambda を呼ぶ
aws scheduler create-schedule \
  --name daily-report \
  --schedule-expression 'cron(0 9 ? * MON-FRI *)' \
  --schedule-expression-timezone Asia/Tokyo \
  --flexible-time-window '{"Mode":"OFF"}' \
  --target '{
    "Arn": "arn:aws:lambda:ap-northeast-1:123456789012:function:daily-report",
    "RoleArn": "arn:aws:iam::123456789012:role/scheduler-exec",
    "Input": "{\"source\":\"scheduler\"}"
  }'
式 書き方 例 タイムゾーン
1回だけ at(yyyy-mm-ddThh:mm:ss) at(2026-10-20T09:00:00) 指定できる
一定間隔 rate(値 単位) rate(5 minutes)・rate(1 hour) 関係なし(開始から一定間隔)
日時の指定 cron(分 時 日 月 曜日 年) cron(0 9 ? * MON-FRI *) 指定できる

確認環境:AWS CLI 1.46.1・boto3 1.43.112・Python 3.11(Linux)。AWS には接続せず、moto 5.2.4 のサーバーモードに CLI を向けて、create-schedule(SQS・Lambda・ECS・ユニバーサルターゲット、DLQ・再試行ポリシー付き)、get-schedule・list-schedules・update-schedule・delete-schedule、スケジュールグループ、ActionAfterCompletion、boto3 での1回だけのスケジュール作成を動かしました。moto はターゲットを実際には呼ばないため、呼び出しの時刻・再試行・DLQ への送り方・上限・料金は AWS のドキュメントに基づいています(確認日 2026年10月13日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「EventBridge Schedulerの使い方|cron・rate・1回実行」

EventBridge ルール(スケジュール式)との違い

EventBridge には、前からある「スケジュールルール」(aws events put-rule --schedule-expression)と、2022年に出た「EventBridge Scheduler」(aws scheduler)の2つがあります。ドキュメントでは、スケジュールルールは legacy(従来の機能) とされ、Scheduler が勧められています。

項目 EventBridge Scheduler EventBridge ルール(スケジュール)
CLI・リソース aws scheduler・AWS::Scheduler::Schedule aws events・AWS::Events::Rule
タイムゾーン IANA のタイムゾーンを指定できる(夏時間も調整) UTC だけ
1回だけの実行 at() 式がある 無い(cron で年まで指定して代用)
ターゲット テンプレート化ターゲット+ユニバーサルターゲット(270 以上のサービス、6,000 以上の API) ルールの対応ターゲット。1 ルールに最大 5 個
スケジュールとターゲット 1 対 1 1 対 多(最大 5)
作れる数(既定) 1 リージョンに 10,000,000 スケジュール 1 イベントバスに 300 ルール(東京)
再試行・DLQ スケジュールごとに設定 ターゲットごとに設定
フレックスタイムウィンドウ ある 無い
呼び出しの権限 実行ロール(Scheduler が引き受ける) ターゲット側のリソースポリシー(Lambda の add-permission など)またはロール
実行の精度 60 秒(指定した分の 00〜59 秒の間) 1 分。数秒の遅れがあり得る

上限の数はドキュメントの値です(ルールは「Custom Event Bus - Classic」の表)。スケジュールルールの cron の書き方と、UTC への換算は、関連記事「EventBridge cron式の書き方|JST変換と例の早見表」で扱っています。Scheduler では --schedule-expression-timezone Asia/Tokyo を付けると、cron を日本時間のまま書けます。

準備:実行ロールを作る

Scheduler は、スケジュールに付けた IAM ロール(実行ロール)を引き受けて、ターゲットの API を呼びます。 信頼ポリシーのプリンシパルは scheduler.amazonaws.com です。

cat > trust.json <<'EOF'
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": { "Service": "scheduler.amazonaws.com" },
    "Action": "sts:AssumeRole",
    "Condition": { "StringEquals": { "aws:SourceAccount": "123456789012" } }
  }]
}
EOF

aws iam create-role --role-name scheduler-exec \
  --assume-role-policy-document file://trust.json

Condition の aws:SourceAccount は、自分のアカウントのスケジュールだけがこのロールを使えるようにする条件です。ドキュメントの基本例には無く、本番では「混乱した代理(confused deputy)」を防ぐ条件を足すよう案内されています。信頼ポリシーの読み方は、関連記事「IAMロールとは|ユーザー・ポリシーとの違いとAssumeRole、信頼ポリシー」で扱っています。

ターゲットごとに付ける権限です。

ターゲット 実行ロールに必要な権限
Lambda lambda:InvokeFunction
SQS sqs:SendMessage(KMS で暗号化したキューなら KMS の権限も)
SNS sns:Publish
ECS(RunTask) ecs:RunTask、タスクロール・タスク実行ロールを渡す iam:PassRole
Step Functions states:StartExecution
ユニバーサルターゲット 呼ぶ API の権限(例:ec2:StopInstances)
DLQ を付けるとき DLQ のキューへの sqs:SendMessage
cat > invoke.json <<'EOF'
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "lambda:InvokeFunction",
    "Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:daily-report*"
  }]
}
EOF
aws iam put-role-policy --role-name scheduler-exec \
  --policy-name invoke-lambda --policy-document file://invoke.json

ドキュメントの例は "Resource": "*" ですが、呼ぶ関数やキューの ARN に絞ることができます。Lambda 側に add-permission(リソースベースのポリシー)を足す操作は、Scheduler では使いません。 ロールの権限で呼ぶためです。

スケジュール式の書き方

at:1回だけ

at(2026-10-20T09:00:00)          ← --schedule-expression-timezone Asia/Tokyo なら日本時間の 9:00
決まり(ドキュメント) 内容
形式 at(yyyy-mm-ddThh:mm:ss)。タイムゾーンは --schedule-expression-timezone で指定(省くと UTC)
開始日・終了日 --start-date・--end-date は無視される
実行後 スケジュールは残り、上限の数に数えられ続ける。--action-after-completion DELETE で自動で消せる

rate:一定間隔

rate(5 minutes)    rate(1 hour)    rate(7 days)
決まり(ドキュメント) 内容
単位 minutes・hours・days(値は正の数)
最初の実行 --start-date があればそこから。無ければ作った直後から
days と夏時間 days は「24 時間」として数える。夏時間で1日が 23・25 時間になっても、前回の 24 時間後

rate は「何時何分」を決めません。毎日 9:00 のように時刻をそろえるなら cron を使います。

cron:日時の指定

cron(分 時 日 月 曜日 年) の6つを空白で区切ります。

フィールド 値 使える記号
分 0-59 , - * /
時 0-23 , - * /
日 1-31 , - * ? / L W
月 1-12 または JAN-DEC , - * /
曜日 1-7 または SUN-SAT(1 が日曜) , - * ? L #
年 1970-2199 , - * /

「日」と「曜日」の両方に * は書けません。 どちらかに *(または値)を書いたら、もう片方は ? にします。cron(0 9 * * MON-FRI *) は誤りで、cron(0 9 ? * MON-FRI *) が正しい形です。

よく使う例です(--schedule-expression-timezone Asia/Tokyo を付けた場合)。

やりたいこと 式
毎日 2:30 cron(30 2 * * ? *)
平日 9:00 cron(0 9 ? * MON-FRI *)
平日 9〜18 時の毎時 0 分 cron(0 9-18 ? * MON-FRI *)
15 分ごと cron(0/15 * * * ? *)
毎月 1 日 0:00 cron(0 0 1 * ? *)
毎月末日 18:00 cron(0 18 L * ? *)
毎月 15 日に一番近い平日 10:00 cron(0 10 15W * ? *)
第 2 火曜 10:00 cron(0 10 ? * 3#2 *)
毎月最後の金曜 10:15 cron(15 10 ? * 6L *)

# を使うときは、曜日のフィールドに式を1つしか書けません(3#1,6#3 は不可)。

タイムゾーンと夏時間

項目 内容(ドキュメント)
指定できる式 cron と at。値は IANA のタイムゾーン名(Asia/Tokyo・America/New_York など)
省いたとき UTC
夏時間で時刻が進む日 その時刻が存在しなければ、その日の実行は飛ばされる
夏時間で時刻が戻る日 1回だけ実行され、繰り返さない
精度 60 秒。1:00 の指定なら 1:00:00〜1:00:59 の間に呼ぶ(フレックスタイムウィンドウ無しのとき)

Asia/Tokyo には夏時間が無いので、日本時間で書くかぎり、飛ばされたり重なったりはしません。

create-schedule:ターゲット別の設定

ターゲットは2種類あります。

種類 Arn に入れるもの 対象
テンプレート化ターゲット 呼ぶリソースの ARN(関数・キュー・クラスターなど) Lambda Invoke、SQS SendMessage、SNS Publish、Step Functions StartExecution、ECS RunTask、EventBridge PutEvents、Kinesis・Firehose PutRecord、CodeBuild・CodePipeline・SageMaker の開始、Inspector
ユニバーサルターゲット arn:aws:scheduler:::aws-sdk:サービス:API名 上記以外の AWS API

Lambda

aws scheduler create-schedule \
  --name cleanup-hourly \
  --schedule-expression 'rate(1 hour)' \
  --flexible-time-window '{"Mode":"OFF"}' \
  --target '{
    "Arn": "arn:aws:lambda:ap-northeast-1:123456789012:function:cleanup",
    "RoleArn": "arn:aws:iam::123456789012:role/scheduler-exec",
    "Input": "{\"source\":\"scheduler\",\"at\":\"<aws.scheduler.scheduled-time>\"}"
  }'

Input の文字列が、そのまま Lambda の event になります。関数側では event["at"] に予定の時刻が入ります。Lambda 関数の作り方は、関連記事「AWS CLIでLambdaを作成・更新 環境変数とレイヤー」で扱っています。

SQS(DLQ・再試行つき)

moto で作って get-schedule で読み戻した形です。

aws scheduler create-schedule-group --name batch

aws scheduler create-schedule --name daily-report --group-name batch \
  --schedule-expression 'cron(0 9 ? * MON-FRI *)' --schedule-expression-timezone Asia/Tokyo \
  --flexible-time-window '{"Mode":"FLEXIBLE","MaximumWindowInMinutes":15}' \
  --target file://sqs-target.json
{
  "Arn": "arn:aws:sqs:ap-northeast-1:123456789012:jobs",
  "RoleArn": "arn:aws:iam::123456789012:role/scheduler-exec",
  "Input": "{\"job\":\"report\",\"at\":\"<aws.scheduler.scheduled-time>\"}",
  "RetryPolicy": { "MaximumEventAgeInSeconds": 3600, "MaximumRetryAttempts": 3 },
  "DeadLetterConfig": { "Arn": "arn:aws:sqs:ap-northeast-1:123456789012:scheduler-dlq" }
}
$ aws scheduler get-schedule --name daily-report --group-name batch
"Arn": "arn:aws:scheduler:ap-northeast-1:123456789012:schedule/batch/daily-report",
"FlexibleTimeWindow": { "MaximumWindowInMinutes": 15, "Mode": "FLEXIBLE" },
"ScheduleExpression": "cron(0 9 ? * MON-FRI *)",
"ScheduleExpressionTimezone": "Asia/Tokyo",
"State": "ENABLED",

--target は file:// で JSON ファイルを渡すと、引用符のエスケープで迷いません。FIFO キューに送るときは "SqsParameters": {"MessageGroupId": "..."} を足し、キュー側でコンテンツに基づく重複排除を有効にしておきます(CLI リファレンス)。SQS の基本は関連記事「Amazon SQSの使い方|送受信・削除と可視性タイムアウト、FIFO」で扱っています。

ECS(Fargate タスクの起動)

Arn にはクラスターの ARN、EcsParameters にタスク定義とネットワークを入れます。

{
  "Arn": "arn:aws:ecs:ap-northeast-1:123456789012:cluster/batch",
  "RoleArn": "arn:aws:iam::123456789012:role/scheduler-exec",
  "EcsParameters": {
    "TaskDefinitionArn": "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/nightly-job",
    "TaskCount": 1,
    "LaunchType": "FARGATE",
    "PlatformVersion": "LATEST",
    "NetworkConfiguration": {
      "awsvpcConfiguration": {
        "Subnets": ["subnet-0123456789abcdef0"],
        "SecurityGroups": ["sg-0123456789abcdef0"],
        "AssignPublicIp": "DISABLED"
      }
    }
  },
  "Input": "{\"containerOverrides\":[{\"name\":\"app\",\"command\":[\"python\",\"nightly.py\"]}]}"
}
aws scheduler create-schedule --name nightly-ecs \
  --schedule-expression 'cron(30 2 * * ? *)' --schedule-expression-timezone Asia/Tokyo \
  --flexible-time-window '{"Mode":"OFF"}' --target file://ecs-target.json
項目(CLI リファレンス) 内容
awsvpcConfiguration 先頭の a が小文字。中の Subnets・SecurityGroups・AssignPublicIp は大文字始まり
Subnets 必須。最大 16
SecurityGroups 最大 5。省くと VPC の既定のセキュリティグループ
AssignPublicIp ENABLED は Fargate のときだけ。プライベートサブネットなら DISABLED で、NAT か VPC エンドポイントが要る
TaskCount 1〜10(既定 1)
Input RunTask の追加の引数。上の例ではコンテナのコマンドを上書き

タスク定義の書き方は、関連記事「ECSタスク定義JSONの書き方|Fargate必須項目と環境変数secrets」で扱っています。

ユニバーサルターゲット(例:開発用 EC2 を夜に止める)

テンプレートに無い API は、arn:aws:scheduler:::aws-sdk:サービス:API名 で呼べます。Input には、その API のリクエストの JSON をそのまま書きます。

aws scheduler create-schedule --name stop-dev-ec2 \
  --schedule-expression 'cron(0 20 ? * MON-FRI *)' --schedule-expression-timezone Asia/Tokyo \
  --flexible-time-window '{"Mode":"OFF"}' \
  --target '{
    "Arn": "arn:aws:scheduler:::aws-sdk:ec2:stopInstances",
    "RoleArn": "arn:aws:iam::123456789012:role/scheduler-exec",
    "Input": "{\"InstanceIds\":[\"i-0123456789abcdef0\"]}"
  }'
決まり(ドキュメント) 内容
サービス名 SDK のサービス名(エンドポイントの名前と違うことがある。Cognito ユーザープールは cognitoidentityprovider)
API 名 先頭小文字(stopInstances・sendMessage)
呼べない API get・describe・list・poll・receive・search・scan・query・select・read・lookup・discover・validate・batchGet・retrieve・invokeModel などで始まる読み取り系

Input で使える置き換え

Input の中に書くと、呼び出しのたびに値に置き換わります。

キーワード 値の例
<aws.scheduler.schedule-arn> スケジュールの ARN
<aws.scheduler.scheduled-time> 予定の時刻(2022-03-22T18:59:43Z)
<aws.scheduler.execution-id> 呼び出しごとの ID
<aws.scheduler.attempt-number> 何回目の試行か(1 から)

execution-id は再試行でも同じ値ではなく、scheduled-time は予定の時刻です。Scheduler の配信は「少なくとも1回」(AWS のブログ)なので、同じ予定時刻の処理が2回来ても結果が変わらないよう、scheduled-time を処理済みのキーにする作り方があります。

フレックスタイムウィンドウ

FLEXIBLE にすると、予定の時刻から最大 N 分の間のどこかで呼びます。 多数のスケジュールが同じ時刻に集まるときに、呼び出しを散らせます。

値(API リファレンス) 内容
{"Mode":"OFF"} 予定の時刻に呼ぶ
{"Mode":"FLEXIBLE","MaximumWindowInMinutes":15} 予定の時刻から 15 分以内に呼ぶ
MaximumWindowInMinutes 1〜1,440

--flexible-time-window は省けません。 CLI では次のエラーになりました。

aws: error: the following arguments are required: --flexible-time-window

MaximumWindowInMinutes に 0 を入れると、送る前に止まります。

Parameter validation failed:
Invalid value for parameter FlexibleTimeWindow.MaximumWindowInMinutes, value: 0, valid min value: 1

決まった時刻ちょうどに動かしたい処理(締めの集計など)は OFF、多少ずれてよい処理は FLEXIBLE です。

再試行と DLQ

ターゲットの呼び出しに失敗すると、Scheduler は再試行し、それでも届かなければ DLQ(SQS の標準キュー)に送ります。

項目 内容
MaximumRetryAttempts 0〜185。再試行の回数。0 で再試行しない
MaximumEventAgeInSeconds 60〜86,400(24 時間)。この時間を過ぎたら再試行をやめる
指定しないとき 24 時間・185 回まで再試行(AWS のブログ。moto でも get-schedule に 86400・185 が入った)
再試行の間隔 指数バックオフ(だんだん間隔をあける)
DLQ が無いとき 再試行し尽くしたイベントは捨てられる
DLQ のキュー 標準キューだけ。FIFO は使えない

moto で RetryPolicy を書かずに作ったスケジュールです。

$ aws scheduler get-schedule --name every5 --query Target.RetryPolicy
{
    "MaximumEventAgeInSeconds": 86400,
    "MaximumRetryAttempts": 185
}

1 時間ごとの処理が 24 時間再試行され続けると、次の回と重なります。 間隔より短い MaximumEventAgeInSeconds、少なめの MaximumRetryAttempts にして、DLQ で失敗に気づく形が扱いやすくなります。

DLQ に入ったメッセージには、失敗の理由がメッセージ属性で付きます。

aws sqs receive-message --queue-url "$DLQ_URL" \
  --attribute-names All --message-attribute-names All --max-number-of-messages 1
属性(ドキュメント) 内容
ERROR_CODE・ERROR_MESSAGE ターゲットの API が返したエラー
EXHAUSTED_RETRY_CONDITION MaximumRetryAttempts(回数を使い切った)か MaximumEventAgeInSeconds(時間切れ)
TARGET_ARN・SCHEDULE_ARN 呼び先とスケジュール
SCHEDULED_TIME・EXECUTION_ID・RETRY_ATTEMPTS 予定の時刻・実行 ID・試行回数
IS_PAYLOAD_TRUNCATED 本文が切り詰められたか

EXHAUSTED_RETRY_CONDITION は、再試行できるエラーのときに付きます。権限が無いなど、再試行しても直らないエラーでは付きません。DLQ の監視と再処理は、関連記事「SQSデッドレターキューの設定|maxReceiveCountと再処理」で扱っています。

1回だけ実行して自動で消す(アプリから作る)

「3日後にリマインドを送る」のように、アプリが1件ずつスケジュールを作る使い方です。ActionAfterCompletion="DELETE" にすると、実行後に自動で消えます。

import json, uuid
from datetime import datetime
from zoneinfo import ZoneInfo
import boto3

scheduler = boto3.client("scheduler")

def schedule_reminder(user_id: str, run_at: datetime) -> str:
    """run_at の時刻に1回だけ Lambda を呼ぶ。実行後はスケジュールを自動で消す"""
    name = f"reminder-{user_id}-{uuid.uuid4().hex[:8]}"   # 64 文字以内・英数と - _ .
    scheduler.create_schedule(
        Name=name,
        GroupName="default",
        ScheduleExpression=f"at({run_at.strftime('%Y-%m-%dT%H:%M:%S')})",
        ScheduleExpressionTimezone="Asia/Tokyo",
        FlexibleTimeWindow={"Mode": "OFF"},
        ActionAfterCompletion="DELETE",
        Target={
            "Arn": "arn:aws:lambda:ap-northeast-1:123456789012:function:send-reminder",
            "RoleArn": "arn:aws:iam::123456789012:role/scheduler-exec",
            "Input": json.dumps({"userId": user_id,
                                 "scheduledTime": "<aws.scheduler.scheduled-time>"}),
            "RetryPolicy": {"MaximumRetryAttempts": 3, "MaximumEventAgeInSeconds": 3600},
        },
    )
    return name

run_at = datetime(2026, 10, 16, 9, 0, tzinfo=ZoneInfo("Asia/Tokyo"))
name = schedule_reminder("u123", run_at)
s = scheduler.get_schedule(Name=name)
print(name)
print(s["ScheduleExpression"], s["ScheduleExpressionTimezone"], s["ActionAfterCompletion"])
print(s["Target"]["Input"])

moto に向けて動かした出力です。

reminder-u123-02ad45ec
at(2026-10-16T09:00:00) Asia/Tokyo DELETE
{"userId": "u123", "scheduledTime": "<aws.scheduler.scheduled-time>"}
ActionAfterCompletion(ドキュメント) 消えるとき
DELETE・at 式 1回呼んだあと
DELETE・cron/rate 式 --end-date に一番近い最後の呼び出しのあと。EndDate が無いと消えない
NONE(既定) 消えない。終わった at のスケジュールも上限の数に残る

取り消すときは delete_schedule(Name=name) です。 名前を DB に保存しておくと、予約のキャンセルに使えます。

更新の注意:update-schedule は「全部置き換え」

update-schedule は、渡さなかった項目を既定値に戻します。 API リファレンスに「指定しなかった任意の項目は、更新後にシステムの既定値になる」と書かれています。

moto で、タイムゾーン・再試行・DLQ・Input を付けたスケジュールを、式とターゲットの ARN だけ渡して更新した結果です。

$ aws scheduler update-schedule --name report --schedule-expression 'cron(0 10 * * ? *)' \
    --flexible-time-window Mode=OFF --target '{"Arn":"arn:...:jobs","RoleArn":"arn:...:scheduler-exec"}'
$ aws scheduler get-schedule --name report --query '{Expr:...,TZ:...,Retry:...,DLQ:...,Input:...}'
{
    "Expr": "cron(0 10 * * ? *)",
    "TZ": "UTC",
    "Retry": { "MaximumEventAgeInSeconds": 86400, "MaximumRetryAttempts": 185 },
    "DLQ": null,
    "Input": null
}

タイムゾーンが UTC に戻り、10 時(日本時間 19 時)の実行になりました。 DLQ と Input も消えています。CLI でも --flexible-time-window と --target を省くとエラーで止まりますが、それ以外は黙って既定値に戻ります。

get-schedule の結果から必要な項目を取り出し、変えたい所だけ書き換えて渡すと安全です。

aws scheduler get-schedule --name report \
 | jq '{Name, GroupName, ScheduleExpression, ScheduleExpressionTimezone, FlexibleTimeWindow,
        Target, Description, StartDate, EndDate, KmsKeyArn, ActionAfterCompletion}
       | with_entries(select(.value != null))
       | .State = "DISABLED"' > update.json

aws scheduler update-schedule --cli-input-json file://update.json

moto で動かすと、State だけが DISABLED に変わり、タイムゾーン(Asia/Tokyo)・再試行(3 回・3600 秒)・DLQ は残りました。止める・再開するだけなら、この方法で State を DISABLED/ENABLED にします。

一覧・削除・グループ

aws scheduler list-schedules --query 'Schedules[].[GroupName,Name,State]' --output text
aws scheduler list-schedules --group-name batch --name-prefix daily
aws scheduler delete-schedule --name cleanup-hourly
aws scheduler delete-schedule --name daily-report --group-name batch
aws scheduler delete-schedule-group --name batch     # グループ内のスケジュールも消える
項目 内容
スケジュールグループ スケジュールをまとめる入れ物。タグはグループに付ける。default が最初からある
グループを消すと 状態が DELETING になり、中のスケジュールも消える(ドキュメント。moto でも消えた)
--group-name を省くと default グループ
名前 1〜64 文字、[0-9a-zA-Z-_.]+。グループの中で一意

moto で出たエラーと、実際の AWS での扱い

操作 moto での結果 AWS での扱い(ドキュメント)
同じ名前で作る ConflictException ... Schedule lambda-hourly already exists. 同じく ConflictException
消したスケジュールを取得 ResourceNotFoundException ... does not exist. 同じく 404
--flexible-time-window を省く CLI のエラー(必須) 必須
MaximumWindowInMinutes=0 送る前にエラー(最小 1) 1〜1,440
MaximumRetryAttempts=200 作られた 0〜185。ValidationException になる範囲
cron(0 9 * * MON-FRI *) 作られた 日と曜日の両方に値があるため不正な式

moto は式や上限の範囲を細かく調べません。 テストで作れても、実際の AWS では断られる設定があります。式の書き方は上の表で確かめてから使います。

上限と料金

項目(ドキュメント) 値
スケジュールの数 1 リージョンに 10,000,000(引き上げ可)。終わった at のスケジュールも含む
スケジュールグループ 1 リージョンに 500
呼び出しの速さ 東京などで 1,000 TPS(ほかは 500)。超えると遅れて呼ばれる(捨てられない)
CreateSchedule の速さ 東京などで 5,000 回/秒
Input の大きさ 256 KB(固定)
1つのスケジュールの読み書き 10 TPS
料金(AWS の料金ページ) 値
無料枠 毎月 14,000,000 回の呼び出し(GovCloud 以外の全リージョン合計)
超えた分 料金ページの計算例では 100 万回あたり 1.00 USD

5 分ごとのスケジュールは、1 か月(30 日)で 8,640 回です。数百個の定期実行なら無料枠の中に収まる計算です。料金の確かめ方は、関連記事「AWSの料金を確認する方法|Cost Explorer・CLI・予算アラート」で扱っています。

よくある質問

Q. スケジュールが動いたかどうかは、どこで分かりますか。 A. CloudWatch の AWS/Scheduler 名前空間の指標で見ます。値はアカウント全体と、スケジュールグループ(ScheduleGroup ディメンション)ごとに集計されます。

指標(ドキュメント) 分かること
InvocationAttemptCount 呼び出しを試みた回数
TargetErrorCount・TargetErrorThrottledCount ターゲットがエラー・スロットリングを返した
InvocationThrottleCount Scheduler の呼び出しの上限で遅らせた
InvocationDroppedCount 再試行を使い切って捨てた(DLQ 無し)
InvocationsSentToDeadLetterCount DLQ に送った

InvocationDroppedCount と InvocationsSentToDeadLetterCount が 0 より大きくなったら知らせるアラームを作っておくと、失敗に気づけます。関連記事「CloudWatchアラームをAWS CLIで作成|SNS通知・カスタム指標」で扱っています。

Q. 秒単位で動かせますか。 A. できません。精度は 60 秒で、指定した分の中のどこかで呼ばれます。秒単位の待ち合わせは、Step Functions の Wait 状態などで作ります。関連記事「Step Functions入門|ASLの書き方とLambda連携・Retry」で扱っています。

Q. 既存の EventBridge ルールから移すと、何が変わりますか。 A. cron を UTC から日本時間に書き直せること、Lambda の add-permission の代わりに実行ロールを使うこと、ターゲットが1つになることです。ルールに複数のターゲットがあるなら、スケジュールを複数作ります。

Q. CloudFormation ではどう書きますか。 A. AWS::Scheduler::Schedule で、FlexibleTimeWindow・ScheduleExpression・Target が必須です。CLI の JSON と同じ名前の項目が並びます。

まとめ

  • aws scheduler create-schedule に 式・--flexible-time-window・--target(Arn と RoleArn) が必須
  • 時刻は cron + --schedule-expression-timezone Asia/Tokyo。日と曜日のどちらかは ?
  • 1回だけは at()。--action-after-completion DELETE で実行後に消す
  • 実行ロールの信頼ポリシーは scheduler.amazonaws.com。Lambda の add-permission は使わない
  • 再試行は既定で 24 時間・185 回。間隔に合わせて短くし、DLQ(標準キュー) を付ける
  • update-schedule は全部置き換え。get-schedule → 書き換え → --cli-input-json で更新
  • 無料枠は毎月 1,400 万回の呼び出し

参考・出典

確認日はいずれも 2026年10月13日です。

  • EventBridge Scheduler User Guide「Schedule types in EventBridge Scheduler」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html
  • EventBridge Scheduler User Guide「Getting started with EventBridge Scheduler」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/getting-started.html
  • EventBridge Scheduler User Guide「Setting up Amazon EventBridge Scheduler」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/setting-up.html
  • EventBridge Scheduler User Guide「Using templated targets」「Using universal targets」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-targets-universal.html
  • EventBridge Scheduler User Guide「Adding context attributes」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-schedule-context-attributes.html
  • EventBridge Scheduler User Guide「Configuring flexible time windows」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-schedule-flexible-time-windows.html
  • EventBridge Scheduler User Guide「Configuring a schedule's dead-letter queue」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/configuring-schedule-dlq.html
  • EventBridge Scheduler User Guide「Deleting a schedule」「Managing a schedule group」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-schedule-delete.html
  • EventBridge Scheduler User Guide「Quotas for EventBridge Scheduler」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/scheduler-quotas.html
  • EventBridge Scheduler API Reference「CreateSchedule」「UpdateSchedule」「RetryPolicy」「FlexibleTimeWindow」:https://docs.aws.amazon.com/scheduler/latest/APIReference/API_UpdateSchedule.html
  • AWS CLI Command Reference「scheduler create-schedule」:https://docs.aws.amazon.com/cli/latest/reference/scheduler/create-schedule.html
  • Amazon EventBridge User Guide「Creating a rule that runs on a schedule」:https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule-schedule.html
  • Amazon EventBridge User Guide「Amazon EventBridge quotas」:https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-quota.html
  • Amazon EventBridge の料金:https://aws.amazon.com/eventbridge/pricing/
  • AWS Compute Blog「Introducing Amazon EventBridge Scheduler」:https://aws.amazon.com/blogs/compute/introducing-amazon-eventbridge-scheduler/
  • クラスメソッド「[新機能] タイムゾーン指定でスケジュール起動できるAmazon EventBridge Schedulerがリリースされました」:https://dev.classmethod.jp/articles/amazon-eventbridge-scheduler-new-way-to-launch-tasks/

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「EventBridge Schedulerの使い方|cron・rate・1回実行」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?