Overview
When a schedule fires or you manually trigger a workflow, Spark creates a Task record that tracks the execution from start to finish. This document explains the complete task lifecycle, from creation to completion or failure.Task Lifecycle States
Tasks in Spark progress through several states:State Definitions
| State | Meaning | Database Fields Updated |
|---|---|---|
| pending | Task created, waiting for worker | status='pending', created_at |
| running | Worker is executing the workflow | status='running', started_at, tries incremented |
| completed | Workflow executed successfully | status='completed', completed_at, output_data |
| failed | Execution failed after max retries | status='failed', completed_at, error |
Task Creation
Tasks are created in two ways:1. From Schedules
When Celery Beat detects a due schedule, it queues a Celery task that creates a Task record:2. Manual Execution
When you trigger a workflow via API or CLI:Worker Task Pickup
Workers continuously poll the Redis queue for new tasks using Celery’s task protocol.How Redis Queue Works
Worker Configuration
Workers are configured to process tasks one at a time:prefetch_multiplier=1?
- Ensures fair distribution across workers
- Prevents one worker from hogging all tasks
- Better for long-running workflow executions
Task Execution Flow
Once a worker picks up a task, here’s the complete execution flow:Step-by-Step Breakdown
Step 1: Get Task and Update Status
Step 2: Get Workflow Source
Step 3: Create Adapter
Spark uses the adapter pattern to support different workflow sources (LangFlow, Hive):Step 4: Execute Workflow
- Authentication with the workflow source
- Input transformation (convert input_data to source-specific format)
- API request to execute the workflow
- Output normalization (convert response to standard format)
- Error handling (catch and format errors)
Step 5: Handle Result
Input/Output Handling
Input Data
Input data flows from the schedule or API request to the workflow source:-
LangFlow: Input becomes the message for the ChatInput component
-
Hive: Input becomes the prompt for agent/team/workflow
Output Data
Output data is normalized by adapters and stored intask.output_data:
output_data field can store up to 10,000 characters in PostgreSQL. Larger outputs are truncated.
Retry Logic
Spark implements automatic retry logic for failed tasks:Default Retry Configuration
Retry Decision Flow
Retry Implementation
Backoff Strategy
Celery’s built-in retry policy adds delays between attempts:- Attempt 1: Execute immediately (t=0s)
- Attempt 2: Wait 0.2s, retry (t=0.2s)
- Attempt 3: Wait 0.2s, retry (t=0.4s)
- After 3 retries: Mark as failed (t=0.6s)
Manual Retry
You can manually retry a failed task via API or CLI:Error Capture
When a task fails, Spark captures detailed error information:Error Storage
Error Logging
Errors are logged at multiple levels:Common Error Types
| Error Type | Cause | Resolution |
|---|---|---|
| Connection Error | Can’t reach workflow source | Check source URL and network connectivity |
| Authentication Error | Invalid API key | Verify API key in source configuration |
| Workflow Not Found | Remote flow ID doesn’t exist | Re-sync the workflow from the source |
| Input Validation Error | Invalid input format | Check input_data format for the source type |
| Execution Timeout | Workflow takes too long | Increase timeout or optimize workflow |
| Rate Limit Error | Too many requests to source | Add delay between tasks or scale workers |
Viewing Error Details
Result Storage
Task results are stored in theoutput_data field of the Task record.
Storage Format
Database Schema
Accessing Results
Result Retention
Task results are stored indefinitely by default. You can implement cleanup:Performance Characteristics
Typical Task Timing
| Phase | Duration | Notes |
|---|---|---|
| Queue to pickup | 0.1-2s | Depends on worker availability |
| Status update | 10-50ms | Database write |
| Adapter invocation | 5-20ms | Object creation overhead |
| Workflow execution | 1-30s | Depends on workflow complexity |
| Result storage | 10-50ms | Database write |
| Total | 1-35s | For typical workflows |
Scaling Considerations
-
Workers: Run multiple workers to handle concurrent tasks
-
Database connections: Each worker uses a connection pool
-
Redis queue depth: Monitor queue length
Debugging Task Execution
Task Not Running?
-
Check worker is running:
-
Check Redis queue:
-
Check task status:
-
Check worker logs:
Task Stuck in “running”?
-
Worker crashed during execution
- Task remains in “running” state
- Manually update:
UPDATE tasks SET status='failed' WHERE id='...'
-
Long-running workflow
- Check if workflow source is still processing
- Consider increasing timeout
High Failure Rate?
-
Check workflow source health:
-
Review error patterns:
-
Adjust retry settings:
Source Code References
- TaskRunner:
automagik_spark/core/scheduler/task_runner.py - WorkflowManager:
automagik_spark/core/workflows/manager.py - Celery tasks:
automagik_spark/core/tasks/workflow_tasks.py - Task model:
automagik_spark/core/database/models.py
Next Steps
- Learn about Adapter System to understand workflow execution
- See Scheduling Internals for how tasks are created from schedules
- Explore Scaling Production for handling high task volumes

