mech.app

The mech.app newsletter

Agentic AI, minus the noise.

Get practical field notes on AI agents, automation, developer tools and security delivered to your inbox.

No spam. Unsubscribe anytime.

Dev Tools

Swarm vs. Pipeline vs. Graph: How Choosing the Wrong Agent Orchestration Topology Costs Six Months

Decision framework for selecting agent orchestration patterns based on task structure, coordination overhead, and failure modes with real rebuild costs.

Source: dev.to
Swarm vs. Pipeline vs. Graph: How Choosing the Wrong Agent Orchestration Topology Costs Six Months

The author spent six months building a swarm for a task that was secretly a directed acyclic graph. Not six months of iteration. Six months of building, debugging, rewriting the coordination layer, adding tracing that was never needed, and watching a system that should have been deterministic behave like weather.

The task was document processing: extract, validate, enrich, summarize, format. Five stages. Genuinely sequential. The swarm version used peer-to-peer negotiation between agents. The pipeline rewrite took three weeks and was faster, cheaper, and more reliable.

The swarm wasn’t wrong as an architecture. It was wrong for the task. That mismatch is the cost nobody warns you about.

The Coordination Tax

A March 2026 controlled study tested four coordination architectures on identical software engineering tasks with a fixed $50 budget and the same LLM:

  • Single agent: 28 of 28 tasks succeeded
  • Hierarchical coordination: 18 of 28 tasks succeeded
  • Self-organized swarm: 32% success rate
  • Gated pipeline: never produced implementation code, consumed entire budget on planning phases

The hierarchy didn’t fail because the model was weak. It failed because coordination complexity introduces information loss that compounds at every handoff. The single agent retained 85.8% of the original specification entropy at verification. The hierarchy retained 25.8%. Three-quarters of the task intent was lost in translation.

This is not a model problem. It’s a topology problem.

Three Orchestration Patterns

Pipeline (Sequential DAG)

A pipeline is a directed acyclic graph where each node executes after its dependencies complete. State flows forward. Retry happens at the node level.

Runtime characteristics:

  • Deterministic execution order
  • No message passing overhead between stages
  • State is immutable once a stage completes
  • Retry semantics are local to the failing node
  • Observability is linear: you can trace a single execution path

Failure modes:

  • Brittle when dependencies are actually conditional
  • No parallelism unless you explicitly fork the DAG
  • Upstream failures cascade downstream without negotiation

When to use:

  • Task has clear sequential dependencies
  • Each stage produces a well-defined artifact for the next stage
  • You need deterministic replay for debugging or compliance

Swarm (Peer-to-Peer Coordination)

A swarm is a collection of agents that coordinate through message passing or shared state. No central orchestrator. Agents negotiate task allocation and synchronization.

Runtime characteristics:

  • Non-deterministic execution order
  • High message passing overhead (agents poll or subscribe to state changes)
  • State synchronization requires consensus or eventual consistency
  • Retry semantics are distributed: one agent’s failure may trigger renegotiation across the swarm
  • Observability requires distributed tracing across all agents

Failure modes:

  • Coordination overhead dominates when task is actually sequential
  • Debugging requires reconstructing causal chains from message logs
  • Emergent behavior can be non-reproducible

When to use:

  • Task decomposition is unknown at design time
  • Agents need to adapt to changing conditions (resource availability, partial failures)
  • Parallelism is essential and dependencies are sparse

Graph (Conditional DAG with Dynamic Routing)

A graph is a DAG where edges can be conditional and nodes can spawn new subgraphs at runtime. State flows forward but routing decisions happen dynamically.

Runtime characteristics:

  • Execution order is partially deterministic (fixed topology, conditional edges)
  • Message passing overhead is lower than swarm (only at decision points)
  • State is versioned: conditional branches may need to reconcile divergent state
  • Retry semantics are hybrid: local retries for nodes, global retries for subgraphs
  • Observability requires tracking which branches were taken

Failure modes:

  • Complexity explodes if you add too many conditional edges
  • State reconciliation bugs when branches merge
  • Harder to reason about than a pure pipeline, more brittle than a swarm

When to use:

  • Task has known stages but routing between stages depends on runtime conditions
  • You need determinism for the happy path but flexibility for edge cases
  • Parallelism is needed but only within bounded subgraphs

Topology Mismatch Detection

You can detect topology mismatch during development by measuring coordination overhead relative to task execution time.

Pipeline mismatch signals:

  • Agents are waiting idle because they can’t start until a sequential dependency completes, but the dependency is actually optional
  • You’re adding conditional logic to skip stages, which means you need a graph

