Pidgey
Type-safe background jobs that start simple and scale when you need them.
Pidgey is a progressive job queue for TypeScript developers. Start with SQLite for zero-setup development, use your existing PostgreSQL database in production, and scale to Redis when you need it—all with the same code.
Key Features
🎯 Type-Safe Everything
Full end-to-end type inference from job definition to enqueueing. TypeScript catches errors before they reach production.
export const sendEmail = pidgey.defineJob({
name: 'send-email',
handler: async (data: { to: string; subject: string }) => {
await emailService.send(data);
},
});
// ✅ Full autocomplete and type checking
await sendEmail.enqueue({
to: 'leslie.knope@pawnee.gov',
subject: 'Welcome!',
});🔄 Progressive Enhancement
Start simple, add complexity only when needed. Same code, just change your adapter:
// Week 1: Development with SQLite
const pidgey = Pidgey({ adapter: 'sqlite' });
// Month 1: Production with PostgreSQL
const pidgey = Pidgey({ adapter: 'postgres', connection: DATABASE_URL });
// Month 6: High throughput with Redis
const pidgey = Pidgey({ adapter: 'redis', options: { host: 'redis' } });Your jobs, handlers, and application code never change.
⚡ Next.js Native
File-based job discovery—just like Next.js routes. One file per job, automatic discovery. Plus Server Actions support and zero-config setup for App Router.
'use server';
import { sendEmail } from '@/jobs/send-email';
export async function signup(email: string) {
await sendEmail.enqueue({ to: email, subject: 'Welcome!' });
}Run npx pidgey worker dev and all jobs in your jobs/ directory are automatically discovered.
Quick Start
npm install @pidgeyjs/core @pidgeyjs/next @pidgeyjs/sqlite1. Create config and client:
export default defineConfig({ adapter: 'sqlite', filename: './pidgey.db' });import { Pidgey } from '@pidgeyjs/next';
import config from '../pidgey.config';
export const pidgey = Pidgey(config);2. Define a job:
import { pidgey } from '@/lib/pidgey';
export const sendEmail = pidgey.defineJob({
name: 'send-email',
handler: async (data: { to: string; subject: string }) => {
console.log(`Sending email to ${data.to}`);
return { sent: true };
},
});3. Enqueue from anywhere:
await sendEmail.enqueue({ to: 'leslie.knope@pawnee.gov', subject: 'Welcome!' });4. Start the worker:
npx pidgey worker devWhy Pidgey?
Most job queue solutions force you to choose between simplicity and scalability:
- Managed services — Great DX but vendor lock-in and monthly bills
- Redis-based queues — Powerful but require infrastructure before you write your first job
- Postgres-native queues — Database-backed but no escape hatch when you outgrow them
Pidgey gives you both: Start with zero infrastructure, scale without rewriting.
What You Get
- ✅ Automatic retries with exponential backoff
- ✅ Scheduled (cron) jobs with pause/resume support
- ✅ Delayed job scheduling
- ✅ Concurrency control
- ✅ Job lifecycle hooks and status tracking
- ✅ Multiple queue support
- ✅ Type-safe job definitions
- ✅ Failed job tracking and bulk retry
- ✅ Self-hosted (your infrastructure, your data)
Next Steps
- Getting Started — Complete installation and setup guide
- Deployment — Deploy your app and workers to production
- Why Pidgey? — Learn about progressive scaling and see detailed comparisons
- API Reference — Explore the full API
- Adapters — Choose your database backend