Production runtime shapes — pick by task, not by framework
request-response
synchronous HTTP
user waits for completion
short tasks only (<30s)
Agno, Mastra, raw SDK
OTel spans per request
fits: chat UX, tool calls
streaming
SSE / WebSocket / WebRTC
progressive output
LiveKit adds WebRTC
Pipecat, LiveKit, SDK
first-token latency matters
fits: voice, copilot UX
queue-based
producer worker pool DLQ
webhook / pubsub for results
long-horizon tasks
Celery, BullMQ, SQS
queue depth + DLQ metrics
fits: computer use, research
event + cron
trigger-based
+ scheduled
CrewAI Flows
Managed Agents
cron + durable
durable execution cross-cuts all shapes (LangGraph, AutoGen v0.4 actors, Managed Agents)
state checkpointed after every step resume picks up at exact step
actor-model fault isolation one agent crash does not crash peers
essential when step count is unknown and recovery cost is high
observability load-bearing: OTel GenAI (Lesson 23) + Langfuse/Phoenix/Opik (Lesson 24)
without spans + eval: failing at step 40 is un-debuggable; you replay from scratch
pick the shape first; the framework is a second-order choice.