concat will subscribe the observable one by one. It won't subscribe next one until current one is completed.

Following is a typical example

// When a$ is subscribed, emit a value every 1 second, and emit 4 values in total.
// 0----1s---- a1 ----1s---- a2 ----1s---- a3 ----1s---- a4|
const a$ = interval(1000).pipe(
  map((x) => 'a' + x),
// When b$ is subscribed, emit a value every 200ms, and emit 2 values in total
// 0----200ms---- b1 ----200ms---- b2|
const b$ = interval(100).pipe(
  map((x) => 'b' + x)

// The result of following is 
// 0----1s---- a1 ----1s---- a2 ----1s---- a3 ----1s---- a4 ----200ms---- b1 ----200ms---- b2|
concat(a$, b$).subscribe((x) => {

Also note that if you use Subject as Observable. Before a$ is completed, any value emitted via b$.next will not be passed to concat as the subject is not subscribed yet. If you do want to output all values including the ones before subscribed, consider using BehaviorSubject or ReplaySubject