- ERPNext Scheduler - Implementation
- This skill helps you implement scheduled tasks and background jobs. For exact syntax, see
- erpnext-syntax-scheduler
- .
- Version
-
- v14/v15/v16 compatible
- Main Decision: What Are You Trying to Do?
- ┌─────────────────────────────────────────────────────────────────────┐
- │ SCHEDULER DECISION │
- ├─────────────────────────────────────────────────────────────────────┤
- │ │
- │ Run at fixed intervals or times? │
- │ ├── YES → Scheduler Event (hooks.py) │
- │ │ See: references/workflows.md §1-2 │
- │ │ │
- │ └── NO → Run in response to user action? │
- │ ├── YES → frappe.enqueue() │
- │ │ See: references/workflows.md §3-4 │
- │ │ │
- │ └── NO → Probably neither - reconsider requirements │
- │ │
- └─────────────────────────────────────────────────────────────────────┘
- Scheduler Event vs frappe.enqueue
- Aspect
- Scheduler Event
- frappe.enqueue
- Triggered by
- Time/interval
- Code execution
- Defined in
- hooks.py
- Python code
- Arguments
- None (must be parameterless)
- Any serializable data
- Use case
- Daily cleanup, hourly sync
- User-triggered long task
- Restart behavior
- Runs on schedule
- Lost if worker restarts
- Which Scheduler Event Type?
- ┌─────────────────────────────────────────────────────────────────────┐
- │ SCHEDULER EVENT TYPE │
- ├─────────────────────────────────────────────────────────────────────┤
- │ │
- │ Simple recurring interval? │
- │ ├── Every minute → scheduler_events.cron[" * * * "] │
- │ ├── Hourly → scheduler_events.hourly │
- │ ├── Daily → scheduler_events.daily │
- │ ├── Weekly → scheduler_events.weekly │
- │ └── Monthly → scheduler_events.monthly │
- │ │
- │ Complex schedule (e.g., "weekdays at 9am")? │
- │ └── scheduler_events.cron["0 9 * * 1-5"] │
- │ │
- │ Run after every request? │
- │ └── scheduler_events.all (use sparingly!) │
- │ │
- └─────────────────────────────────────────────────────────────────────┘
- Which Queue?
- Queue
- Timeout
- Use For
- short
- 5 min
- Quick operations (<1 min)
- default
- 5 min
- Standard tasks (1-3 min)
- long
- 30 min
- Heavy processing (>3 min)
- Rule
- Always specify queue explicitly. Default is short . Quick Start: Basic Scheduled Task
myapp/tasks.py
import frappe def daily_cleanup ( ) : """Daily cleanup task - no parameters allowed""" frappe . db . delete ( "Error Log" , { "creation" : ( "<" , frappe . utils . add_days ( None , - 30 ) ) } ) frappe . db . commit ( )
hooks.py
scheduler_events
{ "daily" : [ "myapp.tasks.daily_cleanup" ] } After editing hooks.py: bench migrate Quick Start: Background Job
myapp/api.py
import frappe from frappe import enqueue @frappe . whitelist ( ) def process_documents ( doctype , filters ) : enqueue ( "myapp.tasks.process_batch" , queue = "long" , timeout = 1800 , job_id = f"process_ { doctype } _ { frappe . session . user } " ,
v15+ dedup
doctype
doctype , filters = filters ) return { "status" : "queued" } Critical Rules 1. Scheduler tasks receive NO arguments
❌ WRONG
def my_task ( doctype ) :
Arguments not supported
pass
✅ CORRECT
def my_task ( ) :
Parameterless
doctype
"Sales Invoice"
Hardcode or read from settings
- ALWAYS migrate after hooks.py changes bench migrate
Required to register new scheduler events
- Jobs run as Administrator Scheduler and enqueued jobs run with Administrator permissions. Always commit explicitly.
- Commit after batches, not per record
❌ WRONG - Slow
for doc in docs : doc . save ( ) frappe . db . commit ( )
Commit per record
✅ CORRECT - Fast
for doc in docs : doc . save ( ) frappe . db . commit ( )
Single commit after batch
- Use job_id for deduplication (v15+) enqueue ( . . . , job_id = "unique_identifier" )
Prevents duplicate jobs
Version Differences Aspect v14 v15 v16 Tick interval 4 min 60 sec 60 sec Job dedup job_name job_id job_id Cron support ✅ ✅ ✅ V14 deduplication uses different parameter:
v14
enqueue ( . . . , job_name = "unique_id" )
v15+
enqueue ( . . . , job_id = "unique_id" ) Reference Files File Contents workflows.md Step-by-step implementation patterns decision-tree.md Detailed decision flowcharts examples.md Complete working examples anti-patterns.md Common mistakes to avoid See Also erpnext-syntax-scheduler - Exact syntax reference erpnext-errors-serverscripts - Error handling patterns