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

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:


# 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 (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:

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 (lines 180‑182) and injected into GlobalConfig before the coordinator starts:

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:

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:

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 (lines 30‑41), the framework automatically selects pSHMTransport on macOS platforms where high‑bandwidth UDP is unreliable, demonstrating the same pattern:


# 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 (lines 90‑107)
  3. Place the producer and consumer on different workers to maximize parallel processing

Runtime Adjustment

Temporary scaling without code changes:


# 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; 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 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 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 (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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →