PHP and MySQL
How to run reliable PHP cron jobs
Make scheduled PHP work idempotent, observable and separate from web requests with locking and explicit runtime configuration.
By AppLaunch Editorial · Reviewed 2026-08-25
Direct answer
A production cron job should use the intended CLI PHP version, prevent harmful overlap, record success and failure, and be idempotent so a retry does not duplicate side effects. Long jobs need timeouts, checkpoints and a clear owner.
What this means in plain English
A cron job runs PHP work on a schedule, such as sending reminders or cleaning old data. Use the exact PHP binary and working folder the job expects, because scheduled jobs often have a smaller environment than an interactive terminal.
Make repeated runs safe. A job should not send the same invoice twice if it is retried, and two copies should not change the same data at once. Record when it starts, finishes and fails, then alert when an expected run never happens.
What makes a cron job safe to repeat?
| Runtime | Exact CLI PHP binary and environment |
|---|---|
| Concurrency | Lock or queue prevents unsafe overlap |
| Evidence | Start, completion, duration and failure logs |
A simple example
A job runs every five minutes but sometimes takes eight. Without a lock, the next copy starts while the first is still working and sends duplicate messages. A lock and per-message idempotency make overlap harmless, while monitoring shows the job needs optimisation.
What to do, step by step
1. Use an absolute command and working directory.
Start here before buying anything or changing several settings at once. It gives you a clear starting point based on runtime: exact cli php binary and environment. Write the result down so you can compare it later.
2. Add idempotency or a distributed lock.
Use the same files, versions and settings that the real project will use. A quick test with an empty or different setup can look successful while completely missing the problem you are trying to solve.
3. Capture output and exit code.
Try the busiest realistic situation, not the easiest one. Include the people, data, traffic or background work you genuinely expect, then watch for slowdowns and errors rather than relying on a single headline number.
4. Alert when expected runs are missing.
Finish by checking the result against evidence: start, completion, duration and failure logs. Keep the old setting or release available until you know the change works and can be reversed safely.
One more useful tip
Do not send all cron output to /dev/null. Capture useful output with limits so failures are visible without filling the disk.
Common mistakes and how to avoid them
Assuming cron uses the web PHP version.
This gives a misleading or unsafe result because it leaves out runtime. A better approach is to use an absolute command and working directory, then check the result before making the change permanent.
Silencing all output.
This gives a misleading or unsafe result because it leaves out concurrency. A better approach is to add idempotency or a distributed lock, then check the result before making the change permanent.
Running a minute job that routinely lasts longer than a minute.
This gives a misleading or unsafe result because it leaves out evidence. A better approach is to capture output and exit code, then check the result before making the change permanent.
Words explained
- PHP
- The programming language that runs the server-side part of many websites and applications.
Quick checklist
- Use an absolute command and working directory.
- Add idempotency or a distributed lock.
- Capture output and exit code.
- Alert when expected runs are missing.
Common questions
What is the simple answer?
A production cron job should use the intended CLI PHP version, prevent harmful overlap, record success and failure, and be idempotent so a retry does not duplicate side effects. Long jobs need timeouts, checkpoints and a clear owner.
What should I check first?
Start with runtime: exact cli php binary and environment. That is usually more useful than choosing from a marketing label or copying somebody else’s setting.
How can I make the change safely?
Use an absolute command and working directory. Then change one thing at a time, keep a backup or old version, and use the same real-world test after each change.
What is the easiest mistake to avoid?
Assuming cron uses the web PHP version. Avoiding that one mistake makes the rest of the comparison much more trustworthy.