# MPI Send modes **Send modes** in MPI make blocking behaviour explicit. Standard `MPI_Send` may block depending on message size; `MPI_Ssend` always synchronizes, `MPI_Bsend` always buffers, and `MPI_Rsend` requires a posted receive. `MPI_Ssend` (synchronous send) never buffers. It blocks until the receiver has posted a matching `MPI_Recv`, which makes it the most useful tool for debugging deadlocks: replacing `MPI_Send` with `MPI_Ssend` removes buffering as a variable, so if the code hangs it definitely has a cyclic dependency rather than just exceeding buffer limits. `MPI_Bsend` (buffered send) always returns immediately by copying into a user-supplied buffer attached with `MPI_Buffer_attach`. `MPI_Rsend` (ready send) asserts that a matching receive is already posted; behaviour is undefined if it is not, but it can skip handshake overhead on implementations that exploit the guarantee. ```c // synchronous: blocks until receiver has called MPI_Recv MPI_Ssend(&x, 1, MPI_INT, dest, 0, MPI_COMM_WORLD); // buffered: always returns immediately; user manages the buffer char buf[MPI_BSEND_OVERHEAD + sizeof(int)]; MPI_Buffer_attach(buf, sizeof(buf)); MPI_Bsend(&x, 1, MPI_INT, dest, 0, MPI_COMM_WORLD); MPI_Buffer_detach(&buf_ptr, &buf_size); // blocks until buffer is drained ``` All four modes have non-blocking variants: `MPI_Issend`, `MPI_Ibsend`, `MPI_Irsend`. They follow the same request/wait pattern as `MPI_Isend`.