Skip to content

Getting Started

Get your first task queue running in under 5 minutes.

Installation

sh
npm install taskora ioredis
sh
yarn add taskora ioredis
sh
pnpm add taskora ioredis
sh
bun add taskora ioredis

Create Your Instance

Every taskora project starts with an instance — the central registry that holds your tasks, adapters, and configuration.

ts
import { createTaskora } from "taskora"
import { redisAdapter } from "taskora/redis"

const taskora = createTaskora({
  adapter: redisAdapter("redis://localhost:6379"),
})

The adapter can accept a Redis URL string, an ioredis options object, or an existing ioredis instance.

Redis tuning for production

For best memory efficiency, set hash-max-listpack-value 1024 in your Redis config. This keeps job hashes in compact encoding for payloads up to ~1 KB. See Performance for details.

Define a Task

A task is a named function that processes data. Taskora infers the input and output types from your handler.

ts
const sendEmailTask = taskora.task(
  "send-email",
  async (data: { to: string; subject: string; body: string }) => {
    // Your email sending logic
    const messageId = await mailer.send(data)
    return { messageId }
  },
)

Dispatch a Job

Call dispatch() to enqueue a job. It returns a ResultHandle immediately — no await needed to enqueue.

ts
const handle = sendEmailTask.dispatch({
  to: "user@example.com",
  subject: "Welcome!",
  body: "Thanks for signing up.",
})

// The handle is thenable — await it to get the job ID
const jobId = await handle // "550e8400-e29b-41d4-a716-446655440000"

// Or wait for the actual result
const result = await handle.result // { messageId: "..." }

Start the Worker

Call taskora.start() to begin processing jobs. Workers automatically pick up jobs from Redis using blocking dequeue (BZPOPMIN) — no polling overhead.

ts
await taskora.start()

Graceful Shutdown

ts
process.on("SIGTERM", async () => {
  await taskora.close() // waits for active jobs to finish
})

Add Retry Logic

Tasks can be configured with retry policies for automatic error recovery.

ts
const sendEmailTask = taskora.task("send-email", {
  retry: {
    attempts: 3,
    backoff: "exponential",
    delay: 1000,
  },
  handler: async (data: { to: string; subject: string }) => {
    return await mailer.send(data)
  },
})

Full Example

Here's a complete working example:

ts
import { createTaskora } from "taskora"
import { redisAdapter } from "taskora/redis"

const taskora = createTaskora({
  adapter: redisAdapter("redis://localhost:6379"),
  defaults: {
    retry: { attempts: 3, backoff: "exponential", delay: 1000 },
    timeout: 30_000,
    concurrency: 5,
  },
})

const processImageTask = taskora.task("process-image", {
  timeout: 60_000,
  concurrency: 2,
  handler: async (data: { url: string; width: number }, ctx) => {
    ctx.log.info("Starting image processing", { url: data.url })
    ctx.progress(0)

    const image = await downloadImage(data.url)
    ctx.progress(50)

    const resized = await resize(image, data.width)
    ctx.progress(100)

    return { path: resized.path, size: resized.size }
  },
})

// Dispatch
const handle = processImageTask.dispatch({ url: "https://example.com/photo.jpg", width: 800 })

// Monitor progress
handle.on?.("progress", (p) => console.log(`Progress: ${p}%`))

// Wait for result
const result = await handle.result
console.log("Done:", result.path)

// Start workers
await taskora.start()

Next Steps

Released under the MIT License.