Hatchet is an open-source distributed task queue — think Celery but with durable workflows, retries, rate limiting, and a beautiful dashboard.
Why Hatchet?
- Durable workflows: Multi-step jobs that survive crashes
- Rate limiting: Built-in concurrency and rate controls
- Retries: Automatic retry with exponential backoff
- Cron jobs: Schedule recurring tasks
- Dashboard: Real-time monitoring UI
- TypeScript-first: Full type safety
Quick Setup
npx create-hatchet@latest
# Or self-host:
docker compose up -d
Define a Worker
import Hatchet from '@hatchet-dev/typescript-sdk';
const hatchet = Hatchet.init();
const worker = await hatchet.worker('my-worker');
worker.registerWorkflow({
id: 'send-email',
description: 'Send welcome email to new user',
on: { event: 'user:created' },
steps: [
{
id: 'send',
run: async (ctx) => {
const { email, name } = ctx.workflowInput();
await sendEmail(email, `Welcome, ${name}!`);
return { sent: true };
},
},
],
});
await worker.start();
Trigger a Workflow
await hatchet.event.push('user:created', {
email: 'user@example.com',
name: 'Alice',
});
Multi-Step Workflows
worker.registerWorkflow({
id: 'process-order',
steps: [
{
id: 'validate',
run: async (ctx) => {
const order = ctx.workflowInput();
if (!order.items.length) throw new Error('Empty order');
return { valid: true };
},
},
{
id: 'charge',
parents: ['validate'],
run: async (ctx) => {
const order = ctx.workflowInput();
const charge = await stripe.charges.create({ amount: order.total });
return { chargeId: charge.id };
},
},
{
id: 'fulfill',
parents: ['charge'],
run: async (ctx) => {
const { chargeId } = ctx.stepOutput('charge');
await fulfillOrder(ctx.workflowInput().id, chargeId);
return { fulfilled: true };
},
},
],
});
Rate Limiting
{
id: 'call-api',
rateLimits: [{ key: 'api-calls', units: 1 }],
run: async (ctx) => {
return await externalApi.call(ctx.workflowInput());
},
}
Cron Schedules
worker.registerWorkflow({
id: 'daily-report',
on: { cron: '0 9 * * *' },
steps: [{
id: 'generate',
run: async () => {
const report = await generateDailyReport();
await sendSlack(report);
},
}],
});
Real-World Use Case
An e-commerce startup replaced 500 lines of custom queue code with Hatchet. Order processing went from fragile cron jobs to durable workflows with automatic retries. Failed charges now retry 3 times before alerting support.
Need to automate data collection? Check out my Apify actors for ready-made scrapers, or email spinov001@gmail.com for custom solutions.
Top comments (0)