Daily checks
The ten-minute daily routine for whoever runs a live Zodiac Tech CRM install — health endpoint, backups, queue, leads and payments.
Daily checks
A live install has a small number of moving parts: the web app, the queue worker, the scheduler and the nightly jobs. Ten minutes each morning is enough to catch almost everything before your team notices. Work down this page in order — each step links to the page that explains the fix when something is off.
Who this is for
- The super admin (or whoever is on point) for a live install.
- Developers covering support for a client workspace.
Difficulty: Easy · Time: about 10 minutes · Prerequisites: Super Admin access and, ideally, the ability to run php artisan on the server (or reach the cron runner).
Step 1 — Read the health endpoint
Open GET {your app URL}/api/v1/health. It returns HTTP 200 with status: ok, or HTTP 503 with status: degraded when a core check fails:
{
"status": "ok",
"checks": { "db": "...", "cache": "...", "storage": "..." },
"queue": "...",
"version": "...",
"timestamp": "..."
}
If it is degraded, note which of db, cache or storage failed — the same failure is written to the log as healthcheck.db.failed, healthcheck.cache.failed or healthcheck.storage.failed. Point an uptime monitor at this URL and at your login page; see Monitoring & alerts.
Step 2 — Skim Super Admin → System Health
Open Super Admin → Settings → System Health (/super-admin/settings/system-health). On a healthy morning:
- Queue driver is not
syncon production. Withsync, jobs run inline inside web requests — slow integrations then block page loads, and System Health warns about it when you restart the queue. - Debug mode is off.
- Disk usage has headroom (recordings and backups grow over time).
- The WhatsApp health card shows connections as connected, templates where you expect them, and
queue_failuresat 0. That count comes from failed jobs forSendLeadMessage.
The page also carries the one-click actions you will want on a bad day — Clear caches, Run migrations, Rebuild caches, Storage link and Restart queue. Incident response says when to use each.
Step 3 — Confirm last night's jobs ran
This is what runs every night (server time):
| Time | Job | Where you see it |
|---|---|---|
| 02:00 | leadhub:backup |
Super Admin → Settings → Backups — newest entry is from last night; run Verify |
| 03:00 | leadhub:purge-audit-logs |
Old audit rows gone; see Data retention & privacy (GDPR) |
| 03:15 | leadhub:purge-recordings |
Old recordings' audio deleted; rows kept with status = expired |
| 03:30 | leadhub:capture-benchmarks |
Benchmark snapshot recorded |
| 04:00 | leadhub:execute-erasure |
Runs only when a tenant's 30-day deletion countdown has passed |
| 04:30 | leadhub:sync-meta-ads --days=30 |
Meta ads data refreshed |
The nightly backup is opt-in leadhub:backup only runs when it is enabled — Super Admin → Settings → Script Settings → Backups (auto_nightly_backup), or leadhub.backups.auto_nightly in config on custom installs. If it is off, you own the backup schedule instead.
Do not just look at the backup — verify it. The Verify action on the Backups page re-opens the archive, checks it is healthy and counts the SQL statements inside.
Step 4 — Make sure the queue and scheduler are alive
- Failed jobs:
php artisan queue:failedshould be empty, or only rows you have already triaged. - Worker: a
queue:workprocess must be running and must listen to every queue:php artisan queue:work --queue=default,webhooks,automations,integrations,notifications,exports,ai-sdr,mailA worker that omits a queue silently starves it. - Scheduler:
php artisan schedule:runfires every minute — via cron on a VPS, or via the singlecron.phpentry point on shared hosting (it drains the queue with a time budget, then runs the scheduler). Every scheduled task logs its failure asschedule task failed: {name}, so searchingstorage/logs/laravel.logforschedule task failedis a fast check that nothing is quietly broken.
Step 5 — Glance at leads, messages and money
- Leads: Admin → Lead Source Health Report (
/admin/lead-source-health-report) and Webhook Logs (/admin/webhook-logs) — no unexpectedrejectedorinvalid_signaturerows. - Meta issues: Super Admin → Meta Ads → Needs Attention (
/super-admin/meta-ads/needs-attention) — the nav badge shows open CRITICAL issues; acknowledge the ones you are handling. - Billing: Super Admin → Billing → Commercial (
/super-admin/billing/commercial) — read thepayment_failures,grace_period,restrictedandsuspendedcards; anything unusual, see Payments failing.
Expected result
Every check above done in about ten minutes, with nothing to fix — or a short list of specific items, each with a page that tells you how to fix it.
Common mistakes
| Mistake | Why it hurts | Do this instead |
|---|---|---|
| Only checking that the site loads | The queue or nightly jobs can be dead while pages still render | Do Steps 3 and 4 every day |
Running queue:work without the queue list |
Jobs on missing queues never run | Always pass the full --queue= list |
| Never verifying backups | A backup that cannot restore is not a backup | Verify the newest backup, and do a restore drill monthly |
Leaving QUEUE_CONNECTION=sync in production |
Integrations run inside web requests and block them | Use the database/Redis driver with a running worker |
| Ignoring disk usage | A full disk breaks uploads, the database and backups | Watch it weekly; prune backups and old recordings |
Troubleshooting
| What you found | Go to |
|---|---|
| Health endpoint degraded | Incident response |
| Backups missing or failing to verify | Incident response |
| Leads stopped arriving | Leads not entering the CRM |
| Failed jobs piling up | Incident response |
| Payment failures on the cards | Payments failing |
Technical details
- Scheduler definitions live in
routes/console.php. Every entry logs failures via->onFailure(...)asschedule task failed: {name}; most use->withoutOverlapping(10). - High-frequency tasks: every 5 minutes (IMAP mailbox checks, appointment reminders, follow-up due checks,
tasks:send-reminders); hourly (notifications:digest,reports:deliver,filters:send-alerts, payment failure checks); every 15 minutes (ProcessEmailSequences,ProcessAiSdrEnrollments,leadhub:sync-calendars); every 30 minutes (leadhub:meta-ops-scan, provider reconciliation, applied change requests); every 6 hours (leadhub:meta-health). - The health endpoint is
App\Http\Controllers\Api\HealthControlleratGET /api/v1/health— public, 200/503.
Related guides
Was this page helpful?
Thanks — noted. ✦