Setting up the cron job
A few POS features work quietly in the background — emailing your scheduled reports, taking automatic backups, warning you about low stock. For any of that to happen, your server needs to poke the POS once a minute. That poke is called a cron job, and you set it up once, in about two minutes.
What a cron job is
A cron job is your server's alarm clock. You tell it "run this command every minute", and from then on it does — day and night, whether or not anyone is logged in.
The POS uses a single one. Every minute the server runs one short command; the POS looks at its to-do list, sees whether anything is due right now, and either does it or goes straight back to sleep. When nothing is due — which is most minutes — it costs practically nothing.
Not one per feature. This single entry drives every background task the POS has — now and after future updates. Set it up once and forget about it.
What needs it
The POS works perfectly well without a cron job for selling, stock and reports you run yourself. What stops working is everything that's meant to happen on its own:
| Feature | Without the cron job |
|---|---|
| Scheduled reports | Never sent. Schedules can be created, but nothing arrives by email. |
| Automatic backups | Never taken. Manual backups still work — but only if you remember. |
| Low-stock alerts | No daily bell notification when items drop to their reorder level. |
| Update checks | No "a new version is available" banner unless you check manually. |
| Dashboard & trend figures | Still correct, but recalculated live each time — slower on big catalogs. |
| Online refund retries | A card refund that failed because the gateway was down isn't retried automatically. |
Start here: Settings → Scheduler
Before you go anywhere near your hosting panel, open Settings → Scheduler in the POS. It does most of this page's work for you:
- It tells you whether the cron job is already running — a plain Working, Working, but slowly, Cron job not set up or Stopped, with the time it last ran.
- It shows the exact command to paste, already filled in with your installation's real folder path — nothing to work out by hand. There's a Copy button next to it.
- It offers a second version of the command with the full path to PHP, for hosts where the plain one doesn't run.
- It has a Test button that watches for the next run and tells you within a minute or two whether your cron job is really firing.
- It has a fallback for hosts that don't offer cron at all — see no cron on your hosting?
The rest of this page explains what that command means and where to paste it in the common hosting panels.
The command
This is the whole thing. It's the same on every host — only the folder path and the word php may need adjusting for yours, and Settings → Scheduler has already filled the path in for you.
cd /home/username/public_html && php artisan schedule:run >> /dev/null 2>&1
Read left to right, it says: go into the folder where the POS is installed, run its scheduler, and throw away any output so your inbox doesn't fill up. Three things in it are yours to fill in:
| Part | What to put |
|---|---|
/home/username/public_html | The folder your POS files are in — the one containing artisan and the public folder. Settings → Scheduler shows yours; or see finding your paths. |
php | Usually fine as-is. If your host runs several PHP versions, use the full path to PHP 8.2+ instead — again, see finding your paths. |
>> /dev/null 2>&1 | Leave it. It silences the output. Drop it temporarily if you're testing and want to see errors. |
And the schedule itself — "every minute" — is written as five stars:
* * * * *
│ │ │ │ │
│ │ │ │ └─ day of week (0–6)
│ │ │ └─────── month (1–12)
│ │ └───────────── day of month (1–31)
│ └─────────────────── hour (0–23)
└───────────────────────── minute (0–59)
All stars means "every value" — so, every minute of every hour of every day. In most control panels you don't type the stars at all; you pick Once per minute from a dropdown.
cPanel, step by step
The most common setup on shared hosting.
-
Open Cron Jobs
Log in to cPanel and, under Advanced, click Cron Jobs. (Use the panel's search box if you can't spot it.)
-
Set the schedule to every minute
Under Add New Cron Job, open Common Settings and choose Once Per Minute (* * * * *). The five boxes below fill themselves in.
-
Paste the command
In the Command box, paste the command from above, with your own folder path in place of
/home/username/public_html. -
Add the cron job
Click Add New Cron Job. It appears in the list below and starts running within a minute. That's it.
-
Stop the email notifications (optional)
cPanel emails you the output of every run by default. Clear the Cron Email field at the top of the page, or your inbox will get 1,440 messages a day.
Plesk, step by step
-
Open Scheduled Tasks
Go to Websites & Domains → your domain → Scheduled Tasks, then Add Task.
-
Choose "Run a command"
Set Task type to Run a command. In Command, enter the full path to PHP followed by
artisan schedule:run, and set the working directory to your POS folder if Plesk offers the option. -
Run it every minute
Set Run to Cron style and enter
* * * * *. -
Test, then switch notifications off
Use Run Now to check it doesn't error, set Notify to Do not notify, then OK to save.
DirectAdmin & other panels
Every panel has the same two boxes — when and what — under a name like Cron Jobs, Scheduled Tasks or Task Scheduler. In DirectAdmin it's Advanced Features → Cronjobs. Set the five timing fields to * and paste the same command. If you genuinely can't find it, send your host's support team this line: "Please add a cron job that runs php artisan schedule:run every minute in my POS folder." — they do this daily.
VPS or dedicated server (SSH)
If you have terminal access, edit the crontab of the user that owns the site files:
crontab -e
Add this line at the end, save, and exit:
* * * * * cd /var/www/pos && /usr/bin/php artisan schedule:run >> /dev/null 2>&1
Confirm it saved with crontab -l.
Use the site's own user, not root. A cron running as root can create log and cache files the web server then can't write to, which breaks the POS in confusing ways. If in doubt, match the user that owns your POS folder.
No cron on your hosting?
A few budget plans offer no cron job at all — only "open this web address on a schedule". The POS has a fallback for exactly that case, in Settings → Scheduler, at the bottom of the page.
-
Generate a cron URL
Click Generate cron URL. You get a private web address unique to your shop. Until you do this, the address doesn't exist at all — nothing is exposed on a normal install.
-
Point something at it every minute
Use your host's "fetch a URL on a schedule" feature, or a free external service such as cron-job.org. The page also gives you a
wgetversion if your panel wants a command rather than a link. -
Check the status turns green
Come back to Settings → Scheduler after a minute or two — the status at the top should say the scheduler is working.
Treat that URL like a password. Anyone who has it can trigger your scheduled tasks — it doesn't expose any of your data, but don't publish it. If it ever leaks, generate a new one and the old address stops working immediately.
Use a real cron job if your host offers one. A URL ping depends on an outside service still being up and still remembering you. The proper cron job doesn't.
Finding your folder and PHP paths
The folder path
You need the folder that contains the file called artisan — the same folder you uploaded during installation. In cPanel's File Manager, open that folder and read the path shown at the top; it usually looks like /home/username/public_html, or /home/username/public_html/pos if you installed into a subfolder. Over SSH, cd into it and run pwd.
Point at the app folder, not the public folder. artisan sits one level above public. If your cron says .../public_html/public, it will fail every minute with "Could not open input file: artisan".
The PHP path
Plain php works on most hosts. But many shared hosts keep several PHP versions installed and the default one for cron can be older than the one your website uses — and the POS needs PHP 8.2 or newer. If you hit that, use the full path instead. Common ones:
| Host type | Typical PHP path |
|---|---|
| cPanel (EasyApache) | /opt/cpanel/ea-php82/root/usr/bin/php |
| CloudLinux / LiteSpeed | /usr/local/bin/ea-php82 or /opt/alt/php82/usr/bin/php |
| Plesk | /opt/plesk/php/8.2/bin/php |
| Ubuntu / Debian VPS | /usr/bin/php or /usr/bin/php8.2 |
Not sure which? Your host's PHP selector page normally shows the exact path, and support will tell you in a one-line reply. Over SSH, which php and php -v answer it in a second.
How daily tasks behave
Daily work such as scheduled backups uses the configured company/store timezone. A task claims its eligible window before running, so frequent cron ticks do not start overlapping copies. If a shared-host cron misses the opening minute and returns later in the allowed window, the task can catch up once rather than disappearing for the day.
The Scheduler page records heartbeat and task-run evidence. A manual backup or other manual action does not pretend that its scheduled version ran. Failed or interrupted work remains visible for investigation instead of retrying blindly every minute.
Checking that it works
-
Open Settings → Scheduler and press "Test my cron job"
This is the direct answer, and it takes under a minute. The page watches for your server to run the scheduler and turns green the moment it does. It never runs anything itself — so a pass is proof that your cron job fired, not just that the POS is alive.
-
Read the status at the top of that page
Even without running a test, the page always shows one of: Working, Working but slowly (your host limits how often cron may run — usually fine), Cron job not set up, or Stopped. Settings → System Health repeats the same verdict alongside the other install checks.
-
If the test times out, look at the output
Temporarily remove
>> /dev/null 2>&1from the end of the command so the server emails you what the run printed. The error message is usually self-explanatory — see the table below. Put it back once fixed. -
End-to-end proof (optional)
Create a scheduled report to your own address a few minutes ahead and wait for it to land. This also exercises your email settings — use Run now first to rule email out.
Common problems
| What you see | What it means |
|---|---|
Could not open input file: artisan | The folder path is wrong — most often it points at the public folder instead of the one above it. |
php: command not found | Cron can't find PHP. Use the second command on Settings → Scheduler — the one with the full path to PHP already filled in. |
| Status says Working, but slowly | Your cron is alive but running less often than every minute — usually a host-imposed limit. Backups and reports still go out, just a few minutes late. Nothing to fix unless you set it to hourly yourself. |
| Status says Stopped | It worked before and has since quit. Check the cron job still exists in your panel — server migrations and panel resets are the usual culprits. |
| "requires PHP 8.2" or a syntax error | Cron is using an older PHP than your website. Again, full path to the newer binary. |
| Nothing at all happens | Check the job is actually saved and enabled in your panel, and that the schedule is * * * * * — not hourly or daily. |
| Hundreds of emails from your server | Normal behaviour, wrong setting. Clear the cron email address in your panel and keep >> /dev/null 2>&1 on the command. |
| Reports arrive at the wrong time | The server clock or the POS timezone. Set your timezone under Settings → Regional. |
| Backups run but reports don't | Cron is fine — it's email. Check your SMTP settings in Settings. |
Tips & best practices
- Do it straight after installing. It takes two minutes and it's the difference between backups that happen and backups you meant to take.
- Every minute is the right frequency. It's deliberately cheap. Don't be tempted to "save resources" by making it hourly.
- If your host caps cron frequency — some allow only every 5 or 15 minutes — set the shortest they allow. Everything still works; scheduled reports simply go out at the next allowed tick rather than exactly on the minute.
- One cron job, not several. Adding the same line twice just doubles the work. If you're unsure whether it's already set up, check the existing list before adding another.
- Recheck it after moving hosts. Migrations bring the files and database across, but almost never the cron job. It's the most common reason backups quietly stop after a move.
Notes & warnings
The POS won't warn you loudly if the cron job is missing. Selling carries on as normal — it's the silent, automatic things that stop. Confirm it's working once, and check again after any server change.
A missed run isn't a disaster. If the server is down for an hour, due tasks simply run at the next opportunity. Nothing is lost, it's just late.
Related: Installation & setup · Scheduled reports · Backup & restore · Troubleshooting