Speeding Up Workflows with Parallelization

Introduction & Context

Welcome back! You've mastered sequential workflows with prompt chaining and conditional workflows with intelligent routing. Now, it is time to unlock dramatic performance improvements by learning parallel processing — executing multiple independent Claude API calls simultaneously instead of waiting for each one to complete.

In this lesson, you will discover how to transform workflows that take minutes into operations that complete in seconds. You will learn how to use Ruby threads to run multiple API calls concurrently and build a system that asks Claude multiple questions at the same time.

The Parallelization Workflow Pattern

Before diving into the technical details, let's understand the high-level pattern we'll be implementing. This workflow has two distinct phases that work together to provide both speed and comprehensive results:

Phase 1: Parallel Research Gathering

  • Launch multiple independent Claude API calls simultaneously using Ruby threads.
  • Each call researches a different aspect of your topic (attractions, transportation, culture).
  • All questions run concurrently, completing in roughly the time taken by the slowest individual request.
  • Results are collected and preserved in their original order.

Phase 2: Sequential Result Synthesis

  • Combine all parallel research into a single, comprehensive dataset.
  • Send the aggregated information to Claude with instructions for synthesis.
  • Generate a unified, actionable final result (such as a complete travel guide).
  • This sequential step ensures all information is properly integrated.

This two-phase approach maximizes both efficiency and quality: you get the speed benefits of parallel processing for data gathering while maintaining coherent analysis through sequential aggregation. It is particularly powerful for research tasks, analysis workflows, and any scenario in which you need to gather diverse information quickly and synthesize it into actionable insights.

Understanding Concurrency with the Ruby Anthropic SDK

When working with the Ruby Anthropic SDK, the Anthropic::Client performs blocking operations by default — each call to client.messages.create waits for Claude's response before returning. Although this is simple and straightforward, it means that multiple API calls occur one after another, which can be slow when you have many independent tasks.

Ruby
require "anthropic"

client = Anthropic::Client.new

# Sequential approach - each call waits for the previous one to finish
response1 = client.messages.create(...)  # Wait for this to complete
response2 = client.messages.create(...)  # Then wait for this to complete

To achieve parallelism with the Ruby SDK, we use Ruby threads. A thread allows you to start an operation that runs concurrently with your main program. By creating multiple threads, each making its own API call, you can have several Claude requests in flight at the same time:

Ruby
# Parallel approach using threads
thread1 = Thread.new { client.messages.create(...) }
thread2 = Thread.new { client.messages.create(...) }

# Collect results - this waits for both threads to complete
result1 = thread1.value
result2 = thread2.value

The key difference: instead of waiting for each API call to finish before starting the next one, threads let you start all the calls at once. Ruby's threading system handles the concurrent execution, and you collect the results when all threads complete.

How results are ordered: When you create threads from an array and later call .map(&:value) on that array of threads, the results are returned in the same order as the original array — even if some threads finish before others do. This predictable ordering makes it easy to match responses to their original questions.

In summary:

  • Use sequential calls for simple workflows in which each step depends on the previous one.
  • Use threads for parallel execution when you have multiple independent tasks that can run simultaneously.

Choosing the right approach is the key to optimizing your Claude workflows for both simplicity and speed.

Creating Methods for Claude Calls

Let's build the foundation of our parallel workflow by creating a method specifically designed for Claude API calls. This method will handle individual questions while being optimized for concurrent execution via threads:

Ruby
require "anthropic"

client = Anthropic::Client.new

MODEL = "claude-sonnet-4-6"

def ask_question(client, question)
  puts "🔄 Asking: #{question}"
  
  # Send request to Claude with system prompt
  response = client.messages.create(
    model: MODEL,
    max_tokens: 2000,
    system: "You are a travel expert. Give brief, helpful answers.",
    messages: [{ role: "user", content: question }]
  )
  
  # Extract the answer
  answer = response.content.first.text
  
  puts "✅ Answered: #{question}"
  
  [question, answer]
end

The puts statements help visualize when each question starts and completes. While we know Ruby preserves the order of results when mapping threads, returning an array of [question, answer] makes each result self-contained. This is a best practice for data integrity: it ensures that when we pass these results to the final synthesis step, the aggregator prompt can explicitly associate every answer with its original question, providing Claude with the full context needed to create a coherent guide.

Preparing the List of Questions

With our method ready, let's define the independent research questions that will form the parallel component of our workflow. Parallel processing shines when you have independent problems that do not rely on each other's answers:

Ruby
# List of independent questions for Paris trip planning
questions = [
  "What are the top 3 must-see attractions in Paris?",
  "What is the most efficient way to get around Paris as a tourist?",
  "What are important cultural etiquette tips for visitors to France?"
]

These questions cover different aspects of travel planning (attractions, transportation, culture) and are completely independent of each other, making them perfect candidates for parallel execution.

Building Parallel Thread Collections

Now, let's use Ruby threads to create multiple tasks that execute simultaneously. This is where the parallel magic happens:

Ruby
puts "Starting #{questions.length} research questions in parallel..."

