Claude Code Inngest Durable Workflow for Long Running Tasks
Building applications that handle long-running tasks is a common challenge in modern software development. Whether you’re processing large datasets, running AI model inference, or coordinating complex multi-step workflows, you need a reliable way to manage state and ensure tasks complete successfully even when interruptions occur. This guide explores how to combine Claude Code with Inngest to create robust, durable workflows that handle long-running tasks with ease.
Understanding Durable Workflows
Traditional request-response HTTP patterns work well for quick operations, but many real-world tasks take minutes, hours, or even days to complete. Durable workflows solve this problem by providing a framework for:
- State persistence: Workflow progress is saved and can resume after interruptions
- Event-driven execution: Steps execute based on events rather than blocking threads
- Automatic retries: Failed steps can be automatically retried with configurable policies
- Visibility: You can track workflow status and debug issues
Inngest is a developer-friendly durable workflow platform that integrates smoothly with your existing codebase. It handles the complexity of state management, allowing you to write business logic without worrying about infrastructure.
Why Combine Claude Code with Inngest?
Claude Code brings powerful AI-assisted development capabilities to your workflow. When you combine Claude Code with Inngest, you get:
- AI-powered workflow design: Claude Code can help design and implement complex workflow logic
- Natural language debugging: Describe issues in plain English and get actionable guidance
- Code generation: Quickly scaffold Inngest workflow definitions and step functions
- Documentation assistance: Generate documentation for your workflow states and events
Getting Started with Inngest
First, install the Inngest SDK and set up your project:
npm install inngest
Create an Inngest client configuration:
import { Inngest } from 'inngest';
import { serve } from 'inngest/next';
const inngest = new Inngest({
name: 'MyApp',
eventKey: process.env.INNGEST_EVENT_KEY,
});
Building Your First Durable Workflow
Let’s create a workflow that processes a batch of items with multiple steps. This demonstrates key patterns for long-running tasks:
// Define the workflow steps
const processItemStep = inngest.step({
id: 'process-item',
name: 'Process individual item',
}, async ({ item }, { stepRunId }) => {
// Your processing logic here
const result = await processItem(item);
return { success: true, result };
});
const notifyCompletionStep = inngest.step({
id: 'notify-completion',
name: 'Send completion notification',
}, async ({ userId, totalProcessed }, { stepRunId }) => {
await sendNotification(userId, `Processed ${totalProcessed} items`);
return { notified: true };
});
// Define the workflow
const batchProcessWorkflow = inngest.createWorkflow(
'batch-process',
{
id: 'batch-process',
on: 'batch/process.started',
},
async ({ event }) => {
const items = event.data.items;
const results = [];
// Process each item, handling failures gracefully
for (const item of items) {
const result = await processItemStep.run({ item });
results.push(result);
}
// Notify completion
await notifyCompletionStep.run({
userId: event.data.userId,
totalProcessed: results.length,
});
return { completed: true, total: results.length };
}
);
Handling Long-Running Operations
For operations that take significant time, Inngest provides the sleep and waitForEvent primitives. Here’s how to use them with Claude Code assistance:
const aiAnalysisWorkflow = inngest.createWorkflow(
'ai-analysis',
{
id: 'ai-analysis',
on: 'analysis/request',
},
async ({ event }) => {
// Step 1: Queue the analysis job
const job = await inngest.step.run('queue-analysis', async () => {
return await queueAnalysisJob(event.data);
});
// Step 2: Wait for completion (could be minutes to hours)
const result = await inngest.step.waitForEvent('wait-for-result', {
event: 'analysis/completed',
timeout: '24h', // Long timeout for async processing
match: `data.jobId == "${job.id}"`,
});
if (!result) {
// Handle timeout - could retry or notify
return { status: 'timeout', jobId: job.id };
}
return { status: 'completed', result: result.data };
}
);
Error Handling and Retries
Claude Code can help you design robust error handling strategies. Here’s a pattern for implementing retries with backoff:
const robustProcessingStep = inngest.step({
id: 'robust-process',
name: 'Process with retry',
retry: {
attempts: 3,
delay: '2s',
backoff: 'exponential',
},
}, async ({ data }, { stepRunId, context }) => {
const attempt = context?.attempt || 1;
try {
return await processWithPotentialFailure(data);
} catch (error) {
// Claude Code can help analyze error patterns
if (error.code === 'RATE_LIMIT') {
// Handle rate limiting specifically
throw new RetryError('Rate limited, will retry');
}
throw error;
}
});
Best Practices for Claude Code + Inngest Integration
1. Use Descriptive Step IDs
Claude Code works best when your code is well-structured. Use clear, descriptive IDs for steps:
// Good: Descriptive IDs help Claude understand the flow
inngest.step({ id: 'validate-user-input', name: 'Validate user input' })
// Avoid: Generic IDs make debugging harder
inngest.step({ id: 'step1', name: 'Step 1' })
2. Document State Transitions
Add comments that help Claude Code understand your workflow logic:
// WORKFLOW: Order Processing
// States: pending -> payment_confirmed -> processing -> shipped -> delivered
// Events: order.placed, payment.confirmed, item.shipped, delivery.completed
// Retries: payment confirmation has 3 retries with 5s delay
3. Implement Checkpointing for Very Long Tasks
For tasks running over days or weeks, implement explicit checkpoints:
const longRunningWorkflow = inngest.createWorkflow(
'data-migration',
{ id: 'data-migration', on: 'migration/start' },
async ({ event }) => {
const { totalRecords } = event.data;
const batchSize = 1000;
let processed = 0;
while (processed < totalRecords) {
// Process batch
const batchResult = await processBatch.run({
offset: processed,
limit: batchSize,
});
// Create checkpoint - allows resume if interrupted
await inngest.step.waitForEvent('checkpoint', {
event: 'migration.checkpoint',
timeout: '1h',
match: `data.offset == ${processed + batchSize}`,
});
processed += batchResult.processed;
}
return { migrated: processed };
}
);
Monitoring and Debugging
Inngest provides a dashboard to monitor workflow execution. Combine this with Claude Code’s debugging capabilities:
- Check workflow status: Describe the error to Claude Code and get potential causes
- Analyze logs: Use Claude Code to interpret Inngest execution logs
- Plan recovery: Ask Claude Code for strategies to recover from specific failure states
Conclusion
Combining Claude Code with Inngest gives you a powerful toolkit for building reliable long-running task systems. Inngest handles the complexity of durable execution, while Claude Code assists with design, implementation, and debugging. Start with simple workflows and progressively adopt more advanced patterns as your needs grow.
The key is to use Claude Code’s strengths—understanding intent, generating code, and explaining patterns—while letting Inngest handle the heavy lifting of workflow state management. Together, they make building robust, long-running task systems accessible to developers at any level.
Related Reading
- Claude Code for Beginners: Complete Getting Started Guide
- Best Claude Skills for Developers in 2026
- Claude Skills Guides Hub
Built by theluckystrike — More at zovo.one