A simple job queue system for managing and processing asynchronous tasks with rate limiting, and cross-platform persistence.
- Features
- Installation
- Basic Usage
- Rate Limiting Strategies
- Storage Backends
- API Overview
- Testing
- License
- Multiple storage backends (In-Memory, IndexedDB, SQLite, PostgreSQL)
- Rate limiting strategies (Concurrency, Delay, Composite)
- Job prioritization and retry logic
- Progress tracking and event listeners
- Cross-platform support (Browser, Node.js, Bun)
- TypeScript-first implementation
bun add @ellmers/job-queue
import { Job, InMemoryJobQueue } from "@ellmers/job-queue";
// Define your job type
interface MyJobInput {
data: string;
}
interface MyJobOutput {
result: number;
}
class MyJob extends Job<MyJobInput, MyJobOutput> {
async execute(input: MyJobInput): Promise<MyJobOutput> {
return { result: input.data.length };
}
}
// Create queue with in-memory storage
const queue = new InMemoryJobQueue<MyJobInput, MyJobOutput, MyJob>("my-queue", MyJob, {
limiter: new ConcurrencyLimiter(5), // 5 concurrent jobs
deleteAfterCompletionMs: 60_000, // clean up completed jobs after 1 minute
deleteAfterFailureMs: 86_400_000, // clean up failed jobs after 1 day
});
await queue.start();
await queue.start();
await queue.stop();
await queue.reset();
const job = new Job({
input: { data: "process-me" },
maxRetries: 3,
});
const jobId = await queue.add(job);
queue.on("job_start", (queueName, jobId) => {
console.log(`Job ${jobId} started in ${queueName}`);
});
queue.on("job_progress", (queueName, jobId, progress) => {
console.log(`Job ${jobId} progress: ${progress}%`);
});
import { CompositeLimiter, ConcurrencyLimiter, DelayLimiter } from "@ellmers/job-queue";
const limiter = new CompositeLimiter([
new ConcurrencyLimiter(5), // Max 5 concurrent jobs
new DelayLimiter(100), // Minimum 100ms between job starts
]);
InMemoryRateLimiter
- Rate limiter using in-memory storageSqliteRateLimiter
- Rate limiter using SQLite storagePostgresRateLimiter
- Rate limiter using PostgreSQL storage
import { ConcurrencyLimiter } from "@ellmers/job-queue";
const limiter = new ConcurrencyLimiter(15); // Max 15 jobs at a time
import { DelayLimiter } from "@ellmers/job-queue";
const limiter = new DelayLimiter(100); // Minimum 100ms between job starts
import { Job, InMemoryJobQueue, InMemoryRateLimiter } from "@ellmers/job-queue";
const queue = new InMemoryJobQueue<MyJobInput, MyJobOutput>("browser-queue", Job, {
limiter: new InMemoryRateLimiter(10, 1), // 10 jobs/second
});
// equivalent example on how to use the storage class directly
import { Job, JobQueue, InMemoryRateLimiter } from "@ellmers/job-queue";
import { InMemoryQueueStorage } from "@ellmers/storage";
const queue = new JobQueue<MyJobInput, MyJobOutput>("browser-queue", Job, {
storage: new InMemoryQueueStorage("browser-queue"),
limiter: new InMemoryRateLimiter(10, 1), // 10 jobs/second
});
import { IndexedDbJobQueue, IndexedDbRateLimiter } from "@ellmers/job-queue";
const queue = new IndexedDbJobQueue<MyJobInput, MyJobOutput>("browser-queue", Job, {
limiter: new InMemoryRateLimiter(10, 1), // 10 jobs/second
});
import { SqliteJobQueue, SqliteRateLimiter } from "@ellmers/job-queue";
const queue = new SqliteJobQueue(db, "sqlite-queue", Job, {
limiter: new SqliteRateLimiter(10, 1), // 10 jobs/second
});
import { PostgresJobQueue, PostgresRateLimiter } from "@ellmers/job-queue";
const queue = new PostgresJobQueue(postgresPool, "pg-queue", Job, {
limiter: new PostgresRateLimiter(10, 1), // 10 jobs/second
});
Job
: Base job class with progress tracking and retry logicJobQueue
: Main queue management classIJobQueue
: Interface for queue implementations
ConcurrencyLimiter
: Limits concurrent job executionsDelayLimiter
: Enforces minimum delay between jobsCompositeLimiter
: Combines multiple limitersNullLimiter
: No-op limiter for developmentInMemoryRateLimiter
: Rate limiter using in-memory storageIndexedDbRateLimiter
: Rate limiter using IndexedDB storageSqliteRateLimiter
: Rate limiter using SQLite storagePostgresRateLimiter
: Rate limiter using PostgreSQL storage
InMemoryJobQueue
- Volatile memory storage usingInMemoryQueueStorage
IndexedDbJobQueue
- Browser persistent storage usingIndexedDbQueueStorage
SqliteJobQueue
- Local SQLite storage usingSqliteQueueStorage
PostgresJobQueue
- PostgreSQL persistent storage usingPostgresQueueStorage
Run all tests:
bun test
Apache 2.0 - See LICENSE for details