Skip to content

Jobs & Queues

Jobs are the fundamental building blocks of Spooled. Learn how to queue, process, and manage asynchronous work reliably at any scale.

Job Lifecycle

Every job follows a predictable lifecycle from creation to completion. Understanding this lifecycle is key to building reliable systems.

%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ecfdf5', 'primaryTextColor': '#065f46', 'primaryBorderColor': '#10b981', 'lineColor': '#6b7280'}}}%%
stateDiagram-v2
    [*] --> pending: Job created
    pending --> processing: Worker claims
    processing --> completed: Success
    processing --> failed: Error
    failed --> pending: Retry
    failed --> deadletter: Max retries exceeded
    deadletter --> pending: Retry from DLQ
    completed --> [*]

Job States

State Description Transitions
pending Job is waiting to be processed → processing (by worker)
processing Worker is processing the job → completed, failed
completed Job finished successfully Terminal state
failed Job failed, may retry → pending (retry), deadletter
deadletter Job in dead-letter queue → pending (retry from DLQ)

Dashboard Tip

📍 Dashboard → Jobs

What to look for:

  • Filter jobs by status (pending, processing, completed, failed, deadletter)
  • View job payload and metadata
  • See retry count and last error

Creating Jobs

Use the SDK or REST API to create jobs. Each job belongs to a queue and carries a payload that your workers will process.

curl -X POST https://api.spooled.cloud/api/v1/jobs \
  -H "Authorization: Bearer sp_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "queue_name": "my-queue",
    "payload": {
      "event": "user.created",
      "user_id": "usr_123",
      "email": "alice@example.com"
    },
    "idempotency_key": "user-created-usr_123"
  }'

Job Properties

Property Type Description
queue_name string Queue name (alphanumeric + hyphens)
payload object JSON payload (up to 1MB on paid plans)
idempotency_key string Prevents duplicate jobs (optional but recommended)
max_retries number Max retry attempts (default: 3)
scheduled_at Date When to process (null = immediately)
priority number Higher values processed first (default: 0)
tags array | object Optional tags for filtering (stored as JSON)

Filtering jobs (including tags)

Use query parameters to filter job listings. For tags, you can filter by a single tag value:

# List jobs tagged "urgent"
curl https://api.spooled.cloud/api/v1/jobs?tag=urgent \
  -H "Authorization: Bearer YOUR_API_KEY"

# List DLQ jobs tagged "urgent"
curl https://api.spooled.cloud/api/v1/jobs/dlq?tag=urgent \
  -H "Authorization: Bearer YOUR_API_KEY"

Claiming & Processing Jobs

Workers claim jobs to process them. Claimed jobs are locked for a visibility timeout to prevent duplicate processing.

# Claim up to 5 jobs
curl -X POST https://api.spooled.cloud/api/v1/jobs/claim \
  -H "Authorization: Bearer sp_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "queue_name": "my-queue",
    "worker_id": "worker-1",
    "limit": 5
  }'

Important: Visibility Timeout

If a worker doesn't complete or fail a job within the visibility timeout, the job becomes available for other workers. Set this higher than your expected processing time.

Completing Jobs

# Complete a job
curl -X POST https://api.spooled.cloud/api/v1/jobs/job_xyz123/complete \
  -H "Authorization: Bearer sp_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "worker_id": "worker-1",
    "result": {"processed": true}
  }'

Failing Jobs

# Fail a job (will retry if retries remaining)
curl -X POST https://api.spooled.cloud/api/v1/jobs/job_xyz123/fail \
  -H "Authorization: Bearer sp_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "worker_id": "worker-1",
    "error": "Connection timeout"
  }'

Heartbeat (Extend Lease)

For long-running jobs, extend the lease to prevent the job from being released:

# Extend job lease (heartbeat)
curl -X POST https://api.spooled.cloud/api/v1/jobs/job_xyz123/heartbeat \
  -H "Authorization: Bearer sp_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "worker_id": "worker-1",
    "lease_duration_secs": 300
  }'

Batch Operations

Queue multiple jobs in a single API call for better performance. All jobs in a batch share the same idempotency key scope.

# Bulk enqueue up to 100 jobs
curl -X POST https://api.spooled.cloud/api/v1/jobs/bulk \
  -H "Authorization: Bearer sp_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "queue_name": "notifications",
    "jobs": [
      {"payload": {"type": "email", "to": "a@example.com"}},
      {"payload": {"type": "sms", "to": "+1234567890"}},
      {"payload": {"type": "push", "token": "abc123"}}
    ]
  }'

Scheduled Jobs

Schedule jobs for future execution. Perfect for reminders, delayed notifications, or recurring tasks.

# Schedule a job for later
curl -X POST https://api.spooled.cloud/api/v1/jobs \
  -H "Authorization: Bearer sp_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "queue_name": "reminders",
    "payload": {"type": "cart-abandoned", "user_id": "usr_123"},
    "scheduled_at": "2024-12-10T09:00:00Z"
  }'

Idempotency

Idempotency keys prevent duplicate job processing. When you create a job with an idempotency key:

  • If no job exists with that key, a new job is created
  • If a job exists and is still pending/processing, the existing job is returned
  • If a job exists and completed, the completed job is returned (no duplicate)

Best Practice

Always use meaningful idempotency keys derived from your business logic, like process-order-{orderId} or send-welcome-email-{userId}.

Working with Queues

Queues are logical groupings of related jobs. Use separate queues for different job types to enable independent scaling and monitoring.

Queue Naming

  • Use lowercase letters, numbers, and hyphens
  • Maximum 64 characters
  • Be descriptive: payment-processing, email-notifications

Recommended Queue Structure

  • High-priority queue — Critical operations (payments, security alerts)
  • Default queue — Standard background jobs
  • Low-priority queue — Analytics, cleanup, non-urgent tasks

Dashboard Tip

📍 Dashboard → Queues

What to look for:

  • Jobs pending vs processing
  • Throughput rate
  • Pause/resume controls

Actions:

  • Pause a queue during maintenance
  • Monitor queue depth for scaling decisions

Next Steps