
SaaS Background Exports: Clear Status, Safe Downloads, and Predictable Expiry
Design large data exports as traceable jobs with scoped permissions, meaningful progress, bounded retries, and secure delivery.
MVPs & SaaS Projects
Design cancellation around durable requests, safe checkpoints, and explicit partial outcomes instead of assuming a worker stops immediately.

LET’S BUILD SOMETHING USEFUL
Talk to Ataraxy Developers about your website, app, or custom software.
A customer starts a long-running analysis, notices the wrong input, and presses Cancel. The interface immediately says “Canceled,” but a worker continues processing and later sends a completion email. The problem is not simply a slow queue. The application treated a request to stop as proof that work had stopped.
Job cancellation is a small protocol between the user interface, application state, workers, and any external systems involved. Its design should explain what can stop, when the stop takes effect, and what remains afterward. This is particularly important for SaaS workflows that import data, generate reports, run AI analysis, or perform a sequence of external actions.
Begin with the effect the job produces. Generating a temporary report may be easy to abandon. Updating thousands of customer records may leave partial changes. Sending messages to external recipients may cross a point where the effect cannot be recalled. Those jobs should not share an unexplained “cancel” promise.
For a hypothetical document-analysis job, define whether cancellation stops new documents from starting, interrupts the current document where supported, or only prevents final publication of the result. State whether completed partial results remain accessible. The product wording should describe the chosen behavior in terms the customer can understand.
Identify the point after which cancellation is no longer available. A job may enter a short commit phase where completing the operation is safer than interrupting it. Show that phase honestly and provide an appropriate next action. Do not leave an enabled Cancel button that silently has no effect.
Treat cancellation as durable application state tied to the job, tenant, and authorized actor. A message sent only to a worker can be lost during restart or disconnection. If the application accepts the request, future workers should be able to discover it before continuing the job.
Make repeated cancellation requests safe. A second click or network retry should return the current state of the same job rather than create another cancellation operation with conflicting timestamps. Verify the caller’s permission each time; knowing a job identifier is not sufficient authority to stop another customer’s work.
Record when cancellation was requested separately from when it was acknowledged and when the job reached a terminal outcome. These times explain delays and support honest status messages. They also make it possible to distinguish an unresponsive worker from a job that is finishing a documented safe step.
Workers should inspect the cancellation state at meaningful boundaries, such as before starting a document or before writing a new batch of results. Choose checkpoint frequency based on the duration and consequences of each unit. A check only at the beginning of a two-hour job provides little practical control.
Queue commands need careful interpretation. Celery’s worker guide explains that revoke normally skips a task that has not started, while termination is an administrative last resort affecting the worker process. A queue-level action should not be treated as a complete business cancellation workflow.
Keep the job’s own state authoritative for the customer-facing outcome. If a worker discovers a cancellation request, it should stop at an allowed checkpoint, perform the required cleanup, and record what happened. A worker crash is not equivalent to a clean cancellation; recovery must inspect the recorded progress and any external effects.
The worker may finish at the same time the user requests a stop. Define which transitions are valid and enforce them atomically at the state boundary. A terminal completed job should not later be relabeled canceled merely because a delayed request arrived.
For example, a report job can allow cancellation until its final artifact is committed. If completion wins that decision, return “Completed before cancellation took effect” and offer the normal result controls. If cancellation wins, the worker should not publish the artifact afterward. The exact rule matters more than which label sounds reassuring.
Use the same transition rules when workers retry. A replacement worker must not restart a canceled job just because the queue delivered its original message again. Check durable state before doing work and before committing final effects. This prevents queue delivery behavior from overriding the user’s recorded intent.
If a job updates records in units, preserve a ledger of completed units and their outcomes. Cancellation can then stop future work while reporting which changes already happened. Do not imply that stopping a job automatically rolls back every previous action.
Where reversal is supported, make it a separate, explicitly designed operation. A compensating action may have different permissions, risks, and failure modes from the original job. Automatically reversing completed work can be more disruptive than leaving a clear partial result for review.
For external APIs, inspect the provider’s cancellation and status capabilities. A request timeout may leave an uncertain outcome, just as it does during normal processing. Reconcile the provider’s state before retrying or claiming an action was prevented. If the provider cannot stop an accepted operation, explain that limit in the product contract.
Useful states include queued, running, cancellation requested, stopping, canceled, completed, and failed, but a product does not need to display every internal state. It does need to distinguish pending cancellation from confirmed cancellation and partial completion from no work performed.
Show progress in units the customer recognizes where possible: documents analyzed, records updated, or files prepared. If an estimate is uncertain, label it accordingly. Avoid a fabricated remaining time that counts down to zero while the worker is waiting on an external service.
For AI jobs, account separately for work already submitted to a provider and work that has not started. Stopping local scheduling does not establish that a remote inference was canceled or that no usage occurred. Present usage according to the service’s actual accounting rules, with any unresolved provider outcome reconciled before a final statement.
Create a test sequence for canceling before a worker starts, during a unit, between units, during final commit, and after completion. Add repeated cancellation requests, a worker restart, duplicate queue delivery, and an external response that arrives late. Verify both state and actual side effects.
Inspect cleanup behavior as well. Temporary files, locks, reserved capacity, and partial result references need defined handling. A job can stop consuming compute while leaving resources that block later work. Track cleanup failures as actionable exceptions rather than hiding them behind a terminal canceled label.
Review notifications and webhooks after each scenario. A canceled job should not emit an ordinary completion message from a stale worker. If the service sends a partial-outcome notification, its wording should agree with the recorded ledger and link to the correct job under current access checks.
Cancellation is a request that becomes an outcome only after the system confirms what stopped and what remains. Store intent durably, use safe checkpoints, resolve races explicitly, and report partial effects honestly. This gives customers meaningful control while keeping workers and integrations consistent with the application’s record.
LET’S BUILD SOMETHING USEFUL
Talk to Ataraxy Developers about your website, app, or custom software.