Swarm mismatch signals:

  • Agents are negotiating task allocation but always converge to the same assignment (the task is deterministic)
  • Message passing latency exceeds task execution time
  • You’re adding sequence numbers or causal ordering to messages (you need a pipeline)

Graph mismatch signals:

  • You have more than three conditional branches per decision point (you need a swarm to explore the space)
  • State reconciliation logic is more complex than the task logic (you need a pipeline with explicit forks)

Architecture: Pipeline with Escape Hatches

For most document processing, data transformation, and multi-step reasoning tasks, start with a pipeline and add conditional edges only when runtime data forces it.

from typing import Protocol, TypeVar, Generic
from dataclasses import dataclass
from enum import Enum

T = TypeVar('T')

class StageResult(Generic[T]):
    """Immutable result from a pipeline stage."""
    data: T
    metadata: dict
    next_stage: str | None  # None = terminal

class Stage(Protocol[T]):
    def execute(self, input: T) -> StageResult[T]:
        """Execute stage logic. Raise on failure."""
        ...

class PipelineExecutor:
    def __init__(self, stages: dict[str, Stage]):
        self.stages = stages
        self.trace = []  # Linear execution log
    
    def run(self, initial_data, start_stage: str):
        current_stage = start_stage
        data = initial_data
        
        while current_stage:
            stage = self.stages[current_stage]
            try:
                result = stage.execute(data)
                self.trace.append({
                    'stage': current_stage,
                    'status': 'success',
                    'metadata': result.metadata
                })
                data = result.data
                current_stage = result.next_stage
            except Exception as e:
                self.trace.append({
                    'stage': current_stage,
                    'status': 'failed',
                    'error': str(e)
                })
                raise
        
        return data

Key properties:

  • Each stage returns an immutable result and declares the next stage
  • Conditional routing happens inside the stage (via next_stage)
  • Trace is a linear log, not a distributed trace
  • Retry logic is external to the executor (wrap stages in retry decorators)

When to add graph semantics:

  • A stage needs to fork into parallel subgraphs (add a ForkStage that returns multiple next_stage values)
  • A stage needs to wait for multiple upstream stages (add a JoinStage that blocks until all inputs arrive)

When to switch to swarm:

  • You can’t predict the stage sequence at design time
  • Agents need to bid on tasks based on runtime resource availability

Coordination Overhead Comparison

TopologyMessage PassingState SyncRetry ScopeObservabilityDeterminism
PipelineNone (direct handoff)Immutable forward flowPer-stageLinear traceFull
GraphAt decision pointsVersioned state at joinsPer-stage or per-subgraphBranch tracePartial (conditional edges)
SwarmContinuous (polling or pub/sub)Consensus or eventual consistencyDistributed renegotiationDistributed traceNone

Failure Mode Catalog

Pipeline forced into swarm topology:

  • Agents negotiate task allocation for a task with fixed dependencies
  • Coordination latency exceeds task execution time
  • Non-deterministic execution order breaks assumptions about state availability

Swarm forced into pipeline topology:

  • Central orchestrator becomes bottleneck for task allocation
  • Agents can’t adapt to partial failures (pipeline retries entire stage)
  • Parallelism is lost because stages are artificially serialized

Graph forced into pipeline topology:

  • Conditional logic is pushed into stage code instead of topology
  • State reconciliation happens manually instead of at join nodes
  • You end up with a pipeline full of if/else branches

Graph forced into swarm topology:

  • Agents negotiate routing decisions that are actually deterministic
  • Coordination overhead for decisions that could be static

Technical Verdict

Use a pipeline when:

  • Task has sequential dependencies that are known at design time
  • Each stage produces a well-defined artifact
  • You need deterministic replay for debugging or compliance
  • Coordination overhead would exceed task execution time

Use a graph when:

  • Task has known stages but routing depends on runtime conditions
  • You need parallelism within bounded subgraphs
  • State reconciliation at merge points is simpler than swarm consensus

Use a swarm when:

  • Task decomposition is unknown at design time
  • Agents need to adapt to changing resource availability
  • Parallelism is essential and dependencies are sparse
  • You can tolerate non-deterministic execution order

Avoid:

  • Building a swarm for a task with fixed sequential dependencies (you’ll spend six months debugging coordination)
  • Building a pipeline for a task that needs runtime adaptation (you’ll end up with a pipeline full of conditional logic)
  • Building a graph with more than three conditional branches per decision point (switch to a swarm)

The rewrite from swarm to pipeline took three weeks because the task was always a DAG. The six months were spent fighting the topology, not the task.

Tags

agentic-ai orchestration infrastructure

Primary Source

dev.to ↗