Scheduled Sync¶
Reference for Conflux's automatic sync scheduling — the sync:dispatch Artisan command and the single scheduler entry that runs it across all active connections.
Command: sync:dispatch¶
Queries every SystemConnection with an active status, then dispatches one BulkSyncJob per connection that has at least one pull-in domain.
| Option | Default | Effect |
|---|---|---|
--full |
absent | Dispatches BulkSyncJob with forceFull: true; fetches every record from the source platform, ignoring any existing cursor |
| (absent) | — | Dispatches BulkSyncJob with forceFull: false; uses the delta cursor |
The command is driver-agnostic: it queries SystemConnection directly and works across all integration drivers (WooCommerce, PrestaShop). Which data domains a connection syncs is not read from its System alone — it is the intersection of three things, via SystemConnection::pullInCapabilities():
- the capabilities the connection's
Systemdeclares, - the connector-widget opt-in in
configuration.data_types, when the connection carries one, and - the
data_domains of activeSyncRules naming that connection as source.
A connection is skipped entirely — silently, with no error — when that intersection is empty: no linked System, an empty opt-in, or no active outgoing rule all end the same way. See Sync Rules for where those rules come from. The command always exits 0 (success) regardless of how many jobs were dispatched.
Scheduler Entry¶
One entry in routes/console.php fires the command on a configurable cron schedule, in delta mode:
| Entry | Default schedule | Mode |
|---|---|---|
sync:dispatch |
Every 2 hours (0 */2 * * *) |
Delta |
There is no scheduled full sync. --full is only ever invoked on demand — via the CLI or the Filament "Bulk Sync" action on a connection — and doesn't need its own cron entry: a connection/capability with no prior completed SyncBatch has no delta cursor, so a scheduled delta run already fetches everything for it the first time (see Sync Modes below). Periodic full resyncs are deliberately not scheduled — deletion detection runs on every sync via Deletion Log Sync, not by comparing full snapshots, so there's no correctness reason a full sync needs to recur on its own cadence.
Configuration¶
File: config/sync.php
| Key | Env variable | Default | Description |
|---|---|---|---|
sync.delta_cron |
SYNC_DELTA_CRON |
0 */2 * * * |
Cron expression for delta syncs |
Set this in .env to override the default without touching the config file:
Duplicate-Dispatch Safety¶
BulkSyncJob implements ShouldBeUnique keyed on system_connection_id. If a sync for a given connection is already queued or running when the scheduler fires again, the duplicate dispatch is a no-op. No double-processing occurs.
Deactivation Safety¶
sync:dispatch only queries connections that are active at dispatch time — a connection can still be deactivated while its BulkSyncJob (or one of its child FetchBulkPageRangeJobs) is sitting in the queue. Both jobs re-check $connection->isHealthy() at the top of handle() and return early, without fetching or persisting anything, if the connection is no longer Active. See Connection Flow — Defending Against In-Flight Work.
Sync Modes¶
- Delta sync (default, no
--fullflag) - Passes the cursor from the last completed
SyncBatchto the integration asExportRequest::$modifiedAfter. The integration returns only records modified since that point. When no completedSyncBatchexists yet for a connection/capability — a brand-new connection, or one where every prior attempt failed — there is no cursor, so$modifiedAfterisnulland the integration performs a full fetch, exactly as--fullwould. This is what lets the scheduled delta cron alone cover both "keep up to date" and "first sync ever" without a separate full-sync schedule. See Delta Sync for the cursor derivation logic. - Full sync (
--fullflag) - Passes
modifiedAfter = nullunconditionally, causing the integration to return all records — refreshing the baseline dataset even when a cursor already exists. Only triggered on demand (CLI or Filament), never by the scheduler. See Sync Batches for theSyncBatchmechanics both modes share.
Both modes also dispatch FetchDeletionLogJob on completion, passing the same cursor used for the mode's bulk export — this runs regardless of --full, since it detects deletions directly from the platform's deletion log rather than by comparing snapshots. See Deletion Log Sync.