
Prompt Chain Design Patterns: Sequential vs Conditional vs Parallel
Sequential, conditional, and parallel chains all move data and control from one AI step to the next, but they do it differently, and real workflows often mix all three rather than pick just one. Sequential chains hand output straight down a fixed line of nodes; conditional chains route execution down one of two branches based on a live rule; parallel chains fork into independent branches and merge the results back into one shared scope. The right topology to reach for depends on the shape of the task — how much of it is fixed in advance, and where it genuinely needs to branch or fan out — not on habit or which node type happens to be most familiar.
What a Chain Topology Actually Is
A chain's topology is the pattern its nodes connect in — not what any individual node does, but how control and data move between nodes once the chain starts running.
A prompt chain topology is the shape formed by how its nodes connect: sequential runs one node after another in a straight line, conditional branches execution on a rule, and parallel forks into independent branches and rejoins them — independent of what any single node's own instruction does.
Every real chain combines a topology with node content — a prompt, component, custom, or ai_process node still needs its own instruction regardless of which topology wires it in. The topology decision and the content decision are separate, and getting the topology wrong is what makes a chain hard to reason about even when every individual node's instruction is well-written.
Sequential Chains
Sequential is the default and the simplest topology: each node's outgoing connection wires it to exactly one next node, and the chain runs in a straight line from its input node to its output node. A node's output becomes available to every later node through the chain's shared variable scope, addressed by one of four reference forms:
{{input.fieldName}}— a field from the chain's original input, unchanged for the whole run{{nodeId.output}}— a specific earlier node's full output, addressed by that node's own id{{nodeId.output.fieldName}}— a nested field inside that node's output, when the output is an object{{previousNode.output}}— whatever the immediately preceding node produced, without needing to know its id
Each node's content is resolved against the shared scope right before it runs, which is what makes a sequential chain's data flow explicit rather than implicit: a downstream node names exactly which earlier result it needs. The one behavior worth knowing before you build a long sequential chain is what happens when a reference doesn't resolve — a typo'd node id, or a field that doesn't exist on that node's output. PromptHub doesn't throw in that case; the unresolved {{...}} text is left in the string unchanged. That means a broken reference fails visibly, as literal {{...}} text sitting in your output where a real value should be, instead of crashing the run partway through. It's a deliberate fail-visible design, not a bug — but it also means a broken reference in a long sequential chain can silently produce garbage output rather than an error you'd notice immediately, so it's worth spot-checking a new chain's early runs for stray {{...}} text.
Conditional Chains
A condition node evaluates a rule — or, for advanced cases, an expression — against the chain's current variable scope and routes execution down one of two labelled outgoing connections, conditional_true or conditional_false, based on the result.
The condition evaluator supports four operator families, all evaluated against live values pulled from the scope at the moment the condition node runs:
- Comparison operators —
equals,not_equals,greater_than,greater_than_or_equals,less_than,less_than_or_equals. - String operators —
contains,not_contains,starts_with,ends_with,matches_regex. - Existence operators —
is_empty,is_not_empty,is_null,is_not_null. - Boolean and collection operators —
is_true,is_false,in_list,not_in_list,array_contains,array_length_equals.
One behavior is easy to miss and worth building around deliberately: a condition node left with no rules and no groups configured at all is treated as always-true by the evaluator. That's a deliberate design choice — an unconfigured condition doesn't silently break the chain by routing nowhere — but it also means an accidentally-empty condition node won't surface as an error. If a branch you expect to sometimes skip is always running, check that the condition node actually has rules attached before assuming the logic itself is wrong.
Parallel Chains
A parallel_start node forks execution into multiple branches that run independently; a parallel_end node is the corresponding join point, where the fork's branches converge and their combined outputs merge into the shared scope as one entry. Parallel topology is how you fan work out — run several independent steps side by side that don't depend on each other's results — and then fan it back in before continuing to whatever comes after the join.
The node types that make this work are exactly parallel_start and parallel_end — there's no separate "branch" node type; a branch is just whatever sequence of nodes sits between the fork and the join on one path. Because each branch runs independently until the join, parallel topology is the right shape when the steps genuinely don't need each other's output mid-flight — reach for it to cut wall-clock time on independent work, not to express steps that secretly depend on one another's results, which belongs in a sequential chain instead.
Choosing a Topology
| Pattern | Use when | Watch out for |
|---|---|---|
| Sequential | Each step genuinely needs the previous step's result, and the order is fixed | A single broken {{...}} reference fails visibly but silently — no error, just unresolved text in the output |
| Conditional | The chain needs to skip or select between two different downstream paths based on a real, checkable rule | An accidentally-empty condition node evaluates as always-true rather than raising an error |
| Parallel | Two or more steps are genuinely independent of each other and only need to reconverge afterward | Every parallel_start needs a matching parallel_end, and only work with no cross-branch dependency belongs inside the fork |
| Mixing topologies | Most real chains — a parallel section feeding into a conditional branch feeding into a sequential tail | Mixing adds real structure to reason about; only combine topologies where the task's actual seams justify it, not by default |
Guardrails Every Topology Inherits
Every guardrail below applies uniformly regardless of which topology (or mix of topologies) a chain uses — none of them is specific to sequential, conditional, or parallel chains alone:
- A chain with more than 50 nodes is rejected outright, before a
ChainExecutionrow is even created. - Every chain is checked for cycles ahead of time; a chain containing one is rejected with a
cycle_detectederror naming the cycle path, rather than being allowed to loop. - A user can have at most 3 chain executions running concurrently; a fourth attempt is rejected with a
concurrency_limiterror. - Nesting depth — the case where a chain's Agent node calls back into another chain, which could itself contain another Agent node — is capped at 3 levels, checked before any database read.
- A defense-in-depth execution-count backstop caps any single run at 1,000 total node executions and 10 executions of the same node, a ceiling today's upfront cycle detection and node-count cap should make unreachable for a well-formed chain, kept as a second line of defence rather than a primary one.
- Every run carries a wall-clock execution budget of 4 minutes by default. A run that exceeds it doesn't fail outright — it detaches into a background continuation on the same server process and keeps writing results until it finishes or hits a hard failure.
- If a chain is edited or auto-saved while it's still executing, the in-flight run's node references go stale; the engine detects that specific case and fails with a
stale_chain_stateerror asking you to run the chain again, rather than surfacing a raw database error. - Every guard failure carries one of a fixed set of structured codes —
not_found,forbidden,invalid_chain,cycle_detected,execution_limit,insufficient_tokens,concurrency_limit,stale_chain_state— so a calling client can handle each case distinctly instead of parsing a free-text error string.
Composite Steps: Fewer Nodes, Same Behavior
Every topology above assumes a node's content comes from a promptId or componentId reference, or from typed-in custom content. There's a fourth option that changes what a single node carries rather than how nodes connect: a prompt, component, custom, ai_process, or agent node can carry an attached Skill directly — and, specifically on an agent node, a Prompt as well — instead of wiring a dedicated Skill node ahead of it.
Under the hood, the ChainNode model carries skillId and agentId as independent optional fields alongside the pre-existing promptId and componentId, so a single node can compose a Prompt's content, a Skill's system-level instructions, and — for the Agent case — an Agent's own tool access, without wiring three separate nodes and threading variables between them by hand. This composes with every topology above unchanged: a Composite Step node still participates in a sequential line, a conditional branch, or a parallel fork exactly like any other node — it just does more per node, which means fewer total nodes to keep under the 50-node ceiling and fewer seams for a variable reference to break across.
Picking the Right Shape for Your Chain
None of these topologies is a default you should reach for out of habit. Start from the actual seams in the task — where a result genuinely needs to be inspected, branched on, or run independently of another step — and let the topology follow from that, mixing sequential, conditional, and parallel sections in the same chain where the task's real shape calls for it.
For the fuller picture — what a chain is versus a single prompt or an Agent, how much a chain costs to run, and a step-by-step first-chain walkthrough — see the complete guide to prompt chains. Create a free account to build any of these topologies against your own prompts, components, and skills.