Scheduler & Cron FAQ
How the Scheduler Works
Traffic Exchange Script uses Laravel’s built-in task scheduler. All scheduled tasks run through a single cron entry:
* * * * * cd /path/to/your/site && php artisan schedule:run >> /dev/null 2>&1
This command runs every minute. It checks which tasks are due and dispatches them on the correct frequency. If this cron entry is not running, all automated tasks will stop — newsletters won’t send, subscriptions won’t downgrade, contests won’t finalize.
Before troubleshooting any specific task, always verify the scheduler itself is working.
How to verify the scheduler is running:
1. Open storage/logs/laravel.log in cPanel File Manager (navigate to your site root → storage/logs/).
2. Look for lines from the last few minutes. You should see entries every 1–2 minutes.
3. If the log has no recent entries, the scheduler cron is not running. Fix that first before troubleshooting individual tasks.
Newsletters
Q: I scheduled a newsletter but it was never sent. Members didn’t receive anything.
A: The newsletter dispatch command (te:dispatch-scheduled-newsletters) runs on schedule and sends any newsletter whose scheduled time has passed. If it wasn’t sent, check these in order:
1. Confirm the scheduler is running (see above). If schedule:run is not in your cron, nothing sends.
2. Check the newsletter’s status in the admin panel. Go to Admin → Newsletter. If the newsletter shows as Draft rather than Scheduled, it was never queued for sending. You need to set a scheduled time and save it as Scheduled.
3. Check the scheduled time. The newsletter will not be sent until scheduled_at has passed. If you set the time in a different timezone and it hasn’t occurred yet in UTC (the script’s default timezone), it will wait.
4. Check your mail configuration. The newsletter command dispatches emails via your configured mail driver. If MAIL_MAILER=log (the default if you haven’t set up SMTP), emails are written to the log file and never actually sent. Check your .env:
MAIL_MAILER=smtp
MAIL_HOST=your.smtp.host
MAIL_PORT=587
MAIL_USERNAME=your@email.com
MAIL_PASSWORD=yourpassword
5. Check the log for errors. Open storage/logs/laravel.log and search for newsletter. Any dispatch failures will be logged with the newsletter ID and error message.
Q: Newsletters are sending but members say they are going to spam or not arriving at all.
A: This is a mail deliverability issue, not a scheduler issue. The newsletter was dispatched successfully — the problem is at the mail provider level. See the Email Not Sending section in the Troubleshooting Guide for SMTP and deliverability fixes.
Subscriptions and Membership Downgrades
Q: A member’s subscription expired but they were not downgraded to free. Why?
A: Subscription downgrades are handled by te:apply-scheduled-downgrades. This command looks for cancelled subscriptions whose billing period has ended and applies the scheduled downgrade.
Check these in order:
1. Confirm the scheduler is running. If the cron is not set up, downgrades never run.
2. Confirm the subscription is actually cancelled. Go to Admin → Members → find the member → check their Subscription tab. If the subscription shows as Active and not Cancelled, the downgrade is not yet scheduled. Subscriptions are only downgraded after they are cancelled AND the current billing period ends.
3. Check the billing period end date. The downgrade only applies when current_period_end has passed. If a member paid for a monthly subscription on March 1st and cancels on March 5th, they will remain on the paid tier until April 1st. This is correct behaviour — they paid for the full month.
4. Check the scheduled downgrade target. The admin panel shows the downgrade target level on the member’s subscription. If this field is empty, no downgrade will be applied and the member will stay on their current tier indefinitely after cancellation. Assign a downgrade target in the subscription settings.
Q: The dunning system is not retrying failed payments. Members are staying on paid tiers even after failed charges.
A: Payment retry (dunning) is handled by te:process-dunning. This command retries failed subscription payments on a schedule before eventually downgrading the member.
If dunning is not working:
1. Confirm the scheduler is running.
2. Go to Admin → Members and check the member’s subscription — look for the Dunning section showing retry count and next retry date.
3. Confirm the payment gateway is correctly configured — if the gateway has invalid credentials, all retries will fail silently.
4. Check the log for dunning errors: search laravel.log for dunning.
GeoIP Data
Q: My GeoIP data is out of date. Member locations are showing incorrectly in analytics and geo anomaly detection is misfiring.
A: GeoIP data is updated by running php artisan te:update-geoip. This command downloads the latest MaxMind GeoLite2 database and replaces the stored database file at storage/geoip/GeoLite2-City.mmdb.
To update manually via SSH:
php artisan te:update-geoip
To set it up as a scheduled task (it is already included in the scheduler — check that your cron is running):
The te:update-geoip command runs weekly by default via the scheduler. If your cron is running correctly, the database will update itself. If it is not updating, check the log for errors when this command runs — it may be a network issue (blocked outbound connection to MaxMind’s download servers).
If GeoIP is completely missing (new installation):
Run php artisan te:update-geoip manually immediately after install. The database is not bundled with the script and must be downloaded on first run.
Contests
Q: A contest ended but prizes were not awarded. Members are waiting.
A: Contest finalization is handled by te:finalize-contests. This command runs on schedule and finalizes any contests whose end time has passed.
Check these in order:
1. Confirm the scheduler is running. No scheduler = contests never finalize automatically.
2. Check the contest end time. Go to Admin → Contests and confirm the contest’s end date has actually passed (and is in the past, in UTC).
3. Run finalization manually. You can trigger this immediately via SSH:
php artisan te:finalize-contests
This is safe to run manually — it only processes contests that are truly ended and not yet finalized.
4. Check the log. Search laravel.log for contest to see if finalization ran and whether there were any errors (e.g. prize credits could not be awarded because a member’s account is suspended).
General Scheduler Troubleshooting
Q: How do I add the scheduler cron entry on shared hosting (cPanel)?
A:
1. Log into cPanel and go to Cron Jobs.
2. Set frequency to Once Per Minute (every minute).
3. Enter this command — replace the path with your actual site root:
php /home/youraccount/public_html/artisan schedule:run >> /dev/null 2>&1
4. Save the cron job.
Wait 2–3 minutes, then check storage/logs/laravel.log — you should see scheduler entries starting to appear.
Q: How do I run a scheduled task manually to test it?
A: You can run any artisan command manually via SSH. All Traffic Exchange Script commands follow the pattern php artisan te:<command-name>. Examples:
# Dispatch pending newsletters
php artisan te:dispatch-scheduled-newsletters
# Apply subscription downgrades
php artisan te:apply-scheduled-downgrades
# Update GeoIP database
php artisan te:update-geoip
# Finalize ended contests
php artisan te:finalize-contests
# Run site health checks
php artisan te:check-site-health
# Validate license key
php artisan te:validate-license
Running a command manually is safe — it does the same thing the scheduler would do, just immediately rather than waiting for the next scheduled window.
Q: A task was running, then stopped. The cron is still set up correctly. What else could cause this?
A: A few less-obvious causes:
- Disk full. If your server disk is full, the log file cannot be written to, which can cause the scheduler to fail silently. Check disk usage in cPanel under Disk Usage.
- PHP memory limit hit. If a long-running task exceeded the PHP memory limit, it may have crashed mid-run and left the scheduler in a broken state. Check
storage/logs/laravel.logfor “Allowed memory size exhausted” entries. - Database connection lost. If the database server briefly went down or timed out, commands that depend on the database will fail. Check your hosting provider’s status page.
- Session driver issue. If
SESSION_DRIVER=fileand the sessions directory filled up or lost write permissions, some scheduler commands may fail. Checkstorage/framework/sessions/permissions (should be 775).

Screenshots

