Odoo ir.cron Scheduler Helper

See exactly when your Scheduled Action will run — and what happens when the worker falls behind.

Configure the schedule

Every
 
Starting at (UTC)
Number of runs

Next scheduled runs

  1. 12024-01-01 03:00 UTC
  2. 22024-01-02 03:00 UTC
  3. 32024-01-03 03:00 UTC
  4. 42024-01-04 03:00 UTC
  5. 52024-01-05 03:00 UTC
  6. 62024-01-06 03:00 UTC
  7. 72024-01-07 03:00 UTC
  8. 82024-01-08 03:00 UTC

In plain English

Runs every day, starting 2024-01-01 03:00 UTC, indefinitely. If the worker falls behind, missed runs are skipped — it only runs once when it catches up.

Catch-up simulator

If the worker were down until this moment, here's what would happen when it resumes:

Worker resumes at (UTC)
Missed trigger(s)
4
Executions on resume
1
New next call
2024-01-05 03:00 UTC

doall is disabled: the 4 missed triggers are skipped — the job runs exactly once when the worker resumes, and the schedule jumps forward to the next regular slot.

ir.cron record

Record id
Name
Model XML ID
Python code
record
<record id="ir_cron_my_scheduled_action" model="ir.cron">
    <field name="name">My Scheduled Action</field>
    <field name="model_id" ref="model_res_partner"/>
    <field name="state">code</field>
    <field name="code">model.my_method()</field>
    <field name="interval_number">1</field>
    <field name="interval_type">days</field>
    <field name="nextcall">2024-01-01 03:00:00</field>
    <field name="numbercall">-1</field>
    <field name="doall" eval="False"/>
    <field name="active" eval="True"/>
</record>
Advertisement

The basics

What is ir.cron?

ir.cron is the Odoo model behind Scheduled Actions (Settings > Technical > Automation) — the built-in job scheduler that runs a Python method or server action on a repeating interval. Unlike Linux cron, there is no five-field expression: a schedule is just an interval anchored at a timestamp.

interval_number: 1 how many
interval_type: 'days' unit
nextcall: 2024-01-01 03:00 anchor (UTC)

Getting started

How to use this tool

Configure the schedule above — interval, starting time, number of runs and doall — and everything below updates live: the next scheduled runs, a plain-English explanation, a simulator showing exactly what happens if the worker falls behind, and a ready-to-paste <record model="ir.cron"> XML snippet for your module's data file.

The #1 confusion

Why ir.cron is not Linux cron

Linux cron expressions (* * * * *) encode minute, hour, day-of-month, month and day-of-week independently, so you can say "every Monday at 9am" directly. ir.cron has no such expression — only interval_number + interval_type, anchored at nextcall. After each run Odoo adds the interval to that same value, which is why the schedule preserves its time-of-day (and weekday, for weekly schedules) as long as the worker keeps up — and why it drifts later when the worker falls behind.

Reference

ir.cron fields

The fields that define a Scheduled Action's timing.

interval_number

how many units of interval_type between runs — a positive integer.

interval_type

minutes, hours, days, weeks, or months — that's the entire vocabulary, no day-of-week or day-of-month expression.

nextcall

the next scheduled execution, stored as naive UTC. After each run, Odoo adds the interval to this same value again.

numbercall

-1 for unlimited, or a countdown of remaining runs. Odoo decrements it after each run and deactivates the record at 0.

doall

if the worker falls behind, run once per missed trigger (true) or skip the missed ones and run just once (false).

priority

when multiple crons are due at the same moment, lower priority values run first.

Examples

Common ir.cron configurations

Field snippets you can paste into a scheduled action's data record.

<field name="interval_number">15</field>
<field name="interval_type">minutes</field>

runs every 15 minutes, indefinitely.

<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="nextcall">2024-01-01 03:00:00</field>

runs once a day, at whatever time nextcall specifies — here, 03:00 UTC.

<field name="interval_number">1</field>
<field name="interval_type">weeks</field>

runs weekly, on nextcall's weekday — there is no separate 'day of week' field.

<field name="interval_number">1</field>
<field name="interval_type">months</field>
<field name="nextcall">2024-01-31 00:00:00</field>

runs monthly on the 31st — until a shorter month clamps it to the 28th/29th, after which it stays on that day (see FAQ).

<field name="numbercall">1</field>

a one-off delayed task: runs exactly once, at nextcall, then deactivates itself.

<field name="doall" eval="False"/>

the common choice for idempotent, 'just keep it current' jobs — skip catching up on every missed run after downtime.

FAQ

Frequently asked questions

What is ir.cron in Odoo?

ir.cron is the model behind Settings > Technical > Automation > Scheduled Actions — Odoo's built-in job scheduler. Each record defines a Python method or server action to run on a repeating interval.

Is ir.cron the same as Linux cron?

No. Linux cron uses five-field expressions (minute, hour, day of month, month, day of week) that can express things like "every Monday at 9am". ir.cron only has interval_number + interval_type (minutes/hours/days/weeks/months) anchored at nextcall — there is no independent day-of-week or day-of-month constraint.

How does Odoo compute the next nextcall after a run?

It adds interval_number/interval_type to the current nextcall (not to "now") — that preserves the time-of-day a job runs at, as long as the worker keeps up. If the worker falls behind, the actual execution time drifts later.

What does doall actually do?

It only matters when the worker is late and one or more trigger times have already passed. With doall enabled, the job runs once for every missed trigger, back-to-back, when the worker resumes. With it disabled, the missed triggers are skipped and the job runs exactly once.

What happens when numbercall reaches 0?

Odoo decrements numbercall after every successful run (unless it's -1, meaning unlimited). When it hits 0, the record's active field is set to False and the schedule stops.

Why did my monthly cron move from the 31st to the 28th?

interval_type: months adds a calendar month the same way Python's dateutil.relativedelta does: if the target month is shorter, the day clamps to its last day (Jan 31 + 1 month -> Feb 28). That clamped day then sticks — the next addition uses Feb 28 as its base, landing on Mar 28, not Mar 31.

Can I schedule "every Monday at 9am" with ir.cron?

Set interval_type to weeks, interval_number to 1, and nextcall to any Monday at 09:00 — every run after that lands on the same weekday and time, since nextcall's own weekday becomes the anchor. You can't express "Monday and Thursday" in a single record, though; that needs two Scheduled Actions.

What does the priority field do?

When multiple Scheduled Actions are due at the same time, Odoo processes lower priority values first. It has no effect on when a job is due — only the order ties are broken.