---
title: Parallel
---

import { Callout } from 'fumadocs-ui/components/callout'
import { Tab, Tabs } from 'fumadocs-ui/components/tabs'
import { Image } from '@/components/ui/image'
import { FAQ } from '@/components/ui/faq'

The Parallel block is a container that executes multiple instances concurrently for faster workflow processing. Process items simultaneously instead of sequentially.

<Callout type="info">
  Parallel blocks are container nodes that execute their contents multiple times simultaneously, unlike loops which execute sequentially.
</Callout>

## Configuration Options

### Parallel Type

Choose between two types of parallel execution:

<Tabs items={['Count-based', 'Collection-based']}>
  <Tab>
    **Count-based Parallel** - Execute a fixed number of parallel instances:
    
    <div className="flex justify-center">
      <Image
        src="/static/blocks/parallel-1.png"
        alt="Count-based parallel execution"
        width={500}
        height={400}
        className="my-6"
      />
    </div>
    
    Use this when you need to run the same operation multiple times concurrently.
    If the total count is larger than the batch size, Sim runs the work in serial batches while preserving the original result order.
    
    ```
    Example: Run 5 parallel instances
    - Instance 1 ┐
    - Instance 2 ├─ All execute simultaneously
    - Instance 3 │
    - Instance 4 │
    - Instance 5 ┘
    ```
  </Tab>
  <Tab>
    **Collection-based Parallel** - Distribute a collection across parallel instances:
    
    <div className="flex justify-center">
      <Image
        src="/static/blocks/parallel-2.png"
        alt="Collection-based parallel execution"
        width={500}
        height={400}
        className="my-6"
      />
    </div>
    
    Each instance processes one item from the collection. Large collections run in serial batches while preserving each item's original index.
    
    ```
    Example: Process ["task1", "task2", "task3"] in parallel
    - Instance 1: Process "task1" ┐
    - Instance 2: Process "task2" ├─ All execute simultaneously
    - Instance 3: Process "task3" ┘
    ```
  </Tab>
</Tabs>

## How to Use Parallel Blocks

### Creating a Parallel Block

1. Drag a Parallel block from the toolbar onto your canvas
2. Configure the parallel type and parameters
3. Drag a single block inside the parallel container
4. Connect the block as needed

### Referencing Parallel Data

There's an important distinction between referencing parallel data from **inside** vs **outside** the parallel block:

<Tabs items={['Inside the Parallel', 'Outside the Parallel']}>
  <Tab>
    **Inside the parallel**, use `<parallel.>` references to access the current instance context:
    
    - **`<parallel.index>`**: Current instance number (0-based)
    - **`<parallel.currentItem>`**: Item for this instance (collection-based only)
    - **`<parallel.items>`**: Full collection being distributed (collection-based only)
    
    ```
    // Inside a Function block within the parallel
    const idx = <parallel.index>;           // 0, 1, 2, ...
    const item = <parallel.currentItem>;    // This instance's item
    ```
    
    <Callout type="info">
      These references are only available for blocks **inside** the parallel container. They give you access to the current instance's context.
    </Callout>
  </Tab>
  <Tab>
    **Outside the parallel** (after it completes), reference the parallel block by its name to access aggregated results:
    
    - **`<ParallelBlockName.results>`**: Array of results from all instances
    
    ```
    // If your parallel block is named "Process Tasks"
    const allResults = <processtasks.results>;
    // Returns: [result1, result2, result3, ...]
    ```
    
    <Callout type="info">
      After the parallel completes, use the parallel's block name (not `parallel.`) to access the collected results. The block name is normalized (lowercase, no spaces).
    </Callout>
  </Tab>
</Tabs>

## Example Use Cases

**Batch API Processing** - Process multiple API calls simultaneously
```
Parallel (Collection) → API (Call Endpoint) → Function (Aggregate)
```

**Multi-Model AI Processing** - Get responses from multiple AI models concurrently
```
Parallel (["gpt-4o", "claude-3.7-sonnet", "gemini-2.5-pro"]) → Agent → Evaluator (Select Best)
```

## Advanced Features

### Result Aggregation

Results from all parallel instances are automatically collected and accessible via the block name:

```javascript
// In a Function block after a parallel named "Process Tasks"
const allResults = <processtasks.results>;
// Returns: [result1, result2, result3, ...]
```

