Computing payroll for hundreds of employees or importing thousands of Excel rows inside one HTTP request is a recipe for timeouts and a frozen UI. In Dexova, all heavy work runs as monitorable async jobs. This is the pattern that makes them reliable, not just 'moved to the background'.
Idempotency matters more than it looks
Jobs can run again: a worker dies mid-way, the network hiccups, a retry fires automatically. If a job is not idempotent, a retry doubles its effect — payroll computed twice, stock decremented twice.
The key is a stable job ID and an 'already done?' check before the effect happens. For scheduled jobs, an ID containing the date prevents two replicas from executing the same daily task.
Safe retries, and knowing when to give up
Transient failures (a busy DB, a slow third-party API) deserve retry with backoff. Permanent failures (invalid data) do not — retrying only wastes time and hides the problem.
Distinguish the two explicitly: an error that will never succeed must stop retries and go to a dead-letter for a human to inspect, not spin forever.
Visible progress changes the experience
A payroll run in Dexova is not a button that then goes silent. HR presses it, watches progress, and gets a result they can review before finalizing. Long work with no feedback feels broken — even when it is running fine.
The same pattern applies to bulk employee import: upload, process in the background, and report which rows failed and why — not one generic error that fails the entire file.
Summary
Moving heavy work to the background is only half the job. The other half: idempotency so retries are safe, distinguishing transient from permanent failure, and showing progress so humans trust the system is working.