Docs · Cron & scheduled tasks
Cron & scheduled tasks
FortPass has a single entry point: run_cron($con) in functions.php. Each task has its own throttle so calling run_cron() more often than needed is harmless — only tasks whose interval has elapsed actually do work.
How it gets triggered
- Cron-on-visit: every request invokes
run_cron()at most every 5 minutes (driven bycron_timesetting). - Manual button in
/admin/dashboard→ "Run cron now". - External crontab (optional):
php /path/to/cron.phpevery N minutes for installs with low traffic.
Tasks
| Task | Interval | What it does |
|---|---|---|
| Monthly reports | Day 1 of each month | monthly_dispatch_reports() sends the security summary email to every eligible user. |
| Breach digest | Every 24h | breach_digest_dispatch() — HIBP fetch → email to users with breach_alerts_basic or breach_alerts_realtime. |
| Emergency processing | Every run | Marks requests with elapsed wait as granted, sends email + encrypted recovery code. |
| Cleanup | Every 5 min (throttled) | cron_cleanup_expired() — reset tokens, login codes, expired emergency invites, PIN attempts, sessions, scan history, cancelled subs, expired trials. |
| Translation worker | Every 60s | cron_process_translations() drains the translation queue. See i18n & auto-translation. |
| New language detection | On startup | cron_detect_new_languages() compares installed langs vs translated_languages_seen setting. |
| Translation orphan sweep | Daily | Removes translation rows whose source object no longer exists. |
Cleanup details
The cleanup pass touches several tables on a 5-minute throttle:
- Reset tokens expired / used > 7d ago.
- Login codes > 1h.
- Expired emergency invitations →
status = 'expired'. - PIN attempts > 30d.
- User sessions inactive > 30d.
- Scan history > 20 per user.
- Cancelled subscriptions with grace period elapsed → downgrade to Free.
- Trials without conversion → Free.
past_due > 7d→ Free.
Forcing a task to run
Each task's last-run timestamp lives in settings with key cron_*_last_run. Setting it to 0 manually forces the next execution:
UPDATE settings SET setting_value='0' WHERE setting_name='cron_monthly_last_run';
The next run_cron() call will fire the monthly dispatch, regardless of the calendar.
Performance
Each task short-circuits if its interval hasn't elapsed (single SELECT per task). A typical run_cron() call with all timers fresh does < 10 queries and returns in < 5 ms. Cron-on-visit overhead is negligible.
FortPass · © 2026 Medel Platforms · medel.es