← Open Source
kevinzakka

mjbatch

A Python library for running thousands of MuJoCo simulations in parallel on CPU

Model DevelopmentEnvironmentsPython
Open on GitHub
Momentum
+3stars in 24 hours+0.5%
586
Stars
59
Forks
+15
This week
1
Contributors
Created 2026-09-10 · Updated 2026-10-05 · #2294 today
Top developers
README

mjbatch

Build PyPI version

mjbatch is a Python library for running thousands of MuJoCo simulations in parallel on CPU.

Features include:

  • C++ thread pool execution, with the GIL released;
  • Live array access to simulation state and controls across the batch, with bind for MjData fields;
  • Per-simulation model parameters, with expand for MjModel fields and set_const to recompute derived constants.

For example:

import mujoco, numpy as np
from mjbatch import Batch

model = mujoco.MjModel.from_xml_path("scene.xml")
batch = Batch(model, num_sims=4096)  # threads default to every logical CPU
qpos, ctrl = batch.bind("qpos"), batch.bind("ctrl")
batch.expand("geom_friction")[:, :, 0] = np.random.uniform(0.4, 1.2, (4096, 1))
for _ in range(1000):
  ctrl[:] = policy(qpos)             # your controller, all 4096 at once
  batch.step()                       # step them in parallel; qpos updates in place

Examples

We showcase a range of applications built using mjbatch: RL, MPC, SysID, and hardware co-design. Each example is a self-contained, performant implementation. For instance, the Go1 RL controller learns to walk in under a minute on a five-year-old M1 laptop.

  [![cart-pole swing-up](https://raw.githubusercontent.com/kevinzakka/mjbatch/main/examples/assets/cartpole_swingup.gif)](https://github.com/kevinzakka/mjbatch/blob/main/examples/cartpole_swingup.py)




  [![cart-pole MPC](https://raw.githubusercontent.com/kevinzakka/mjbatch/main/examples/assets/cartpole_mpc.gif)](https://github.com/kevinzakka/mjbatch/blob/main/examples/cartpole_mpc.py)

A two-pole cart swung upright with iLQR

A cart-pole swing-up controller using predictive sampling

  [![G1 backflip](https://raw.githubusercontent.com/kevinzakka/mjbatch/main/examples/assets/g1_flip.gif)](https://github.com/kevinzakka/mjbatch/blob/main/examples/g1_flip.py)




  [![Go1 joystick](https://raw.githubusercontent.com/kevinzakka/mjbatch/main/examples/assets/go1_joystick.gif)](https://github.com/kevinzakka/mjbatch/blob/main/examples/go1_joystick.py)

A G1 humanoid tracking a reference backflip with receding-horizon iLQR

A Go1 quadruped joystick controller trained with PPO

  [![throwing arm co-design](https://raw.githubusercontent.com/kevinzakka/mjbatch/main/examples/assets/arm_throw.gif)](https://github.com/kevinzakka/mjbatch/blob/main/examples/arm_throw.py)




  [![Rizon inertia identification](https://raw.githubusercontent.com/kevinzakka/mjbatch/main/examples/assets/rizon_inertia.gif)](https://github.com/kevinzakka/mjbatch/blob/main/examples/rizon_inertia.py)

CEM jointly optimizes a robot arm's proportions, gears, and controls

Damped Gauss–Newton fits a Rizon arm's inertial parameters to synthetic motion data

Run with uv run examples/.py; some need uv sync --group examples. The ones that open a window need a display; --headless runs the solver without one.

License

Apache-2.0.