AccelerUpDocs
Running AccelerUp/Operations/Background workers

Background workers

What runs in the background, how often, and what happens when one fails.

Around fifty background workers run inside the backend process. They are registered through a helper that leader-gates them: with two replicas, each worker runs on exactly one.

Important

Without that gate, every scheduled rule would evaluate twice and every notification would be sent twice. If you add a worker, register it the same way as the others.

The main ones

WorkerIntervalDoes
monitor_worker30 sHTTP/TCP service checks
dwh_alert_worker1 minEvaluates SQL alerts
notification_retry_worker30 sDrains the delivery retry queue
cf_hourly_workerhourlyCloudflare metric rollups
cf_alert_workerminutesCloudflare error-rate rules
cf_datasource_alert_workerminutesPer-endpoint guard
elk_sync / elk_alert_workerminutesLog analytics + rules
anomaly_workersminutesAnomaly detection across sources
mysqlnode_sync / _alert_workerminutesDatabase node health
proxysql_sync / _alert_workerminutesConnection-pool health
synthetic_workerper checkSynthetic checks
agent_watchdogminutesAgents that stopped reporting
slo_burn_workerminutesError-budget burn rate
jenkins_pollminutesBuild status
release_sync_workerminutesRelease + changeset sync
cost_sync_workerdailyCloud spend snapshots
copilot_kb_workerscheduledKnowledge-base embedding
report_worker / saas_report_workerscheduledScheduled reports
cleanupdailyRetention pruning

internal/worker/ holds the full list.

Failure behaviour

A worker that fails logs and continues on its next tick. It does not take the process down, and it does not stop its siblings.

Workers that talk to slow external systems carry their own timeouts — an individual SQL alert rule, for example, gets two minutes, so one hanging warehouse query cannot hold up every rule behind it. The symptom of missing that is unrelated alerts going quiet, which looks like nothing being wrong.

Rules that cannot evaluate

A worker that cannot do its job raises a fault rather than being silent — and reports it on transition, not on every run. A misconfigured rule evaluated every minute should produce one message, not one a minute forever.

Adding a worker

  1. Put it in internal/worker/.
  2. Extract anything that decides into a pure function with its own tests — the worker should call a decision, not contain one.
  3. Register it through the leader-gating helper in main.go.
  4. If it writes a high-volume table, add that table to the cleanup worker's retention list.

Observing them

Settings → System Health shows worker liveness and last-run times. Start-up lines in the log name each worker as it registers — notification retry worker started, and so on — which is the quickest way to confirm a worker is running on the replica you are looking at.

Where this behaviour lives: backend/internal/worker/, backend/cmd/server/main.go. If the code and this page disagree, the code is right — please fix the page.

Part of Running AccelerUpOperating the platform itself: architecture, deploys, backups.