Common patterns for web apps that need background processing.
Modern web apps need to handle tasks that are too slow for a request-response cycle. Instead of blocking users or managing complex worker infrastructure, offload work to Prikke.
Schedule follow-up emails without managing queues or workers. Perfect for serverless platforms where you can't run background processes.
// When user signs up, schedule welcome sequence
await fetch('https://api.prikke.io/jobs', {
method: 'POST',
headers: {
'Authorization': `Bearer ${PRIKKE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: `welcome-email-${userId}`,
url: `https://myapp.com/api/send-welcome`,
run_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
body: JSON.stringify({ userId, step: 1 })
})
});
Generate PDFs, exports, or analytics reports without timing out. Return immediately to the user and process in the background.
// API route that triggers report generation
export async function POST(request) {
const { reportId, userId } = await request.json();
// Schedule the heavy work
await prikke.createJob({
name: `report-${reportId}`,
url: `${process.env.APP_URL}/api/generate-report`,
run_at: new Date().toISOString(), // Run immediately
body: JSON.stringify({ reportId, userId })
});
return Response.json({
status: 'processing',
message: "We'll email you when it's ready"
});
}
Receive webhooks from third-party services and process them reliably. Don't lose events when your server is slow or down.
// Stripe webhook handler - acknowledge fast, process later
export async function POST(request) {
const event = await request.json();
// Store event and schedule processing
await db.webhookEvents.insert(event);
await prikke.createJob({
name: `stripe-${event.id}`,
url: `${process.env.APP_URL}/api/process-stripe`,
run_at: new Date().toISOString(),
body: JSON.stringify({ eventId: event.id })
});
// Return 200 immediately so Stripe doesn't retry
return Response.json({ received: true });
}
Replace cron jobs running on your server with managed, observable scheduling.
Process recurring billing, send renewal reminders, and handle failed payments automatically.
// Run daily at 6 AM UTC
{
"name": "process-renewals",
"url": "https://myapp.com/api/billing/renewals",
"cron": "0 6 * * *"
}
Clean up old records, aggregate analytics, update materialized views, or sync data between systems.
// Cleanup old sessions every night at 2 AM
{
"name": "cleanup-sessions",
"url": "https://myapp.com/api/maintenance/sessions",
"cron": "0 2 * * *"
}
// Aggregate daily stats every hour
{
"name": "hourly-stats",
"url": "https://myapp.com/api/analytics/aggregate",
"cron": "0 * * * *"
}
Monitor your services and external dependencies. Get alerted when something breaks.
// Check external APIs every 15 minutes
const job = {
name: "healthcheck-stripe",
url: "https://myapp.com/api/health/stripe",
cron: "*/15 * * * *"
};
// Your endpoint checks and alerts
export async function POST(request) {
const stripeHealth = await checkStripe();
if (!stripeHealth.ok) {
await sendSlackAlert('Stripe API is down');
}
return Response.json({ ok: stripeHealth.ok });
}
Keep inventory in sync across multiple sales channels without manual intervention.
// Sync inventory every 30 minutes
{
"name": "sync-inventory",
"url": "https://myapp.com/api/inventory/sync",
"cron": "*/30 * * * *"
}
Send shipping updates, request reviews, or trigger loyalty rewards after purchase.
// When order ships, schedule review request for 7 days later
await prikke.createJob({
name: `review-request-${orderId}`,
url: 'https://myapp.com/api/reviews/request',
run_at: addDays(new Date(), 7).toISOString(),
body: JSON.stringify({ orderId, customerId })
});
They don't survive server restarts, can't run on serverless, and you have no visibility into what's scheduled.
Works for simple cases, but you're building and maintaining job infrastructure instead of your product.
Great for high-throughput, but overkill for most apps. You need workers, retry logic, dead letter queues, monitoring...
Limited to fixed schedules, no one-time jobs, no retry logic, no execution history, and you're locked to one platform.