Run slow work as a background job
Problem
A report, import, or media conversion takes too long for one request and becomes fragile behind browser, proxy, or deployment timeouts.
Before you start
Give the job a durable ID, owner, state, progress value, and expiry policy. Make starting the same job twice safe when duplicate work would be expensive.
Start the job, then ask for status
<section>
<form ng-post="/api/exports" on-success="job = $res">
<label>
Format
<select name="format"><option value="csv">CSV</option></select>
</label>
<button type="submit">Create export</button>
</form>
<div ng-if="job">
<p>Status: {{ job.status }}</p>
<button
type="button"
ng-get="/api/exports/current"
on-success="job = $res"
>
Refresh status
</button>
<a ng-if="job.downloadUrl" href="{{ job.downloadUrl }}">Download</a>
</div>
</section>
Use manual refresh first. Add measured polling or server-sent events only when the user benefits from continuous progress.
Server contract
Return 202 with the accepted job representation. The status endpoint returns
queued, running, completed, failed, or cancelled. Authorize status and download
URLs against the job owner on every request.
Failure path
Keep a failed job record with a safe explanation and request ID. Do not expose worker stack traces or leave failed uploads and generated files indefinitely.
Apply it now
Find the longest request in production traces. Move it to a job when its work can continue independently of the browser connection.
Verify
Test duplicate starts, worker restart, cancellation, failure, expiry, another user’s job ID, and download after completion.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.