Skip to main content
 
Field Guides

Optimizing Video Calls for Low-Powered Devices

Detect CPU constraints and dynamically adjust video quality settings for users on lower-end devices using LiveKit JS SDK v2.14.0+.

Last Updated:


When running 1:1 video calls, users connecting from lower-end laptops (typically with fewer than 6–8 CPU cores) may experience degraded video quality. This happens because the browser automatically reduces video resolution and frame rates when the CPU cannot keep up with real-time encoding and processing demands.

LiveKit JS Client SDK (v2.14.0 and later) provides tools to detect and respond to these CPU constraints so you can optimize the experience for these users.

This guide shows you how to:

  • Detect when the browser limits video quality due to CPU constraints
  • Dynamically adjust settings to maintain performance
  • Disable CPU-intensive features like Krisp noise cancellation and video processors (like background video processing)

Why CPU constraints cause video degradation

WebRTC-enabled browsers constantly monitor system performance. When the CPU is overloaded, they reduce video resolution, frame rate, or encoding complexity. This is reported in the WebRTC stats API as a qualityLimitationReason of cpu.

In LiveKit JS SDK ≥ v2.14.0, you can listen for this condition using the ParticipantEvent.LocalTrackCpuConstrained event.

Detecting CPU constraints

The SDK emits ParticipantEvent.LocalTrackCpuConstrained when the browser reports CPU-based quality limitation.

Here's how to listen for it:

room.localParticipant.on(ParticipantEvent.LocalTrackCpuConstrained, (track) => {
console.warn('CPU constrained, taking action', track);
// Your optimization logic here
});

Recommended optimizations for low-powered devices

To reduce CPU load and maintain a smooth call:

Disable Krisp noise cancellation

If your app uses Krisp noise suppression, disable it before the participant joins the room. Krisp is highly effective but consumes significant CPU resources. See the enhanced noise cancellation docs for more details.

Dynamically reduce video quality

When CPU constraints are detected:

  • Lower the publisher's video quality
  • Lower the subscriber's video quality
  • Stop any video processors (e.g., background blur) that add CPU load

Here's a React hook that encapsulates this behavior:

import {
Room,
ParticipantEvent,
RoomEvent,
RemoteTrackPublication,
VideoQuality,
LocalVideoTrack,
isVideoTrack,
} from 'livekit-client';
import * as React from 'react';
export function useLowCPUOptimizer(room: Room) {
const [lowPowerMode, setLowPowerMode] = React.useState(false);
React.useEffect(() => {
const handleCpuConstrained = async (track: LocalVideoTrack) => {
setLowPowerMode(true);
console.warn('CPU constrained', track);
// Reduce publisher video quality
track.prioritizePerformance();
// Reduce subscriber video quality
room.remoteParticipants.forEach((p) => {
p.videoTrackPublications.forEach((pub) => {
pub.setVideoQuality(VideoQuality.LOW);
});
});
// Stop video processors (if any)
if (isVideoTrack(track)) {
track.stopProcessor();
}
};
room.localParticipant.on(ParticipantEvent.LocalTrackCpuConstrained, handleCpuConstrained);
return () => {
room.localParticipant.off(ParticipantEvent.LocalTrackCpuConstrained, handleCpuConstrained);
};
}, [room]);
return lowPowerMode;
}

Use the hook like this:

const lowPowerMode = useLowCPUOptimizer(room);
React.useEffect(() => {
if (lowPowerMode) {
console.warn('Low power mode enabled');
}
}, [lowPowerMode]);

Example in LiveKit Meet

The meet.livekit.io app includes this optimization pattern. See the implementation in GitHub PR #450.

Read related documentation

Find more Frontends guides