Redundant Execution: A High‑Reliability Design Pattern for Agentic AI
This article introduces the redundant‑execution pattern for agentic AI, explains how running multiple identical agents in parallel can mitigate API timeouts, model crashes, and network glitches, and presents a quantitative comparison showing a jump from 60% to 80% success rate and markedly lower latency variance.
Redundant Execution for Fault‑Tolerant Agentic AI
Critical steps that may be unreliable are protected by running two or more identical agents in parallel and returning the first successful result while cancelling the others. This pattern improves both reliability and latency consistency.
Simulated Unreliable Tool
from langchain_core.tools import tool
import time, random
@tool
def get_critical_data(query: str) -> str:
"""Simulated tool that may be slow or intermittently fail"""
instance_id = random.randint(1000, 9999)
print(f"--- [Tool Instance {instance_id}] Attempting to fetch data for query: '{query}' ---")
roll = random.random()
if roll < 0.20:
print(f"--- [Tool Instance {instance_id}] FAILED: Network connection error. ---")
raise ConnectionError("Failed to connect to the external service.")
elif roll < 0.30:
slow_duration = random.uniform(5, 7)
print(f"--- [Tool Instance {instance_id}] SLOW: Experiencing high latency. Will take {slow_duration:.2f}s. ---")
time.sleep(slow_duration)
else:
fast_duration = random.uniform(0.5, 1.0)
print(f"--- [Tool Instance {instance_id}] FAST: Executing normally. Will take {fast_duration:.2f}s. ---")
time.sleep(fast_duration)
result = f"Data for '{query}' successfully retrieved by instance {instance_id}."
print(f"--- [Tool Instance {instance_id}] SUCCESS: {result} ---")
return resultRedundant Executor Node
from typing import TypedDict, Optional, Any
from concurrent.futures import ThreadPoolExecutor, as_completed
from langgraph.graph import StateGraph, END
class RedundantState(TypedDict):
input: str
result: Optional[Any]
error: Optional[str]
performance_log: Optional[str]
def redundant_executor_node(state: RedundantState):
"""Run two identical agents in parallel and return the first successful result"""
print("--- [Redundant Executor] Starting 2 agents in parallel... ---")
start_time = time.time()
with ThreadPoolExecutor(max_workers=2) as executor:
futures = [executor.submit(simple_executor.invoke, {"input": state['input']}) for _ in range(2)]
first_result = None
for future in as_completed(futures):
try:
first_result = future.result()
print("--- [Redundant Executor] A task finished successfully. Cancelling others. ---")
break
except Exception as e:
print(f"--- [Redundant Executor] A task failed with error: {e}. Waiting for the other. ---")
pass
execution_time = time.time() - start_time
log = f"Redundant execution completed in {execution_time:.2f}s."
print(f"--- [Redundant Executor] {log} ---")
if first_result:
return {"result": first_result, "performance_log": log, "error": None}
else:
return {"result": None, "performance_log": log, "error": "Both redundant executions failed."}
workflow = StateGraph(RedundantState)
workflow.add_node("redundant_executor", redundant_executor_node)
workflow.set_entry_point("redundant_executor")
workflow.add_edge("redundant_executor", END)
app = workflow.compile()Experiment Setup
Both the simple (single‑agent) system and the redundant system were executed five times each. Success/failure counts and latency measurements were collected.
import numpy as np
# simple_results and redundant_results are lists of (status, latency, payload)
simple_successes = sum(1 for r in simple_results if r[0] == "SUCCESS")
simple_rate = (simple_successes / len(simple_results)) * 100 if simple_results else 0
redundant_successes = sum(1 for r in redundant_results if r[0] == "SUCCESS")
redundant_rate = (redundant_successes / len(redundant_results)) * 100 if redundant_results else 0
print("=== SYSTEM RELIABILITY ANALYSIS ===")
print(f"Simple Agent Success Rate: {simple_rate:.1f}% ({simple_successes} successes)")
print(f"Redundant Agent Success Rate: {redundant_rate:.1f}% ({redundant_successes} successes)")
if simple_rate > 0:
reliability_increase = ((redundant_rate - simple_rate) / simple_rate) * 100
print(f"Reliability Increase: +{reliability_increase:.1f}%")
simple_latencies = [r[1] for r in simple_results if r[0] == "SUCCESS"]
redundant_latencies = [r[1] for r in redundant_results if r[0] == "SUCCESS"]
print("=== PERFORMANCE & LATENCY ANALYSIS ===")
print(f"Simple Avg Latency: {np.mean(simple_latencies):.2f}s, Max: {np.max(simple_latencies):.2f}s")
print(f"Redundant Avg Latency: {np.mean(redundant_latencies):.2f}s, Max: {np.max(redundant_latencies):.2f}s")Results
Simple agent: 60 % success (3/5), average latency 8.06 s, max latency 11.99 s.
Redundant agent: 80 % success (4/5), average latency 6.08 s, max latency 6.25 s. Reliability increase ≈ 33.3 % and worst‑case latency improves from 11.99 s to 6.25 s.
Key Benefits
Reliability boost : Parallel backup agents raise success probability from 60 % to 80 %.
Latency consistency : Redundant execution eliminates long‑tail delays; worst‑case latency (6.25 s) is lower than the simple system’s average (8.06 s).
Pattern is applicable to any critical step in autonomous workflows to achieve production‑grade resilience.
References
Building the 14 Key Pillars of Agentic AI – https://levelup.gitconnected.com/building-the-14-key-pillars-of-agentic-ai-229e50f65986
Speculative Execution – https://en.wikipedia.org/wiki/Speculative_execution
Redundant Execution (ARM blog) – https://developer.arm.com/community/arm-community-blogs/b/embedded-and-microcontrollers-blog/posts/comparing-lock-step-redundant-execution-versus-split-lock-technologies
Agentic Parallelism: A Practical Guide – https://github.com/FareedKhan-dev/agentic-parallelism
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
DeepNoMind
I’m Yu Fan, a tech leader with deep technical expertise and managerial vision. Formerly at Motorola, now at Mavenir, I’ve led teams for years, focusing on backend architecture and cloud-native solutions, staying abreast of AI and other frontier fields, and championing personal growth and lifelong learning.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