# Create a thread for each question
threads = questions.map do |q|
  Thread.new do
    ask_question(client, q)
  end
end

# Wait for all threads to complete and collect results in order
results = threads.map(&:value)

puts "\nResearch completed!"

The map operation creates a thread for each question, with each thread calling ask_question independently. The threads.map(&:value) call waits for all threads to finish and collects their return values, preserving the original order of the questions array.

Important note on ordering: Even though threads may complete in any order (depending on network latency and Claude's response time), calling .map(&:value) on the threads array returns results aligned with the original questions array order. This occurs because the threads array maintains the same sequence as the questions that created them. You might see ✅ Answered messages appear in a different order (proving true parallelism), but the final results array will always match the order of the questions array.

Aggregating Results for Final Analysis

With all our parallel research complete, let's build the aggregation phase that synthesizes everything into a comprehensive result. This sequential step ensures all information is properly integrated:

Ruby
def create_travel_plan(client, results)
  
  # Combine all Q&A pairs into a formatted string
  combined = results.map { |q, a| "#{q}\n#{a}\n" }.join("\n")
  
  # Create aggregator prompt using heredoc
  aggregator_prompt = <<~PROMPT
    Create a brief Paris travel guide based on this research:

    #{combined}

    Make it concise and practical.
  PROMPT
  
  # Send to Claude for final synthesis
  response = client.messages.create(
    model: MODEL,
    max_tokens: 4000,
    system: "You are a travel planner. Create brief, useful guides.",
    messages: [{ role: "user", content: aggregator_prompt }]
  )
  
  response.content.first.text
end

The heredoc (<<~PROMPT) provides clean, readable multiline strings while preserving indentation. The combined string brings together all the research results, and Claude synthesizes them into a coherent travel guide.

Running the Complete Parallel Workflow

When you run this workflow, you will see the power of parallel execution unfold in three distinct stages:

  1. Instant Launch: All three 🔄 Asking messages appear immediately as the threads fire off simultaneously.
  2. Concurrent Completion: The ✅ Answered messages arrive as Claude finishes each response — often in a different order from the one in which they were asked, proving your requests are truly running in parallel.
  3. Intelligent Synthesis: All this concurrent research is woven together into a comprehensive travel guide that combines the speed benefits of parallel processing with thoughtful analysis.

This visual progression clearly demonstrates how your requests execute concurrently rather than waiting for each other, transforming what could be a slow sequential process into a fast, efficient workflow that delivers both speed and quality.

text
Starting 3 research questions in parallel...
🔄 Asking: What are the top 3 must-see attractions in Paris?
🔄 Asking: What is the most efficient way to get around Paris as a tourist?
🔄 Asking: What are important cultural etiquette tips for visitors to France?
✅ Answered: What are the top 3 must-see attractions in Paris?
✅ Answered: What are important cultural etiquette tips for visitors to France?
✅ Answered: What is the most efficient way to get around Paris as a tourist?

Research completed!

Paris Travel Guide:
# Paris Travel Guide 🗼

## Must-See Attractions
1. **Eiffel Tower** – Book tickets in advance; visit at night for the light show
2. **The Louvre** – Allow half a day minimum; home to the Mona Lisa and Venus de Milo
3. **Notre-Dame Cathedral** – Restoration ongoing, but the exterior and Île de la Cité are worth the visit

> 💡 **Buy a Paris Museum Pass** to save time and money across multiple sites

---

## Getting Around
- **Metro + walking** covers 90% of your needs
- Pick up a **Navigo Easy card** for cheaper fares — lines 1, 4, 6, and 14 hit most tourist spots
- **Vélib' bikes** are great along the Seine
- Avoid taxis and driving, especially during rush hour

---

## Cultural Etiquette
- **Always greet** with *Bonjour/Bonsoir* when entering shops or restaurants
- **Attempt French** — even basic phrases earn goodwill
- Dining is leisurely — don't rush, and wait to be seated
- Keep your voice down and dress neatly
- **Tipping is optional** — service is included

---

*The golden rule: be patient and polite. It goes a long way in Paris.* 🇫🇷

Performance Benefits and Use Cases

This two-stage approach provides significant performance benefits while maintaining result quality. The parallel research phase completes in roughly the time taken by the slowest individual question, while the aggregation phase ensures all information is properly synthesized into a usable travel plan.

This pattern works well for any scenario in which you need to:

  • Research multiple independent topics quickly.
  • Aggregate diverse information into a unified result.
  • Balance speed with comprehensive analysis.

The performance benefits are most significant when you have many independent research topics or when individual API calls have high latency.

Summary & Practice Preparation

You have mastered parallel processing patterns using Ruby threads that transform slow sequential workflows into lightning-fast concurrent operations. The combination of parallel research gathering and sequential result synthesis provides both speed and quality, making it ideal for complex analysis tasks such as travel planning, market research, or technical evaluations.

In the upcoming exercises, you will apply these patterns to real-world scenarios and learn to handle the nuances of concurrent Claude workflows with Ruby threads. Remember: use parallel processing for independent research tasks, then aggregate results sequentially for a comprehensive final analysis.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal