The concat operator concatenates all sources by forwarding received elements downstream. When the operator concatenates two streams, at first, it consumes and resends all elements of the first stream, then does the same for the second.
The merge operator merges data from upstream sequences into one downstream sequence. Unlike the concat operator, upstream sources are subscribed to eagerly (at the same time).
The zip operator subscribes to all upstreams, waits for all sources to emit one element and then combines received elements into an output element. In Chapter 2, Reactive Programming in Spring - Basic Concepts, we described how zip works in detail. In Reactor, the zip operator may operate not only with reactive publishers but also with an Iterable container. For that purpose, we can use the zipWithIterable operator.
The combineLatest operator works similarly to the zip operator. However, it generates a new value as soon as at least one upstream source emits a value.