# How to Tune DimOS Performance Using n_workers and Shared Memory (SHM) Transports

> Tune dimensionalOS performance by increasing n_workers for parallel execution and using SHM transports for high-bandwidth streams reducing latency and network overhead.

- Repository: [Dimensional/dimos](https://github.com/dimensionalOS/dimos)
- Tags: performance
- Published: 2026-03-15

---

**Increase `n_workers` to parallelize module execution and switch high‑bandwidth streams to `pSHMTransport` or `SHMTransport` to eliminate network stack overhead and minimize latency in dimensionalOS/dimos pipelines.**

DimOS is a modular robotics framework where every module runs in an isolated **worker process**. To achieve maximum throughput on multi‑core hardware, you must balance CPU parallelism via the `n_workers` configuration with zero‑copy inter‑process communication using shared‑memory transports. This guide explains how to configure both mechanisms based on the actual implementation in the `dimensionalOS/dimos` repository.

## Understanding the Worker Model in DimOS

DimOS spawns a pool of worker processes at runtime to execute module code. The global singleton `GlobalConfig` defines the default concurrency level in [`dimos/core/global_config.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/global_config.py):

```python

# dimos/core/global_config.py (lines 38-39)

n_workers: int = 2  # Default worker count

```

When a blueprint is instantiated, the `WorkerManager` class creates the requested number of `Worker` processes and manages their lifecycle in [`dimos/core/worker_manager.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/worker_manager.py) (lines 30‑45). The manager distributes incoming module requests across the pool using `WorkerManager._select_worker()`, ensuring load is balanced across available CPU cores.

## Configuring n_workers for Optimal Concurrency

### Setting Workers in a Blueprint

Blueprints declare their resource requirements via the `global_config` decorator. Override the default `n_workers` value to match your hardware:

```python
from dimos.core.global_config import global_config

@global_config(n_workers=8)  # Use 8 workers for high-throughput pipelines

def my_high_performance_blueprint():
    return autoconnect().with_modules([...])

```

### Runtime Override via CLI

You can adjust worker count without modifying source code using the DimOS CLI. The `--n-workers` flag is parsed in [`dimos/robot/cli/dimos.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/robot/cli/dimos.py) (lines 180‑182) and injected into `GlobalConfig` before the coordinator starts:

```bash
dimos run unitree_go2_basic --n-workers 6

```

This command spawns six workers instead of the blueprint’s default, useful for temporary scaling on larger machines.

## Eliminating Bottlenecks with Shared Memory Transports

### Why Shared Memory Outperforms Network Transports

By default, DimOS uses `LCMTransport` (UDP multicast) for inter‑module messaging. While efficient for small control signals, UDP introduces serialization overhead and kernel networking stack latency when streaming large binary data like camera frames or LiDAR point clouds.

The **POSIX shared‑memory transports** (`pSHMTransport` and `SHMTransport`) bypass the network stack entirely. The sender writes data directly into a memory‑mapped segment, and the receiver accesses it via a single `memcpy` operation. This eliminates `sendto`/`recvfrom` system calls and reduces CPU usage significantly.

### Available SHM Transport Options

DimOS provides four transport implementations in [`dimos/core/transport.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/transport.py):

| Transport | Implementation | Best For |
|-----------|---------------|----------|
| `pSHMTransport` | Pickled objects in POSIX SHM (lines 60‑77) | High‑bandwidth sensor messages (`sensor_msgs.Image`) where Python pickling is acceptable |
| `SHMTransport` | Raw bytes in POSIX SHM (lines 90‑107) | Raw binary payloads (point clouds) requiring maximum throughput |
| `JpegShmTransport` | JPEG‑compressed images in SHM | Bandwidth‑constrained wireless links |
| `LCMTransport` | UDP multicast LCM | Small control messages, cross‑machine communication |

### Configuring Shared Memory in Blueprints

Attach transports to specific topics using the `autoconnect().transports(dict)` API. The dictionary maps `(topic_name, message_type)` tuples to transport instances:

```python
from dimos.core.transport import SHMTransport, pSHMTransport
from dimos.msgs.sensor_msgs import PointCloud2, Image

# Configure SHM for high-bandwidth streams

shm_transports = {
    ("lidar/points", PointCloud2): SHMTransport("lidar_points"),  # Raw bytes

    ("camera/image", Image): pSHMTransport("camera_image"),        # Pickled Image msgs

}

blueprint = autoconnect().transports(shm_transports)

```

As shown in [`dimos/robot/unitree/go2/blueprints/basic/unitree_go2_basic.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/robot/unitree/go2/blueprints/basic/unitree_go2_basic.py) (lines 30‑41), the framework automatically selects `pSHMTransport` on macOS platforms where high‑bandwidth UDP is unreliable, demonstrating the same pattern:

```python

# From unitree_go2_basic.py - platform-specific transport selection

if platform.system() == "Darwin":
    # Use shared memory on macOS for high-bandwidth streams

    transports = {(...): pSHMTransport(...)}

```

## Practical Performance Tuning Scenarios

### High-Bandwidth Camera Streams

For 30 FPS 1080p image processing:

1. Set `n_workers=4` to parallelize image decoding, perception, and control
2. Use `pSHMTransport` for `sensor_msgs.Image` topics to avoid UDP bottlenecks
3. Ensure workers are pinned to separate CPU cores if the OS supports affinity

### Dense LiDAR Point Clouds

For high-frequency lidar data:

1. Allocate `n_workers=8` on a 16-core workstation to isolate the sensor driver and mapping modules
2. Configure `SHMTransport` (raw bytes) for `PointCloud2` messages in [`dimos/core/transport.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/transport.py) (lines 90‑107)
3. Place the producer and consumer on different workers to maximize parallel processing

### Runtime Adjustment

Temporary scaling without code changes:

```bash

# Scale workers for a heavy inference workload

dimos run my_blueprint --n-workers 12

```

## Summary

- **Worker Scaling**: DimOS defaults to `n_workers=2` defined in [`dimos/core/global_config.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/global_config.py); increase this value via the `@global_config` decorator or the `--n-workers` CLI flag to parallelize module execution across CPU cores.
- **Shared Memory Transports**: Replace `LCMTransport` with `pSHMTransport` (pickled objects) or `SHMTransport` (raw bytes) from [`dimos/core/transport.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/transport.py) to eliminate UDP overhead for large binary streams like images and point clouds.
- **Configuration Pattern**: Use `autoconnect().transports({(topic, type): Transport(...)})` to bind high‑bandwidth topics to SHM transports while keeping control signals on LCM for cross‑machine compatibility.
- **Hardware Alignment**: Match `n_workers` to physical core count; use 4‑8 workers for high‑throughput sensor processing and 8‑16 for dense perception pipelines on workstation‑class hardware.

## Frequently Asked Questions

### What is the default number of workers in DimOS and where is it defined?

The default is **2 workers**, defined in [`dimos/core/global_config.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/global_config.py) at lines 38‑39 as the `n_workers` field of the `GlobalConfig` class. This value is instantiated when the DimOS coordinator starts and creates the `WorkerManager` pool.

### How do I switch from UDP to shared memory for a specific topic?

Use the `transports` method of the `autoconnect()` builder. Create a dictionary mapping `(topic_name, message_type)` tuples to `SHMTransport` or `pSHMTransport` instances, then pass it to `autoconnect().transports(your_dict)`. This overrides the default `LCMTransport` for those specific streams while leaving others unchanged.

### When should I use pSHMTransport versus SHMTransport?

Choose `pSHMTransport` when streaming **picklable Python objects** like `sensor_msgs.Image` or structured sensor messages where the convenience of pickle serialization outweighs the slight overhead. Choose `SHMTransport` for **raw binary payloads** like dense LiDAR point clouds or uncompressed depth maps where you need maximum throughput and minimal serialization CPU usage.

### Can I change the worker count without modifying my blueprint code?

Yes. Use the `--n-workers` command‑line flag when launching your DimOS application. The CLI handler in [`dimos/robot/cli/dimos.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/robot/cli/dimos.py) (lines 180‑182) parses this argument and injects the value into `GlobalConfig.n_workers` before the coordinator initializes the `WorkerManager`, allowing temporary scaling for specific hardware or workload demands.