Purpose: Task/workflow execution history and metrics
Column
Type
Constraints
Description
id
UUID
PK, DEFAULT uuid_generate_v4()
Task identifier
workflow_id
VARCHAR(255)
UNIQUE, NOT NULL
Temporal workflow ID
user_id
UUID
FK → users
Task creator
tenant_id
UUID
Tenant reference
session_id
VARCHAR(255)
Session identifier
query
TEXT
NOT NULL
Task query/prompt
mode
VARCHAR(50)
Execution mode (SIMPLE, STANDARD, COMPLEX)
status
VARCHAR(50)
NOT NULL
Task status
started_at
TIMESTAMPTZ
NOT NULL, DEFAULT NOW()
Start time
completed_at
TIMESTAMPTZ
Completion time
result
TEXT
Final result
response
JSONB
DEFAULT ''
Structured response
error_message
TEXT
Error details
total_tokens
INTEGER
DEFAULT 0
Total tokens used
prompt_tokens
INTEGER
DEFAULT 0
Input tokens
completion_tokens
INTEGER
DEFAULT 0
Output tokens
total_cost_usd
DECIMAL(10,6)
DEFAULT 0
Total cost
duration_ms
INTEGER
Execution time (ms)
agents_used
INTEGER
DEFAULT 0
Number of agents
tools_invoked
INTEGER
DEFAULT 0
Number of tool calls
cache_hits
INTEGER
DEFAULT 0
Cache hit count
complexity_score
DECIMAL(3,2)
Complexity (0.0-1.0)
metadata
JSONB
Additional metadata
created_at
TIMESTAMPTZ
DEFAULT NOW()
Record creation
Indexes:
idx_task_user_session ON (user_id, session_id)
idx_task_created_at ON (created_at DESC)
idx_task_status ON (status)
idx_task_workflow_id ON (workflow_id)
idx_task_executions_tenant_id ON (tenant_id)
idx_task_executions_session_id ON (session_id)
Status Values:
RUNNING - Task in progress
COMPLETED - Task finished successfully
FAILED - Task failed with error
CANCELLED - Task cancelled by user
Example:
-- Recent tasks for userSELECT workflow_id, query, status, duration_ms, total_cost_usdFROM task_executionsWHERE user_id = '...'ORDER BY started_at DESCLIMIT 20;-- Failed tasks analysisSELECT DATE(started_at) as date, COUNT(*) as failed_count, AVG(duration_ms) as avg_durationFROM task_executionsWHERE status = 'FAILED' AND started_at > NOW() - INTERVAL '7 days'GROUP BY DATE(started_at)ORDER BY date DESC;-- Cost analysisSELECT user_id, COUNT(*) as task_count, SUM(total_cost_usd) as total_cost, AVG(total_cost_usd) as avg_cost, SUM(total_tokens) as total_tokensFROM task_executionsWHERE started_at > NOW() - INTERVAL '30 days'GROUP BY user_idORDER BY total_cost DESC;
Purpose: Streaming event storage for audit and replay
Column
Type
Constraints
Description
id
UUID
PK, DEFAULT uuid_generate_v4()
Event ID
workflow_id
VARCHAR(255)
NOT NULL
Workflow identifier
task_id
UUID
Task reference (nullable)
type
VARCHAR(100)
NOT NULL
Event type
agent_id
VARCHAR(255)
Agent identifier
message
TEXT
Event message
payload
JSONB
DEFAULT ''
Event payload
timestamp
TIMESTAMPTZ
NOT NULL, DEFAULT NOW()
Event time
seq
BIGINT
Sequence number
stream_id
VARCHAR(64)
Redis stream ID
created_at
TIMESTAMPTZ
NOT NULL, DEFAULT NOW()
Record creation
Indexes:
idx_event_logs_workflow_id ON (workflow_id)
idx_event_logs_task_id ON (task_id)
idx_event_logs_type ON (type)
idx_event_logs_ts ON (timestamp DESC)
idx_event_logs_seq ON (workflow_id, seq)
idx_event_logs_workflow_ts ON (workflow_id, timestamp DESC)
uq_event_logs_wf_type_seq UNIQUE ON (workflow_id, type, seq) WHERE seq IS NOT NULL
Event Types:
task.started - Task execution started
task.completed - Task execution completed
agent.thinking - Agent processing
tool.called - Tool invocation
Example:
-- Get all events for a taskSELECT type, agent_id, message, timestampFROM event_logsWHERE workflow_id = '...'ORDER BY timestamp;-- Event frequency analysisSELECT type, COUNT(*) as event_count, DATE_TRUNC('hour', timestamp) as hourFROM event_logsWHERE timestamp > NOW() - INTERVAL '24 hours'GROUP BY type, hourORDER BY hour DESC, event_count DESC;
idx_token_usage_provider_model ON (provider, model)
idx_token_usage_task_id ON (task_id)
Example:
-- Token usage by providerSELECT provider, model, COUNT(*) as call_count, SUM(total_tokens) as total_tokens, SUM(cost_usd) as total_costFROM token_usageWHERE created_at > NOW() - INTERVAL '30 days'GROUP BY provider, modelORDER BY total_cost DESC;-- Daily token trendSELECT DATE(created_at) as date, SUM(total_tokens) as tokens, SUM(cost_usd) as costFROM token_usageWHERE created_at > NOW() - INTERVAL '30 days'GROUP BY DATE(created_at)ORDER BY date;
-- User usage summarySELECT date, total_tasks, successful_tasks, total_cost_usdFROM usage_daily_aggregatesWHERE user_id = '...' AND date > CURRENT_DATE - INTERVAL '30 days'ORDER BY date DESC;-- Aggregate metricsSELECT SUM(total_tasks) as total_tasks, SUM(total_cost_usd) as total_cost, AVG(cache_hit_rate) as avg_cache_rateFROM usage_daily_aggregatesWHERE date > CURRENT_DATE - INTERVAL '7 days';
-- Task success rate by modeSELECT mode, COUNT(*) as total, COUNT(CASE WHEN status = 'COMPLETED' THEN 1 END) as completed, ROUND(100.0 * COUNT(CASE WHEN status = 'COMPLETED' THEN 1 END) / COUNT(*), 2) as success_rateFROM task_executionsWHERE started_at > NOW() - INTERVAL '7 days'GROUP BY mode;-- Average execution time by complexitySELECT CASE WHEN complexity_score < 0.3 THEN 'Low' WHEN complexity_score < 0.7 THEN 'Medium' ELSE 'High' END as complexity, COUNT(*) as task_count, AVG(duration_ms) as avg_ms, AVG(total_cost_usd) as avg_costFROM task_executionsWHERE complexity_score IS NOT NULLGROUP BY complexity;
-- Top cost usersSELECT u.email, COUNT(t.id) as task_count, SUM(t.total_cost_usd) as total_cost, AVG(t.total_cost_usd) as avg_costFROM task_executions tJOIN users u ON t.user_id = u.idWHERE t.started_at > NOW() - INTERVAL '30 days'GROUP BY u.emailORDER BY total_cost DESCLIMIT 10;-- Cost breakdown by modelSELECT tu.provider, tu.model, COUNT(*) as usage_count, SUM(tu.total_tokens) as total_tokens, SUM(tu.cost_usd) as total_cost, AVG(tu.cost_usd) as avg_cost_per_callFROM token_usage tuWHERE tu.created_at > NOW() - INTERVAL '7 days'GROUP BY tu.provider, tu.modelORDER BY total_cost DESC;
-- Slow queries (tasks > 60 seconds)SELECT workflow_id, query, duration_ms, agents_used, tools_invokedFROM task_executionsWHERE duration_ms > 60000 AND started_at > NOW() - INTERVAL '24 hours'ORDER BY duration_ms DESC;-- Tool execution success rateSELECT tool_name, COUNT(*) as total, COUNT(CASE WHEN success THEN 1 END) as successful, ROUND(100.0 * COUNT(CASE WHEN success THEN 1 END) / COUNT(*), 2) as success_rate, AVG(duration_ms) as avg_durationFROM tool_executionsGROUP BY tool_nameORDER BY total DESC;
-- Monthly partitioning for task_executionsCREATE TABLE task_executions_2025_10 PARTITION OF task_executions FOR VALUES FROM ('2025-10-01') TO ('2025-11-01');