Odoo automatically runs background tasks called scheduled actions (crons). These are used for operations such as:
- Sending scheduled or automated emails
- Cleaning temporary and outdated data
- Synchronizing integrations or external systems
Sometimes, you may need to check which scheduled actions are currently running or stuck.
Here’s how to do it using Odoo logs and PostgreSQL.
Check Through Logs
Odoo logs every scheduled action when it starts and ends. Example:
2025-11-02 03:04:27,384 23313 INFO my_test_db odoo.addons.base.models.ir_cron: Job 'My Test Scheduled Action' (100) starting
2025-11-02 03:04:28,398 23313 INFO my_test_db odoo.addons.base.models.ir_cron: Job My Test Scheduled Action' (100) done
Use this in your server terminal:
awk '
BEGIN { IGNORECASE=1 } # make matches case-insensitive
/odoo\.addons\.base\.models\.ir_cron: Job/ {
if (match($0, /\(([0-9]+)\)/, n)) id=n[1]
if ($0 ~ / start(ing|ed)( |$)/) start[id]=$0 # matches "starting" or "started"
if ($0 ~ / done( |$)/) delete start[id] # finished
}
END {
for (i in start) print start[i]
}
' /var/log/odoo/odoo.log
Note: Replace /var/log/odoo/odoo.log with the exact path to your Odoo log file.
Common locations: /var/log/odoo/odoo-server.log, /var/log/odoo/odoo.log, or a custom path set in /etc/odoo/odoo.conf under logfile.
Example Output:
2025-11-02 03:04:27,384 23313 INFO my_test_db odoo.addons.base.models.ir_cron: Job 'My Test Scheduled Action' (100) starting
Check Through SQL (From psql)
Connect to your PostgreSQL database the way you prefer. I’ll just mention two common methods below:
- psql -U <user_name> -d <database_name> -h <host> -p <port>
- sudo -u postgres psql <database_name>
Run the following SQL block to check which scheduled actions are currently executing.
DO $$
DECLARE r RECORD;
BEGIN
RAISE NOTICE 'Running scheduled actions:';
FOR r IN SELECT id, cron_name FROM ir_cron LOOP
BEGIN
PERFORM 1 FROM ir_cron WHERE id = r.id FOR NO KEY UPDATE NOWAIT;
RAISE EXCEPTION 'release-lock';
EXCEPTION
WHEN lock_not_available THEN
RAISE NOTICE ' - % (id=%)', r.cron_name, r.id;
WHEN OTHERS THEN
NULL;
END;
END LOOP;
END$$;
What it does:
- Checks each scheduled action in the ir_cron table.
- If a row is locked, that means the cron is currently running.
- Prints the names and IDs of the active jobs.
- All locks are released immediately.
Example output:
NOTICE: Running scheduled actions:
NOTICE: - My Test Scheduled Action (id=100)
To exit PostgreSQL:
\q