For large result sets, reference only the entry or field you need, such as `<processtasks.results[10][0].id>`. Sim keeps aggregate results indexable by storing oversized entries in execution storage and hydrating them only when an indexed server-side path is explicitly referenced.

### Batch Size

Parallel blocks run up to 20 branches at a time by default. Increase the total count or collection size to process more work; Sim will execute the next batch after the current batch finishes. You can lower the batch size to reduce concurrency for rate-limited APIs.

### Instance Isolation

Each parallel instance runs independently:
- Separate variable scopes
- No shared state between instances
- Failures in one instance don't affect others

### Limitations

<Callout type="info">
  Container blocks (Loops and Parallels) support nesting. You can place parallels inside parallels, loops inside parallels, and any combination of container blocks to build complex multi-dimensional workflows.
</Callout>

<Callout type="info">
  While parallel execution is faster, be mindful of:
  - API rate limits when making concurrent requests
  - Memory usage with large datasets
  - Maximum of 20 concurrent instances per batch to prevent resource exhaustion
</Callout>

## Parallel vs Loop

Understanding when to use each:

| Feature | Parallel | Loop |
|---------|----------|------|
| Execution | Concurrent | Sequential |
| Speed | Faster for independent operations | Slower but ordered |
| Order | No guaranteed order | Maintains order |
| Use case | Independent operations | Dependent operations |
| Resource usage | Higher | Lower |

## Inputs and Outputs

<Tabs items={['Configuration', 'Variables', 'Results']}>
  <Tab>
    <ul className="list-disc space-y-2 pl-6">
      <li>
        <strong>Parallel Type</strong>: Choose between 'count' or 'collection'
      </li>
      <li>
        <strong>Count</strong>: Number of instances to run (count-based)
      </li>
      <li>
        <strong>Collection</strong>: Array or object to distribute (collection-based)
      </li>
      <li>
        <strong>Batch size</strong>: Number of branches to run concurrently, from 1 to 20
      </li>
    </ul>
  </Tab>
  <Tab>
    Available **inside** the parallel only:
    <ul className="list-disc space-y-2 pl-6">
      <li>
        <strong>{"<parallel.index>"}</strong>: Instance number (0-based)
      </li>
      <li>
        <strong>{"<parallel.currentItem>"}</strong>: Item for this instance (collection-based only)
      </li>
      <li>
        <strong>{"<parallel.items>"}</strong>: Full collection (collection-based only)
      </li>
    </ul>
  </Tab>
  <Tab>
    <ul className="list-disc space-y-2 pl-6">
      <li>
        <strong>{"<blockname.results>"}</strong>: Array of all instance results (accessed via block name)
      </li>
      <li>
        <strong>Access</strong>: Available in blocks after the parallel completes
      </li>
    </ul>
  </Tab>
</Tabs>

## Best Practices

- **Independent operations only**: Ensure operations don't depend on each other
- **Handle rate limits**: Add delays or throttling for API-heavy workflows
- **Error handling**: Each instance should handle its own errors gracefully

<FAQ items={[
  { question: "What is the maximum number of concurrent instances?", answer: "The maximum is 20 concurrent instances. This limit exists to prevent resource exhaustion and ensure stable execution." },
  { question: "Can parallel instances share state with each other?", answer: "No. Each parallel instance runs in complete isolation with its own variable scope. There is no shared state between instances, and one instance cannot read or write data from another during execution." },
  { question: "What happens if one parallel instance fails?", answer: "Failures in one instance do not affect other instances. Each instance runs independently, so the remaining instances will continue to execute normally." },
  { question: "Can I nest Parallel blocks inside other Parallel or Loop blocks?", answer: "Yes. Container blocks (Parallels and Loops) support nesting. You can place parallels inside parallels, loops inside parallels, and any combination to build multi-dimensional workflows." },
  { question: "How do I access results after the Parallel block completes?", answer: "Use <blockname.results> where blockname is the normalized name of your Parallel block (lowercase, no spaces). This returns an array containing the results from all instances." },
  { question: "Is the order of results guaranteed?", answer: "No. Because instances execute concurrently, the order of results in the output array is not guaranteed to match the input order. If ordering matters, include an index or identifier in each instance's output." },
  { question: "What is the difference between count-based and collection-based parallel?", answer: "Count-based runs a fixed number of identical instances (e.g., run 5 times). Collection-based distributes items from an array or object across instances, with each instance processing one item. Use count-based for repeated operations and collection-based for batch processing." },
]} />
