How the SugarCRM Scheduler Actually Runs
SugarCRM does not run background work on its own. Everything you see under Admin → Scheduler — outbound campaign emails, inbound email monitoring, report caching, workflow processing, the reminder and notification jobs, and the pruning of old database tracking data — is dispatched by a single PHP script called cron.php that lives in your web root. When that script is executed, Sugar reads the schedulers table, decides which jobs are due based on each job's interval, and pushes them into the job_queue table. A queue runner then processes those pending entries one at a time until the queue is empty or the execution window closes.
On a dedicated server an administrator would add a system cron line that calls cron.php every minute. On Hostiso's managed shared platform you do not have root or raw crontab access, but you do not need it. Both cPanel Jupiter and DirectAdmin Evolution expose a per-account cron manager that writes to your own user crontab, and that is the correct and only place to schedule Sugar's background processing. The script must be invoked as the same Unix user that owns your files, which is exactly what the panel cron does, so there is no ownership mismatch to fight later.
The most common reason a fresh SugarCRM install "does nothing" — reminders never fire, campaigns sit in queued status, inbound email folders never sync — is simply that this cron entry was never created. Sugar deliberately only advances the scheduler when cron.php is called, so without that heartbeat the job_queue never moves. The second most common cause is that the cron exists but calls PHP in a way that triggers a URL-based security guard inside Sugar, which refuses to run the scheduler from a browser-style request and exits quietly.
Configuring the Cron Job in cPanel and DirectAdmin
SugarCRM's scheduler is designed to be driven on a one-minute cadence. Running it every minute does not mean every job fires every minute; each job keeps its own interval, and Sugar skips anything that is not yet due. The frequent call simply guarantees that due jobs are picked up promptly.
The command must run the CLI PHP binary, not the web request handler, and it must set the working directory to the Sugar root so relative includes resolve. Find your CLI PHP path first. In cPanel you can confirm the active version under MultiPHP Manager, and on CloudLinux the per-account selector lives under Select PHP Version. A reliable, version-agnostic command that respects the CloudLinux PHP Selector is:
cd /home/USERNAME/public_html; /usr/local/bin/php -f cron.php > /dev/null 2>&1Replace USERNAME with your account user and adjust the path if Sugar lives in a subfolder such as /home/USERNAME/public_html/crm. The /usr/local/bin/php alias on CloudLinux resolves to whatever version you selected in the panel, so you do not have to hardcode a versioned binary like ea-php82.
In cPanel Jupiter, open Advanced → Cron Jobs. Under Common Settings choose Once Per Minute (* * * * *), paste the command into the Command field, and click Add New Cron Job. In DirectAdmin Evolution, go to Advanced Features → Cron Jobs, set all five time fields (minute, hour, day, month, weekday) to *, enter the same command, and save. DirectAdmin may email cron output to your account by default, so keeping the > /dev/null 2>&1 redirect prevents your inbox from filling with per-minute messages.
After the cron is live, tell Sugar to trust CLI execution. Open Admin → Scheduler and read the on-screen instructions block at the bottom; it shows the exact user context Sugar expects. Then, using File Manager, edit config_override.php in the Sugar root and add the following line so the scheduler accepts command-line runs from your account user:
$sugar_config['cron']['cron_runner'] = array('allowed_cron_users' => array('USERNAME'));Set USERNAME to the Unix account that owns the files — the same one in the cron command. If this allow-list is wrong, Sugar prints a message that the current user is not allowed to run the scheduler and exits without processing anything.
Diagnosing and Clearing Stuck Jobs
When reminders or campaigns stop even though the cron is scheduled, the problem is almost always inside the job_queue table or in file permissions, not in the cron itself. Start by confirming the cron truly executes. Edit the cron command temporarily to log instead of discarding output:
cd /home/USERNAME/public_html; /usr/local/bin/php -f cron.php >> /home/USERNAME/sugarcron.log 2>&1Wait two or three minutes, then open sugarcron.log in File Manager. A clean run is usually silent or reports the jobs it dispatched. If you see a fatal error about a missing class or a permission-denied write, that points directly at the cause. PHP warnings here frequently come from a cache the scheduler cannot write; Sugar stores compiled templates and session-like state under cache/, and if the ownership or mode on that directory is off, job execution dies mid-run and leaves entries flagged as running forever.
Next inspect the queue in phpMyAdmin. Select your Sugar database, open the job_queue table, and sort by date_entered descending. Jobs stuck in status = 'running' from hours ago are orphans — a previous execution was killed by the PHP time limit before it could mark them done, and Sugar will not re-dispatch a job it believes is already running. Reset them with a scoped UPDATE run from the phpMyAdmin SQL tab:
UPDATE job_queue
SET status = 'done', resolution = 'failure'
WHERE status = 'running'
AND date_entered < (NOW() - INTERVAL 1 HOUR);This clears the deadlock so the next cron pass can re-queue those schedulers normally. If jobs pile up as queued but never advance, the queue runner is timing out. Because you cannot edit php.ini globally, raise the limits for CLI and Sugar through a .user.ini file in the Sugar root and the Sugar config. Add to .user.ini:
max_execution_time = 120
memory_limit = 512MThen set a matching ceiling in config_override.php so Sugar's own job runner does not cut itself short:
$sugar_config['cron']['max_cron_jobs'] = 10;
$sugar_config['cron']['max_cron_runtime'] = 60;
$sugar_config['cron']['min_cron_interval'] = 30;A max_cron_runtime of 60 seconds keeps each pass comfortably under the one-minute cadence, and max_cron_jobs caps how many queue entries a single run will chew through so a heavy campaign send cannot monopolize the window. If inbound email jobs in particular hang, verify the mailbox credentials under Admin → Inbound Email separately, since a timed-out IMAP connection blocks the whole runner until PHP kills it.
Verifying Execution and Ongoing Maintenance
Confirm real throughput rather than assuming the cron works. In Admin → Scheduler, open an individual scheduler such as Process Workflow Tasks or Run Nightly Process Bounced Campaign Emails and check its Last Run timestamp. A value updating within the last few minutes proves the full chain — cron, CLI PHP, allow-list, and queue runner — is healthy. If the list of active schedulers is empty, use the Create Default Schedulers action to repopulate them; a database restore or partial migration sometimes drops these rows.
Keep the job_queue table from growing without bound. Sugar ships a cleanup scheduler, but on a busy CRM you can also prune manually in phpMyAdmin by deleting completed rows older than a week, which keeps scheduler dispatch queries fast and avoids the symptoms covered in our guide on configuring schedulers and fixing stuck jobs on shared hosting, since SuiteCRM inherits the same queue architecture from Sugar. A reasonable cleanup query is:
DELETE FROM job_queue
WHERE status = 'done'
AND date_entered < (NOW() - INTERVAL 7 DAY);Finally, once everything is confirmed, change the cron command back to the /dev/null redirect so you are not writing a log every minute, or rotate sugarcron.log periodically through File Manager. Document the exact command, the PHP version selected in the panel, and the allow-list user somewhere in your own notes. When a PHP version change through MultiPHP Manager or the CloudLinux selector later alters the resolved binary, the version-agnostic /usr/local/bin/php path keeps the scheduler running without any further edits.