SIGNALS Documentation
API Reference

Scheduled Tasks

Every task Signals runs on a schedule, how often it runs, and how to run the scheduler and queue workers.

Last reviewed against source:

Run the scheduler

Signals registers all of its recurring work with the Laravel scheduler in routes/console.php. The scheduler does nothing until something calls it every minute. On a self-hosted server, add one cron entry for the user that owns the application:

* * * * * cd /path/to/app && php artisan schedule:run >> /dev/null 2>&1

Check it with php artisan schedule:list, which shows each entry and its next due time.

The first scheduled entry writes a heartbeat to the cache every minute. Admin → System → System Health reads that heartbeat: the Scheduler card is green when it is no more than five minutes old, and warns when it is older or missing. php artisan doctor --only=signals-scheduler runs the same check from the command line. See System Health.

All times below are UTC. Entries marked "one server" take a cache lock so that only one server runs them in a cluster; use a shared cache such as Redis when you run more than one application server. Entries that do not overlap skip a run while the previous one is still going.


Run the queue workers

Many scheduled entries dispatch queued jobs rather than doing the work themselves, and so do web requests. A scheduler without workers queues jobs that never run.

  • During development, composer run dev starts a queue listener alongside the web server.
  • In production, run php artisan queue:work under a process manager such as Supervisor or systemd, and restart it after every deployment with php artisan queue:restart.
  • A worker started without --queue handles only the default queue. Signals dispatches jobs to these named queues, so name them all: default, availability, approvals, embeddings, exports, imports, notifications, privacy, webhooks and workflows. For example: php artisan queue:work --queue=default,availability,approvals,embeddings,exports,imports,notifications,privacy,webhooks,workflows.
  • Set QUEUE_CONNECTION to redis or sqs for production. Without it, the queue connection falls back to database. See Installation.

The Queue card on System Health shows whether named queues are draining and lists failed jobs, which a user with settings.manage can retry.


Every minute

Task What it does
Scheduler heartbeat Records the time of the last run so System Health can tell the scheduler is alive.
signals:base-currency-identity:backfill Backfills base-currency identity on historical records and refreshes open rentals. One server; skips overlap.
Reverse due currency revaluations Reverses currency revaluations that have fallen due.
signals:dispatch-scheduled-workflows Dispatches due runs of published scheduled workflows.
signals:billing-runs:dispatch-pending Recovers billing-run attempts left between claim and queueing.
signals:billing-runs:dispatch-issue-effects Recovers pending billing-run PDF, communication and dashboard effects.
signals:credits:dispatch-issue-effects Recovers credit-note issue effects without resending uncertain email.
signals:finance:dispatch-customer-effects Recovers standalone invoice and payment customer notifications.

The four finance entries run as --apply with a per-run limit.

Every five minutes

Task What it does
signals:dispatch-report-schedules Queues delivery for every report schedule that is due.
signals:api:flush-logs Flushes buffered API metering entries into persistent storage.
Retry due privacy cases Retries approved or failed account privacy cases that are due.
Drain account mutation effects Completes pending follow-up work after account changes.
Drain rental attachment effects Completes pending follow-up work after rental attachment changes.
Drain webhook outbox Hands pending webhook deliveries to the queue, catching any that were missed.
Expire approval requests Expires pending approval requests that are past their deadline.
Escalate approval assignments Escalates approval assignments that have waited too long.
Expire approval delegations Expires approval delegations that have ended.
Expire credit reservations Expires credit reservations that are past their expiry time.

Every fifteen minutes

Task What it does
signals:billing-runs:reconcile-attempts Inspects stale billing-run claims and settles items that have receipts.
signals:workflow-timing:repair Repairs delayed workflow timing operations.

Hourly

Task What it does
signals:api:warm-doc-caches Warms the API specification and documentation caches in the background.
signals:plugin-cache Compiles the enabled plugin list and manifests to the plugin cache.
signals:finance:integrity Reports read-only invoice and billing-run integrity findings, at 20 minutes past the hour.
signals:accounts:health --alerts Reports account identity, merge, credit, privacy and search integrity alerts.
Evaluate account retention Evaluates account retention and opens review cases where needed.
Expire put-asides Releases expired put-aside holds. The put-aside demand source is not built, so this currently does nothing.
Expire waitlist monitors Expires stale shortage waitlist monitors.
signals:shortages:escalate-unresolved Notifies when shortages on confirmed orders approach dispatch unresolved.
signals:virtual-stock:detect-overruns Notifies when virtual stock intakes pass their available-until date without return.
signals:expire-scan-sessions Abandons stale open scan sessions.

