When a web request creates a report, import, email, or provisioning job, the worker runs later without the original session. The queue message must preserve enough trusted context to identify the tenant and authorize access again.
Last updated: September 8, 2026.
{
"job_id": "job_8f4d2",
"tenant_id": 1842,
"actor_id": 73,
"type": "generate_invoice_export",
"resource_id": 9921,
"idempotency_key": "export-1842-9921-v1"
}Store identifiers rather than copying sensitive business data into the queue. Encrypt the transport, restrict producers and consumers, and treat every message as untrusted input.
Re-establish authorization in the worker
The worker loads the job, resolves the tenant, and verifies that the referenced resource belongs to that tenant. It must apply the same tenant-isolation rules as an interactive request. Never query a record by resource_id alone.
Make processing idempotent
Queues can deliver a message more than once, and a worker can stop after completing an external action but before acknowledging the message. Use a unique idempotency key or a job table with states such as pending, running, completed, and failed. A retry should observe completed work instead of sending a second invoice or creating another export.
Control fairness and failures
Apply per-tenant concurrency and queue limits so one customer cannot create a noisy-neighbor incident. Use bounded retries with backoff, then move permanently failing jobs to a dead-letter queue. Store a safe error summary for support without exposing secrets to customers.
Protect results
Save generated files under tenant-scoped storage keys. When a user checks job status or downloads a result, validate both the job and result against the active tenant. Expire temporary exports and signed download links.
Record creation, retries, completion, cancellation, and administrative replay in the audit log. Track queue age as well as queue depth because a small queue can still contain stuck work. Microsoft’s background-job guidance also recommends idempotency, durable state, observability, and independent scaling based on queue demand.