Odoo ir.cron Scheduler Helper
See exactly when your Scheduled Action will run — and what happens when the worker falls behind.
Configure the schedule
Next scheduled runs
- 12024-01-01 03:00 UTC
- 22024-01-02 03:00 UTC
- 32024-01-03 03:00 UTC
- 42024-01-04 03:00 UTC
- 52024-01-05 03:00 UTC
- 62024-01-06 03:00 UTC
- 72024-01-07 03:00 UTC
- 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:
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="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>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.
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.