Configuration
Configure the Pidgey client and worker to match your needs.
Unified Configuration
Pidgey uses a single pidgey.config.ts file for both your application and the worker process.
1. Create the Config
import { defineConfig } from '@pidgeyjs/core';
export default defineConfig({
// Shared config
adapter: 'sqlite',
filename: './pidgey.db',
// Worker-specific config
worker: {
jobsDir: 'jobs',
concurrency: 10,
},
});2. Initialize the Client
Import this config in your client initialization:
import { Pidgey } from '@pidgeyjs/next';
import config from '../pidgey.config';
// Initialize the client with the shared config
export const pidgey = Pidgey(config);Adapter Configuration
Configure your storage backend in pidgey.config.ts:
SQLite
export default defineConfig({
adapter: 'sqlite',
filename: './pidgey.db', // or ':memory:'
});Options:
adapter:'sqlite'filename: Database file path (default:'./pidgey.db')
PostgreSQL
export default defineConfig({
adapter: 'postgres',
connection: process.env.DATABASE_URL,
});Options:
adapter:'postgres'connection: PostgreSQL connection string
Neon
Neon is a serverless Postgres platform that works great with Pidgey. SSL is auto-detected from your connection string.
export default defineConfig({
adapter: 'postgres',
connection: process.env.DATABASE_URL, // Neon connection string
});Advanced Pool Configuration:
export default defineConfig({
adapter: 'postgres',
connection: process.env.DATABASE_URL,
poolConfig: {
max: 10, // Adjust based on your Neon plan limits
idleTimeoutMillis: 10000,
connectionTimeoutMillis: 2000,
},
});Neon free tier includes 20 connections. The queue adapter defaults to 10 connections, and the worker adapter defaults to 20. Adjust pool sizes if running multiple workers.
Serverless Functions:
For Edge/serverless functions, consider using Neon’s serverless driver with HTTP-based connections:
import { Pool, neonConfig } from '@neondatabase/serverless';
import ws from 'ws';
neonConfig.webSocketConstructor = ws;
export default defineConfig({
adapter: 'postgres',
connection: process.env.DATABASE_URL,
});Supabase
Supabase provides managed Postgres with connection pooling. SSL is auto-detected from your connection string.
export default defineConfig({
adapter: 'postgres',
connection: process.env.DATABASE_URL, // Supabase connection string
});Using Supabase Pooler:
For production, use Supabase’s connection pooler (port 6543) for better connection management:
export default defineConfig({
adapter: 'postgres',
// Use session mode for full Postgres compatibility
connection: process.env.DATABASE_URL.replace(':5432', ':6543') + '?pgbouncer=true',
});Direct Connection for Workers:
Workers benefit from direct connections (port 5432):
export default defineConfig({
adapter: 'postgres',
connection: process.env.DATABASE_URL, // Direct connection (port 5432)
});Use Supabase Pooler for your application client and direct connections for workers by setting different environment variables.
Redis
export default defineConfig({
adapter: 'redis',
options: {
host: 'localhost',
port: 6379,
password: process.env.REDIS_PASSWORD,
},
});Options:
adapter:'redis'options: Redis connection optionshost: Redis hostport: Redis port (default: 6379)password: Redis password (optional)
Job Configuration
Configure individual jobs when defining them:
export const myJob = pidgey.defineJob({
name: 'my-job',
handler: async (data) => {
// Handler logic
},
config: {
retries: 5,
timeout: 60000,
queue: 'critical',
},
});Options:
| Option | Type | Default | Description |
|---|---|---|---|
retries | number | 3 | Max retry attempts on failure |
timeout | number | 300000 | Job timeout in milliseconds (5 minutes) |
queue | string | Job name | Queue name for grouping jobs |
Global Defaults
Set defaults for all jobs in your config:
export default defineConfig({
adapter: 'sqlite',
filename: './pidgey.db',
defaultJobOptions: {
maxAttempts: 3,
timeout: 60000,
},
worker: {
jobsDir: 'jobs',
},
});Retries
Control how many times a job retries on failure:
config: {
retries: 5, // Try up to 5 times
}Failed jobs automatically retry with exponential backoff.
Timeouts
Set maximum execution time:
config: {
timeout: 30000, // 30 seconds
}Jobs that exceed the timeout are marked as failed and retried (if retries remain).
Custom Queues
Group related jobs into queues:
export const criticalEmail = pidgey.defineJob({
name: 'critical-email',
handler: async (data) => {
/* ... */
},
config: {
queue: 'critical', // High-priority queue
},
});
export const newsletterEmail = pidgey.defineJob({
name: 'newsletter-email',
handler: async (data) => {
/* ... */
},
config: {
queue: 'low-priority', // Separate queue
},
});Run dedicated workers for each queue:
# Worker 1: Only critical jobs
pidgey worker dev --queue critical --concurrency 50
# Worker 2: Only low-priority jobs
pidgey worker dev --queue low-priority --concurrency 5Environment-Based Configuration
Use environment variables within your pidgey.config.ts to switch configurations:
import { defineConfig } from '@pidgeyjs/core';
const adapter = process.env.JOB_ADAPTER || 'sqlite';
export default defineConfig(
adapter === 'redis'
? {
adapter: 'redis',
options: {
host: process.env.REDIS_HOST!,
port: Number(process.env.REDIS_PORT || 6379),
},
}
: adapter === 'postgres'
? {
adapter: 'postgres',
connection: process.env.DATABASE_URL!,
}
: {
adapter: 'sqlite',
filename: process.env.SQLITE_FILE || './pidgey.db',
}
);Then switch via environment:
# Development
JOB_ADAPTER=sqlite npm run dev
# Production
JOB_ADAPTER=postgres DATABASE_URL=postgres://... npm start
# Scale
JOB_ADAPTER=redis REDIS_HOST=redis.internal npm startWorker CLI Options
Override worker behavior via CLI flags:
# Concurrency
pidgey worker dev --concurrency 50
# Polling interval
pidgey worker dev --poll 1000
# Specific queues
pidgey worker dev --queue emails --queue reports
# Combined
pidgey worker start --concurrency 100 --poll 5000 --queue criticalAvailable flags:
--concurrency— Max concurrent jobs--poll— Polling interval in milliseconds--queue— Process specific queues (repeatable)
Best Practices
Singleton Client
Export one client instance and import it everywhere:
export const pidgey = Pidgey({
/* ... */
});import { pidgey } from '@/lib/pidgey';
export const sendEmail = pidgey.defineJob({
/* ... */
});Separate Concerns
Different queues for different job types:
// Fast, high-priority
config: { queue: 'realtime', timeout: 5000 }
// Slow, low-priority
config: { queue: 'background', timeout: 300000 }Run dedicated workers with appropriate concurrency:
# High-priority: more workers, faster polling
pidgey worker start --queue realtime --concurrency 100 --poll 100
# Low-priority: fewer workers, slower polling
pidgey worker start --queue background --concurrency 10 --poll 5000Progressive Timeouts
Match timeout to expected job duration:
// API call: short timeout
config: {
timeout: 10000;
} // 10 seconds
// Image processing: medium timeout
config: {
timeout: 60000;
} // 1 minute
// Report generation: long timeout
config: {
timeout: 300000;
} // 5 minutesRetry Strategy
Adjust retries based on job type:
// Idempotent API call: more retries
config: {
retries: 5;
}
// Payment processing: fewer retries
config: {
retries: 2;
}
// Email sending: moderate retries
config: {
retries: 3;
}Next Steps
- Worker — Configure and deploy workers
- Adapters — Learn about storage backends
- API Reference — Full API documentation