When does each scheduled action fire?
A reference for staff who need to predict — or explain to a client — exactly when an automated action will happen. All times shown in the client's timezone unless noted; the cron jobs themselves run in UTC and translate per-client.
Payroll
| Action | Fires when | Triggered by | Recipients |
|---|---|---|---|
| Cycle initiation | The client's local 09:00 on its defaultScheduleDay of the month | Hourly cron — picks up clients whose local clock hits 09:00 in that hour | All active contacts with Can submit intake |
| Day-2 reminder | 48 hours after the cycle request email if the client hasn't submitted | check-pending-submissions daily at 09:00 UTC | Same submitter contacts; old token is invalidated, fresh 48-hour link sent |
| Day-5 reminder | 5 days after the cycle request email | Same daily check | Same submitter contacts |
| Day-7 reminder | 7 days after the cycle request email | Same daily check | Same submitter contacts |
| Approval request | Within ~30 seconds of you clicking Generate export (when the client has an active approver) | Synchronous from the export action | First active contact with Can approve, alphabetical by name |
| Approval reminder | 48 hours after approval request if not yet decided | Daily check | Same approver contact |
NOTE
"Local 09:00" follows the IANA timezone on the client record. A client at Asia/Singapore initiates at SGT 09:00 regardless of UTC drift. If you change the client's timezone, the next cycle uses the new zone — already-scheduled cycles don't move.
Bookkeeping
| Action | Fires when | Triggered by |
|---|---|---|
| Folder sync (Drive / SharePoint / Dropbox) | Configurable per channel; default hourly | bookkeeping.folder-sync cron |
| Document classify-and-draft | Within ~30 seconds of a document landing | Pg-boss queue, runs as the OCR pipeline finishes |
| Reconciliation matcher | Triggered by you, runs immediately | Synchronous from Run matcher click |
| Client portal dispatch | Triggered by you, sends within ~30 seconds | Synchronous from Dispatch unreconciled click |
Cross-cutting platform jobs
| Job | Cadence | Effect |
|---|---|---|
| Outbox dispatcher | Every 10 seconds | Drains the outbox table, sends emails / fires webhooks |
| OCR processing | On-demand per file | Vision + Claude pipeline, typically <30 s per page |
| Retention purge | 03:00 UTC on the 1st of the month | Moves cycles past the retention window from CLOSED to ARCHIVED, deletes raw uploads per the retention policy |
Token lifetimes
| Token type | TTL | Refreshed by |
|---|---|---|
| Cycle request magic link | 48 hours | Day-2 / 5 / 7 reminders mint a fresh token; old one is invalidated |
| Approval request magic link | 48 hours | Approval reminder mints a fresh token |
| Bookkeeping client portal link | 48 hours | Re-dispatch from the reconciliation run |
| Staff session cookie | Per session policy (see SLO) | Re-login |
How to figure out "when will the next email fire for this client?"
- Open the client's Cycles page.
- Look at the most recent cycle's status and last reminder sent timestamp on the audit tab.
- Match it against the table above. Example: if the cycle is
REQUESTEDand the last reminder was 2 days ago, the next reminder will fire on the next 09:00 UTC daily check, day-5.
If the client says "I haven't received anything", see Verify an email was sent.
Related
- Verify an email was sent
- Why isn't my cycle showing?
- Notifications catalog — every email the platform can send