Product design

n8n Agents: let AI choose the next step, and workflows define its execution

n8n connects applications and business processes. Agents let teams pursue cross-tool goals while configured workflows, approvals and execution records keep concrete actions under control.

Break down the problem and try your own design and implementation first. Then explore the reasoning to check states, edge cases, trade-offs, and ways to test your approach. The guide offers a reasoning path, not a complete implementation.

01
CODE EXERCISEAdvanced

How can an approval panel replay duplicate and out-of-order events?

Scenario

An approval page receives progress messages and displays states such as awaiting approval, running and awaiting confirmation. Network delivery can duplicate or reorder those messages. Design an event reducer: a rule-driven calculation of trustworthy display state. Reducing events does not send messages or repeat external actions.

Given conditions and requirements

Design an event reducer for your own approval panel. It calculates display state only; it sends no external requests and does not describe n8n's internal implementation.

  1. Every proposed action has a unique, non-empty operationId. A trusted upstream component fixes the action’s content, called its payload, such as where to send a message and what it says. Changing that content creates a new operationId. The service produces consecutive sequence numbers, starting at 1 independently for each operation.
  2. Event types are proposed, approved, rejected, started, succeeded, failed, unknown, reconciled_success and reconciled_failure. proposed must have seq=1. Valid transitions are proposed→approved or rejected; approved→started; started→succeeded, failed or unknown; unknown→reconciled_success or reconciled_failure. All other transitions are invalid; terminal states cannot change. failed means external effects are confirmed not to have happened; timeouts are unknown.
  3. The page can receive events out of order. Deduplicate identical content with the same operationId and seq. Different content under that same key marks the operation as conflicted; it must no longer expose a trusted business state. A previous state might already have been shown before the conflict arrives, so explain how its trusted status is revoked.
  4. Cache events after a gap and advance only through consecutive sequence numbers. An illegal transition marks a conflict; do not skip it and continue reducing. Other operations are independent. Replaying the same complete collection from an empty state must produce the same final result.
  5. There are at most 100,000 events in the batch, and all fields have passed type and size checks. Process only messages that actually arrive; do not loop from 1 to the largest received seq. For example, if only seq=1,000,000,000 arrives, buffer it and wait for the missing messages rather than checking a billion preceding numbers.
  6. Explain data structures, when display state is committed, time and space complexity, and at least three minimal counterexamples. Do not write a complete implementation.

Work through this case

One operation receives seq=3 started, then seq=1 proposed and seq=2 approved, followed by another seq=2 approved. State what the page can show after each arrival. Then add a late seq=2 rejected: this is a conflicting version of the same sequence slot, not an ordinary duplicate, and the prior display must lose its trusted status.

What to deliver

Deliver per-operation state, an event-processing flow, an allowed-transition table and event-by-event traces. Distinguish waiting for a missing message, an unknown real-world outcome and conflicting records. Do not repair display state by reissuing external actions.

Explore the reasoning
  1. Isolate each operation. Keep the full normalized event for each seen seq, the consecutive reduction position, business state and conflict flag. Retain already-processed event identities to detect late, inconsistent duplicates; keeping only the last sequence number misses them.
  2. Check duplicates and conflicts first. An identical duplicate changes nothing. Different content under the same key conflicts the whole operation and revokes its trusted status. Conflict is sticky: a later success cannot clear it. Other operationIds keep progressing independently.
  3. Consume only a consecutive prefix. Store new sequence numbers in a map and consume present entries from nextSeq. Each event is consumed at most once; never scan from 1 to the largest received number. Stop and mark conflict if seq=1 is not proposed or a transition is illegal.
  4. Keep unknown outcomes unknown. unknown after started means awaiting confirmation. Only reconciled_success or reconciled_failure can leave that state. A page unmount, timeout or rejection-button click cannot rewrite what happened externally.
  5. Walk through small sequences. Receive seq3 started, then seq1 proposed and seq2 approved: the first two arrivals show a gap or proposed, and the third consumes the consecutive prefix through started. Then seq4 unknown and seq5 reconciled_success confirm success. Repeating seq2 approved does not advance twice. A late seq2 rejected must revoke the successful state's trust and show conflict. For a different operation, seq2 started after seq1 proposed is illegal and conflicts only that operation.
  6. State complexity assumptions. With bounded event size and amortized constant-time hash operations, N arrivals take O(N) total time and O(N) space for identities and unconsumed events. Duplicates count in N. Arrival order may change intermediate displays, but the complete event collection has the same final state. This reducer does not guarantee exactly-once server execution; that needs a separate idempotency protocol.