The App Engine Cron Service allows you to configure regularly scheduled tasks that operate at defined times or regular intervals. These tasks are commonly known as cron jobs. These cron jobs are automatically triggered by the App Engine Cron Service. For instance, you might use this to send out a report email on a daily basis, to update some cached data every 10 minutes, or to update some summary information once an hour.
A cron job will invoke a URL, using an HTTP
GET request, at a given time of
day. An HTTP request invoked by cron can run for up to 60 minutes, but is
subject to the same limits as other HTTP requests.
Free applications can have up to 20 scheduled tasks. Paid applications can have up to 250 scheduled tasks.
cron.yaml file in the
root directory of your
configures scheduled tasks
for your Python application. The following is an example
cron: - description: "daily summary job" url: /tasks/summary schedule: every 24 hours - description: "monday morning mailout" url: /mail/weekly schedule: every monday 09:00 timezone: Australia/NSW - description: "new daily summary job" url: /tasks/summary schedule: every 24 hours target: beta
The syntax of
cron.yaml is the YAML format. For more information about
this syntax, see the YAML website for more information.
cron.yaml file consists of a number of job definitions. A job
definition must have a
url and a
schedule. You can also optionally specify a
The description is visible in the Cloud Platform Console
and the development server's admin interface.
url field specifies a URL in your application that will be
invoked by the Cron Service. The
format of the schedule field is covered in
The Schedule Format.
timezone should be the name of a standard
zoneinfo time zone
name. If you don't specify a timezone, the
schedule will be in UTC (also known as GMT).
target string is prepended to your app's hostname. It is
usually the name of a service. The cron job will be routed to the default
version of the named service. Note that if the default version of the service
changes, the job will run in the new default version.
If there is no service with the name assigned to
target, the name is assumed
to be an app version, and App Engine will attempt to route the job to that
version. For more information about routing, see How Requests are
If you use a dispatch file,
your job might be re-routed. For example, given the following
dispatch.yaml files, the job will run in
service2, even though its
cron: - description: "test dispatch vs target" url: /tasks/hello_service2 schedule: every 1 mins target: service1
dispatch: - url: '*/tasks/hello_service2' service: service2
The schedule format
Cron schedules are specified using a simple English-like format.
The following are examples of schedules:
every 12 hours every 5 minutes from 10:00 to 14:00 every day 00:00 every monday 09:00 2nd,third mon,wed,thu of march 17:00 1st monday of sep,oct,nov 17:00 1 of jan,april,july,oct 00:00
If you don't need to run a recurring job at a specific time, but instead only need to run it at regular intervals, use the form:
every N (hours|mins|minutes) ["from" (time) "to" (time)]
The brackets are for illustration only, and quotes indicate a literal.
- N specifies a number.
- hours or minutes (you can also use mins) specifies the unit of time.
- time specifies a time of day, as HH:MM in 24 hour time.
By default, an interval schedule starts the next interval after the last job has completed. If a from...to clause is specified, however, the jobs are scheduled at regular intervals independent of when the last job completed. For example:
every 2 hours from 10:00 to 14:00
This schedule runs the job three times per day at 10:00, 12:00, and 14:00, regardless of how long it takes to complete. You can use the literal "synchronized" as a synonym for from 00:00 to 23:59:
every 2 hours synchronized
If you want more specific timing, you can specify the schedule as:
("every"|ordinal) (days) ["of" (monthspec)] (time)
- ordinal specifies a comma separated list of "1st", "first" and so forth (both forms are ok)
- days specifies a comma separated list of days of the week (for example, "mon", "tuesday", with both short and long forms being accepted); "every day" is equivalent to "every mon,tue,wed,thu,fri,sat,sun"
- monthspec specifies a comma separated list of month names (for example, "jan", "march", "sep"). If omitted, implies every month. You can also say "month" to mean every month, as in "1,8,15,22 of month 09:00".
- time specifies the time of day, as HH:MM in 24 hour time.
If a cron job's request handler returns a status code that is not in the range
200–299 (inclusive) App Engine considers the job to have failed. By default,
failed jobs are not retried. You can cause failed jobs to be retried by
retry_parameters block in your configuration file.
cron: - description: "retry demo" url: /retry schedule: every 10 mins retry_parameters: min_backoff_seconds: 2.5 max_doublings: 5
Cron retries syntax
The retry parameters are described in the table below.
The maximum number of retry attempts for a failed cron job not to exceed
'5'. If specified with
The time limit for retrying a failed cron job, measured from when the
cron job was first run. The value is a number followed by a unit of
time, where the unit is s for seconds, m for minutes, h for hours, or d
for days. For example, the value 5d specifies a limit of five days after
the cron job's first execution attempt. If specified with
||The minimum number of seconds to wait before retrying a cron job after it fails.|
||The maximum number of seconds to wait before retrying a cron job after it fails.|
The maximum number of times that the interval between failed cron job
retries will be doubled before the increase becomes constant. The
Validating cron requests
You might want to validate that requests to your cron URLs are coming from App Engine and not from another source. You can do so by validating an HTTP header and the source IP address for the request:
Requests from the Cron Service will also contain a HTTP header:
X-Appengine-Cronheader is set internally by Google App Engine. If your request handler finds this header it can trust that the request is a cron request. The
X-headers are stripped by App Engine when they originate from external sources so that you can trust this header.
Google App Engine issues cron requests from the IP address
Cron and app versions
target parameter has been set for a job, the request is sent to the
specified version. Otherwise Cron requests are sent to the default version of
Uploading cron jobs
To upload your cron jobs, you must specify the
cron.yaml as a parameter
to the following gcloud command:
gcloud app deploy cron.yaml
Deleting cron jobs
To delete all cron jobs, change the
cron.yaml file to just contain:
Displaying job information
You can display the parsed version of your cron jobs, including the times the
jobs will run, using the
appcfg.py cron_info command.
appcfg.py cron_info will not correctly compute schedules if a
timezone different than UTC is specified.
Cron support in the Google Cloud Platform Console
The Cloud Platform Console Task queues page has a tab that shows the tasks that are running cron jobs.
You can also visit the Logs page see when cron jobs were added or removed.