<!-- llms-explorer concept facts · https://llms-explorer.com/tree/jaccl-tcpallgather-side-channel-as-peer-liveness/ · pack 2026-10-05 · ~460 tokens -->

# JACCL TCPAllGather side channel as peer-liveness channel

> In stock MLX main the side channel is used for bootstrap all-gathers and a barrier in the ring constructor; the RDMA completion wait loops never read it

Parent: [Mac local LLMs: Clusters, RDMA, exo and ds4](https://llms-explorer.com/tree/mac-local-llms-clusters-rdma-exo-ds4/) · 1 facets · 6 facts · page: https://llms-explorer.com/tree/jaccl-tcpallgather-side-channel-as-peer-liveness/

## Facts

- In stock MLX main the side channel is used for bootstrap all-gathers and a barrier in the ring constructor; the RDMA completion wait loops never read it — [source](https://raw.githubusercontent.com/ml-explore/mlx/main/mlx/distributed/jaccl/lib/jaccl/ring.cpp)
- `RingGroup::initialize` exchanges left and right connection info with two side-channel all-gathers, which its comment says also act as a barrier before RTR and RTS — [source](https://raw.githubusercontent.com/ml-explore/mlx/main/mlx/distributed/jaccl/lib/jaccl/ring.cpp)
- `RingGroup::barrier` is an `all_sum` of one `uint8_t` over RDMA, not a TCP barrier — [source](https://raw.githubusercontent.com/ml-explore/mlx/main/mlx/distributed/jaccl/lib/jaccl/ring.cpp)
- `MeshGroup::barrier` is also an `all_sum` of one `uint8_t` — [source](https://raw.githubusercontent.com/ml-explore/mlx/main/mlx/distributed/jaccl/lib/jaccl/mesh.cpp)
- `Config::get_side_channel` keeps the `TCPAllGather` alive in a lambda capture for the group's lifetime, so the socket stays open after init — [source](https://raw.githubusercontent.com/ml-explore/mlx/main/mlx/distributed/jaccl/lib/jaccl/jaccl.cpp)
- A user-supplied factory or all-gather function replaces the TCP channel entirely, so there is no socket to watch for liveness — [source](https://raw.githubusercontent.com/ml-explore/mlx/main/mlx/distributed/jaccl/lib/jaccl/jaccl.cpp)