Overdue checks

Two entries share a cadence set by the Overdue check interval (minutes) setting under Admin → Preferences → Scheduling, described in Scheduling settings. The default is 60, which is hourly. Values below 60 run every that many minutes, whole hours run every that many hours, and other values round up to a whole hour. The setting accepts 1 to 1440 minutes.

Task What it does
signals:availability:detect-overdue-demands Extends overdue, unreturned demands so availability keeps reflecting stock that has not come back.
signals:rentals:detect-late-returns Notifies when orders still have equipment out past their end date.

Daily

Time Task What it does
00:00 signals:api:prune-logs Prunes API request and inbound webhook logs past retention.
00:00 queue:prune-failed --hours=720 Removes failed-job records older than 30 days.
00:00 model:prune Runs Laravel's pruning for models that opt in.
00:00 Prune availability data Removes availability snapshots, summaries and events beyond their retention settings.
00:00 signals:scan-equipment-tests Recomputes equipment test due dates for all assets.
00:00 signals:scan-flightcase-overruns Notifies when flightcase contents overrun their sub-hire return deadline.
01:00 signals:exchange-rates:fetch Fetches exchange rates for enabled currencies from an automatic provider. One server.
01:30 Sync changed embeddings Embeds new and changed records for AI search.
02:00 signals:action-log:prune Prunes action log entries past retention.
02:10 signals:ai-usage:prune Prunes AI usage log entries past retention.
02:15 signals:embeddings:prune Removes expired embeddings and those whose source no longer exists.
02:30 signals:communication-log:prune Prunes the communication log past retention.
02:35 signals:workflow-evidence:prune Prunes workflow evidence details and keeps redacted summaries.
02:40 signals:webhook-outbox:prune Prunes settled webhook outbox entries past retention.
02:50 signals:tenant-magic-nonces:prune Prunes consumed magic-link nonces.
03:00 signals:recently-viewed:prune Keeps only the newest recently viewed items per user.
03:15 signals:recent-searches:prune Prunes recent searches past retention.
03:15 signals:imports:prune-staging Prunes import staging files for completed, cancelled and abandoned imports.
03:30 Refresh account quality recommendations Recomputes data-quality recommendations for accounts.
03:30 Verify snapshot integrity Samples availability snapshots, repairs any drift and logs it.
03:30 signals:exports:prune Deletes expired export files.
03:40 signals:accounts:health Runs the full account health report without alerts.
03:40 signals:reports:prune-delivery-files Deletes scheduled report delivery files whose email did not succeed, after 24 hours.
03:45 Prune account privacy artifacts Removes expired or revoked privacy case artifacts.
04:00 signals:accounts:revalidate-expired-vat Queues VAT number revalidation for accounts whose cached check has expired.
04:15 Roll up utilisation Rolls up the day's utilisation figures for reports.
04:30 Roll up asset valuations Rolls up asset valuations for reports.
06:00 signals:invoices:process-overdue Dispatches overdue side effects for unpaid invoices past their due date. Skips overlap.
07:00 signals:rentals:detect-expiring-quotes Notifies when quotes approach their expiry date.
08:00 Digest notifications Sends each user one summary email of unread notifications that they opted into digests for.

Weekly or monthly

Task When What it does
Refresh all embeddings Sundays at 02:15, or the 1st of the month at 02:15 Re-embeds every record for AI search. The ai.refresh_cadence setting chooses weekly (the default) or monthly.

Signals Cloud

On Signals Cloud one scheduler serves every tenant, so each entry above runs once per active tenant and failures in one tenant do not stop the others. The Cloud schedule also runs migrate --force --isolated every five minutes and prunes failed jobs centrally. Cloud queue workers are managed for you.


Reference Use it for
System Health Scheduler and queue checks
Scheduling settings The overdue check interval
Installation Queue and cache drivers
Backup and Restore Protecting the data these tasks maintain