Skip to content

scheduling jobs with cron yaml

ludoch edited this page Apr 15, 2026 · 1 revision

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 that 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.

Important: For a cron task to be considered successful it must return an HTTP status code between 200 and 299 (inclusive).

To deploy or update schedules, your account requires one of the following Identity and Access Management roles:

  • Owner
  • Editor

You can set the permission on the IAM page in the Google Cloud console.

About the cron configuration file

A cron.xml file in the WEB-INF directory of your application (alongside app.yaml) configures scheduled tasks for your Java application. The following is an example cron.xml file:

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 cron.xml file consists of definitions for each of your cron jobs. A job definition must have a <url> and a <schedule>. You can also optionally specify a <description>, <timezone>, <target>, and <retry-parameters>:

`<url>`
Required. The URL in your app to which you want the Cron service to send job requests.
`<schedule>`
Required. Defines the schedule of when you want the job to run, see the syntax below.
`<description>`
Optional. Describes your cron job, which is visible from within the Google Cloud console and the local development server's admin interface.
`<timezone>`
Optional. The name of the time zone, or "zoneinfo", that you want to use for your job schedule. If you don't specify a time zone, the schedule uses `UTC`, which is also known as`GMT`.
`<target>`
Optional. The name of a specific service in your app. When `<target>` is specified, the Cron service targets the job request to that service in your app. The job requests are routed to the versions in the specified service that are configured for traffic. Learn how requests are routed.
  Important considerations for `&lt;target&gt;`:

<ul>
  <li>
    If you have <a
    href="/appengine/docs/legacy/standard/java/splitting-traffic">
    traffic splitting</a> enabled, your job requests will not be split
    between the versions that you have configured:
    <ul>
      <li>
        IP address splitting: Job requests from the Cron service are always
        sent from the same IP address and therefore, get routed to the same
        version every time.
      </li>
      <li>
        Cookie splitting: Job requests do not include a cookie with the
        request and therefore, do not get routed to any other versions.
      </li>
    </ul>
  </li>
  <li>
    If you use a <a href="/appengine/docs/standard/java/how-requests-are-routed#routing_with_a_dispatch_file">
    dispatch file</a>, your jobs can get re-routed when the same URL is also
    configured in the `dispatch.yaml`. For example, if the
    `/tasks/hello_service2` URL is defined in both of the
    following `cron.xml` and `dispatch.yaml`
    files, the job requests are sent to `service2`, even though
    `target: service1` is specified:

      `cron.yaml`:

    <pre class="prettyprint lang-yaml">cron:
  • description: "test dispatch vs target" url: /tasks/hello_service2 schedule: every 1 mins target: service1 dispatch.yaml:
dispatch:
- url: '*/tasks/hello_service2'
service: service2
</li>
</ul>
`<retry-parameters>`
Optional. Specifies to rerun failed jobs, see the syntax below.

Specifying retries

If a cron job's request handler returns a status code that is not in the range 200–299 (inclusive) App Engine considers that job to have failed. By default, failed jobs are not retried. You can cause failed jobs to be retried by including a &lt;retry-parameters&gt; block in your configuration file.

Here is a sample cron.yaml file that contains a single cron job configured to retry up to five times with a starting backoff of 2.5 seconds that doubles each time.

cron:
- description: "retry demo"
  url: /retry
  schedule: every 10 mins
  retry_parameters:
    job_retry_limit: 5
    min_backoff_seconds: 2.5
    max_doublings: 5

Cron retries syntax

The retry parameters are described in the table below.

Element Description
`<job-retry-limit>` An integer that represents the maximum number of retry attempts for a failed cron job. The minimum value is `0`, and the maximum value is `5`. If you also specify `<job-age-limit>`, App Engine retries the cron job until it reaches both limits. The default value for `<job-retry-limit>` is `0`.
`<job-age-limit>` The time limit for retrying a failed cron job, measured from when the cron job first runs. 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 you also specify `<job-retry-limit>`, App Engine retries the cron job until it reaches both limits.
`<min-backoff-seconds>` The minimum number of seconds to wait before retrying a cron job after it fails.
`<max-backoff-seconds>` The maximum number of seconds to wait before retrying a cron job after it fails.
`<max-doublings>` The maximum number of times that the interval between failed cron job retries will be doubled before the increase becomes constant. The constant is: 2**(`max_doublings` - 1) * `min_backoff`.

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 contain the following HTTP header:

      X-Appengine-Cron: true
    

    This and other headers are set internally by App Engine. If a client sends these headers, they are removed from the request.

  • App Engine issues Cron requests from the IP address 0.1.0.2. For Cron jobs created with older gcloud versions (earlier than 326.0.0), Cron requests will come from 0.1.0.1.

    Note: If you define a firewall, you must set a firewall rule for IP address 0.1.0.2 or 0.1.0.1 to allow your app to receive requests from the Cron service.

In Jetty or Tomcat, you might perform this validation in a filter.

Uploading cron jobs

To upload your cron jobs, you must specify the cron.xml as a parameter to the following gcloud command:

gcloud app deploy cron.xml

Deleting cron jobs

To delete all cron jobs, change the cron.xml file to just contain:

cron:

Cron support in the Google Cloud console

You can check on scheduled cron jobs on the Google Cloud console Cron jobs page.

You can also visit the Logs page see when cron jobs were added or removed.

Clone this wiki locally