Skip to main content
Multiple call client support requires daily-js version >= 0.67.0.
daily-js and react-native-daily-js support multiple simultaneous call client instances. The ability to use multiple instances simultaneously affords various use cases both simple and complex. One simple example is having a secondary call instance for building a background effects preview. In a single call, setting the background processing effect applies the effect immediately, disallowing any preview step. With a second call instance, you can use prejoin functionality to start the camera, set the background effect, and preview the track without affecting the primary call until you choose to apply the effect. Another use case we’ve heard is for call coordinators, where a special set of participants monitor or coordinate a larger call and may want to be in a separate call simultaneously for communicating behind the scenes. Breakout rooms could also be solved using multiple call instances, though we generally encourage the use of track subscriptions for smoother transitioning, communication between rooms, and call quality monitoring. There are doubtless other use cases that could be solved with multiple clients. Always feel free to reach out to Daily for help determining the best approach for solving yours.

Limitations

There are a few known limitations when working with multiple call instances.
  1. Each additional call instance will use additional bandwidth and CPU, as it does not simply piggyback on resources already in use. Take this into consideration to ensure instances are properly limited so as not to overwhelm a client’s network or device.
  2. setOutputDeviceAsync() will affect all audio elements on the window regardless of which instance the underlying tracks stem from. This function is a helper for rounding up all audio elements on the window and setting their sinkId to the matching device. If you use this function, call it on all call instances so that the underlying state management stays in sync with reality.
  3. Multiple call client instances are not yet supported in Daily React.

Opt-in flag

Most use cases are still best suited for a single call client instance and the existence of multiple often indicates a bug. For this reason, support for multiple call instances is opt-in. Without opting in, the SDK will throw an error in the constructor when it detects a second call instance. To opt in, add allowMultipleCallInstances: true to the properties passed to your constructors.
const call1 = Daily.createCallObject({ allowMultipleCallInstances: true });
const call2 = Daily.createCallObject({ allowMultipleCallInstances: true });
If you were using multiple call instances before official support, you may have been setting strictMode: false in your constructor. This flag still exists and is used for other validation work but will soon no longer allow the multiple-instance behavior. Replace it with allowMultipleCallInstances.

Retrieving a call instance

If you need to access a call instance created elsewhere in your codebase, use the static getCallInstance() method:
// Returns the first (and usually only) instance
const call = Daily.getCallInstance();

// Returns a specific instance by ID
const call = Daily.getCallInstance(callClientId);
This is most useful in single-instance apps where you want to avoid threading the call object through your component tree. For multi-instance apps, each instance has a unique callClientId string you can use to target a specific one.

callClientId

Each call client instance has a public property identifying it: callClientId. You can use this for identification, and you can also pass it to getCallInstance() to retrieve a handle to the corresponding instance.
const call1Id = call1.callClientId;
const _call1 = Daily.getCallInstance(call1Id);
assert(call1 === _call1);

Event handling

All events include callClientId to indicate which client emitted the event.
call1.on('joined-meeting', handleJoin);
call2.on('joined-meeting', handleJoin);

function handleJoin(event) {
  switch (event.callClientId) {
    case call1.callClientId:
      showJoinedDialog(call1);
      break;
    case call2.callClientId:
      showJoinedDialog(call2);
      break;
  }
}

Logging

To help match up logs and metrics across multiple calls for a single user, the SDK logs all user session IDs for every simultaneous session. An example log: Simultaneous call client instance created, with participant session_id: 47365350-8116-4ec3-b4eb-f39a21a9ead8 If one instance has not yet joined a room (like in the background effects preview use case), the other instance will log: Simultaneous call client instance created, with participant session_id: not yet set Once the second instance joins, the first will log again with the correct session ID.

Demos