Skip to content

Queue

The queue module lets you dispatch work to a background queue and process it asynchronously. This is useful for sending emails, resizing images, syncing data, or any task that should not block an HTTP response.

Import

ts
import { createQueue } from '@loewen-digital/fullstack/queue'

Basic usage

ts
import { createQueue } from '@loewen-digital/fullstack/queue'

const queue = createQueue({ driver: 'memory' })

// Define a job handler
queue.register('send-welcome-email', async (payload: { userId: number }) => {
  const user = await db.query.users.findFirst({ where: (u, { eq }) => eq(u.id, payload.userId) })
  await mail.send({ to: user.email, subject: 'Welcome!', text: 'Thanks for joining.' })
})

// Dispatch a job
await queue.dispatch('send-welcome-email', { userId: 42 })

Job options

ts
await queue.dispatch('send-welcome-email', { userId: 42 }, {
  delay: 5000,      // delay in milliseconds before the job becomes available
  retries: 3,       // retry up to 3 times on failure
  priority: 10,     // higher priority jobs run first
})

Processing jobs

In a dedicated worker process or a background task:

ts
// Process jobs continuously
await queue.work()

// Process a single batch and exit
await queue.runOnce()

Error handling

ts
queue.onError(async (error, job) => {
  logger.error('Job failed', { job: job.name, payload: job.payload, error })
})

Driver options

DriverDescription
memoryIn-process queue. Jobs are lost on restart. Good for development and tests.
databasePersists jobs to the database. No extra infrastructure needed.
redisHigh-performance Redis-backed queue. Requires ioredis.

Config options

OptionTypeDefaultDescription
driver'memory' | 'database' | 'redis'Queue driver
concurrencynumber1Number of jobs to process concurrently
retriesnumber3Default retry count for failed jobs
retryDelaynumber5000Milliseconds between retry attempts
redis.urlstringRedis connection URL
database.tablestring'jobs'Database table name for queued jobs