Follow Us

  • erpgap-icon
  • erpgap-icon
  • erpgap-icon

Odoo 19 Cron Jobs: Batch Processing That Actually Works

How the new cron mechanism in Odoo 19 safely processes large workloads without timeouts

odoo 19.0 crons / scheduled actions

Pulling data in pages of 50/100/250 was never the hard part. The hard part was cron scheduling certainty.

In older versions, if a cron timed out mid-run, it would usually only continue on the next scheduled execution. That meant:

  • If you scheduled the job twice a day, a timeout at 09:00 could mean “continue at 21:00”… not great.
  • To compensate, many teams scheduled the job every hour (or even every few minutes) because they expected interruptions.
  • Or you wrote custom logic to manipulate nextcall / force follow-up runs.

Odoo 19 introduces the missing primitive: a way for a cron to report progress in a way the scheduler understands, so Odoo can decide “do I need to keep running soon to finish?”

That primitive is:

  • ir.cron._commit_progress()

The real feature: scheduling certainty, not paging

The real win is: you can keep a sensible schedule (e.g., twice a day) and still be confident the job will complete.

Because if the job can’t finish within a single execution window, it can:

  • checkpoint progress
  • stop cleanly
  • and Odoo will re-trigger it quickly until it’s done

So you get:

  • “run twice a day” as your intent
  • “continue until complete” as actual behavior

The new primitive: _commit_progress()

This is the method that changes the game:

@api.model
def _commit_progress(
    self,
    processed: int = 0,
    *,
    remaining: int | None = None,
    deactivate: bool = False,
) -> float:
    """
    Commit and log progress for the batch from a cron function.

    The number of items processed is added to the current done count.
    If you don't specify a remaining count, the number of items processed
    is subtracted from the existing remaining count.

    If called from outside the cron job, the progress function call will
    just commit.

    :param processed: number of processed items in this step
    :param remaining: set the remaining count to the given count
    :param deactivate: deactivate the cron after running it
    :return: remaining time (seconds) for the cron run
    """

What it gives you:

  • A standard way to say: “I processed X items”
  • Optionally: “I still have Y remaining”
  • A return value (time_left) so you can stop gracefully before timeout
  • Most importantly: it enables Odoo to know whether the cron should keep going soon or can wait until the next planned schedule

How this looks in a Shopify order pull cron

1) Start the run by declaring the workload (remaining)

The point isn’t “counting is fancy” — it’s giving Odoo the signal: this job has work to finish.

remaining_count = self._get_shopify_orders_count(api_url, access_token, since_id, start_date)

if remaining_count == 0:
    _logger.info("No orders to pull from Shopify")
    return

self.env['ir.cron']._commit_progress(remaining=remaining_count)

2) Process one page (your existing paging stays)

orders = self._fetch_shopify_orders(api_url, access_token, since_id, start_date, page_limit)
if not orders:
    break

3) After each page, checkpoint progress (processed)

This is the new part that turns “paging” into “guaranteed completion”.

time_left = self.env['ir.cron']._commit_progress(processed=len(orders))

4) If time is running out, stop cleanly — and let Odoo continue soon

if not time_left:
    _logger.info("Cron approaching timeout, stopping gracefully")
    return

Why this changes how you schedule crons

Before Odoo 19

  • If you scheduled the cron twice a day and it timed out, it might not continue for hours.
  • So you scheduled it every hour (or more frequently), or you hacked the scheduling logic.

With Odoo 19

  • You can schedule it for business reasons (“twice a day”).
  • And still rely on Odoo to “finish the job” by re-running quickly when needed, because the cron itself reports progress via _commit_progress().

In practice, that means fewer cron runs overall, less noise, and far fewer “why didn’t it finish?” incidents.

Final takeaway

Coding crons always has some challenges but with this new method we can say:

“I’m not done yet — keep me running soon until completion.”

Odoo 19 Cron Jobs: Batch Processing That Actually Works YouTube cover image

Taking your business to the next level

BOOK A FREE 30-min CONSULTATION erpgap-icon

erpgap-icon Official Odoo Partner

Diogo Duarte
3 min read May 5, 2026

Subscribe To Our Newsletter

*/}