Skip to Content

Controlling your Mux Video costs

Learn how to use different pricing strategies and levers to control your costs under different scenarios

You can find all of our costs on our pricing page, but you may be wondering how you can control your costs and potentially find ways to reduce your bill. We’re going to outline a few ways you can optimize your usage of Mux so that you can keep your costs as low as possible.

Cost levers you can leverage through the Mux Video product

Mux offers a few ways to control your costs depending on your use case. We have many features that you can take advantage of that will influence your encoding, storage, and delivery costs. There are also add-ons you can opt-in to using so that you only pay for the features you need.

Use Basic Video Quality

There is no charge for video encoding when using basic quality. This makes encoding free when uploading videos that use this quality level.

The basic video quality level uses a reduced encoding ladder with a lower target video quality and is suitable for simpler video use cases, particularly those that have a lot of user generated content.

Basic assets storage rates are slightly higher than Plus and Premium quality levels Basic Storage Pricing

You can learn more about video quality and what features are supported.

Basic quality level assets have a minimum storage charge of one month and are prorated thereafter. Storage is prorated by the percentage of the month that the video is stored. For example, if a 10-minute asset is stored for only half a month, you will be charged for only 5 minutes.

Automatic Cold Storage

With Automatic Cold Storage, we automatically transition a video or audio-only asset to a different storage level based on how long it has been since it was last viewed. The colder the asset gets, the lower the billing rate becomes.

See more about Automatic Cold Storage

Capping maximum delivery resolution

By setting a maximum delivery resolution, you can take advantage of our resolution based pricing.

The playback URL below with the max_resolution query parameter modifies the resolutions available for the player to choose from.

https://stream.mux.com/{PLAYBACK_ID}.m3u8?max_resolution=720p

The max_resolution parameter can be set to 720p, 1080p, 1440p, or 2160p. You may want to do this in order to reduce your delivery costs, or build a feature to your product where only certain viewers get lower resolution video.

See more here

Capping upload resolution

If the video being captured in your app doesn't need to be played back in full resolution, specify a lower resolution when recording to take advantage of Mux's resolution dependent pricing.

When uploading from a mobile device (Android, iOS or iPadOS), you can utilize our upload SDKs to adjust the resolution of your video input locally before it is uploaded to Mux. By default the SDK will adjust the input resolution to 1920 x 1080 for any inputs that are larger.

Control recording resolution

Preload

If you want to reduce delivery costs for users who might delay watching a video (or not watch it at all), you can set preload="none" in Mux Player (or other compatible player). This means that no video will be pre-loaded until the user plays the video. You could also use preload="metadata" which will only load the minimum amount of data needed for the player to get basic information about the video, like its duration.

The tradeoff with using preload="metadata" or preload="none" is that when the user plays the video they will experience a slower startup time because the video has to load before playback can start.

Mobile browsers, especially on iOS and Android, often ignore auto and metadata due to data-saving policies.

While preload serves as a hint, browsers ultimately decide how to handle video loading. If you need precise control, consider managing video loading via JavaScript.

Lazy loading

Lazy loading can be beneficial because you can opt to only load the player when the user is ready to watch the video, like scrolling it into view. If the player isn't loaded, you're not charged for any video delivery yet. See our guide on how to implement lazy loading for Mux Player here.

Delivery Usage API

This is not a cost control feature, but is a way to get asset level delivery visibility. You can utilize the Delivery Usage API to retrieve information about the delivery of a specific video in a given time period. The Delivery Usage API allows you to get delivery and streaming usage details for each asset and across all assets.

Delivery usage details are aggregated every hour at the top of the hour and can be requested for a specified time window within the last 90 days starting at 12 hours prior to when the request is made.

Cost levers you can leverage on your own

Player buffer length

A player has a buffer for the media it plays. Segments are downloaded into the buffer, decoded, and then played. The forward buffer is the media that has not yet been played. In most modern web players, you can set the buffer length of the playback engine.

The main tradeoff when customizing these parameters is performance. Shortening the buffer length leaves your player vulnerable to rebuffering and the viewer waiting if there's a temporary network disconnection or hiccup and that buffer runs out. This is an advanced option, so please keep that in mind.

By reducing this value, you save on the delivered minutes portion of your bill because you're reducing the actual video delivery from the player. The mechanism to control this sometimes differs from player to player but in Mux Player and hls.js, you can set this in a couple of places by:

const player = document.querySelector('mux-player');
player._hls.config.maxBufferLength = { number in seconds }
player._hls.config.maxBufferSize = { bytes }
player._hls.config.maxMaxBufferLength = { number in seconds }

maxBufferLength = Maximum buffer length in seconds. If buffer length is/become less than this value, a new fragment will be loaded. This is the guaranteed buffer length hls.js will try to reach, regardless of maxBufferSize. \n

maxBufferSize = 'Minimum' maximum buffer size in bytes. If buffer size upfront is bigger than this value, no fragment will be loaded.

maxMaxBufferLength = Maximum buffer length in seconds. Hls.js will never exceed this value, even if maxBufferSize is not reached yet. hls.js tries to buffer up to a maximum number of bytes (60 MB by default) rather than to buffer up to a maximum nb of seconds. this is to mimic the browser behavior (the buffer eviction algorithm is starting after the browser detects that video buffer size reaches a limit in bytes) maxBufferLength is the minimum guaranteed buffer length that hls.js will try to achieve, even if that value exceeds the amount of bytes 60 MB of memory. maxMaxBufferLength acts as a capping value, as if bitrate is really low, you could need more than one hour of buffer to fill 60 MB.

For more information, see the hls.js documentation on these options.

These options are all via hls.js and Mux Player. Your own player and playback engine will differ.

Delete live stream assets when streaming ends

To save on storage costs, you can delete the resulting asset that gets created once your live stream has completed. This way you will limit storage charges and prevent further delivery costs. The ingest/encoding cost is still the same once the live stream has completed, this only affects storage.

Storage is calculated by minutes of video stored. Storage is prorated by the percentage of the month that the video is stored. For example, if a 10-minute asset is stored for only half a month, you will be charged for only 5 minutes.

Pause when out of viewport

One way of reducing your delivery costs is to reduce the time viewers spend having your video play and buffer. You could implement a way to pause your video player when the viewer's browser window is out of focus or not visible. This can prevent unnecessary playback and delivery charges.

You can achieve this by listening to the visibilitychange event on the window object:

document.addEventListener("visibilitychange", function () {
    if (document.visibilityState !== "visible") {
        console.log("Window is inactive, pausing video player");
        // replace the below with the corresponding pause method of the player you're using
        player.pause()
    }
});

Are you still watching?

Many streaming services want to reduce their bandwidth and streaming delivery costs so they have implemented an "Are you still watching?" dialog popup that interrupts playback when the viewer has been watching on autoplay for an extended period of time with no interaction.

You could implement this in your own application as well. Below is a small proof of concept on how you might achieve this using React.

import { useState } from "react";
import MuxPlayer from "@mux/mux-player-react";

export default function App() {
  const [lastPlayedTimestamp, setLastPlayedTimestamp] = useState();

  const playbackId = "g11xsFT2MA9E92016CuQTSh8kv01aaUhJK"
  const secondsToStopVideo = 10; // timer in seconds

  const handleAllUserActivity = (event) => {
    setLastPlayedTimestamp(event.target.currentTime) // reset the last played timestamp after each play
  };

  const handleTimeUpdate = (event) => {
    const player = event.target;
    const timeElapsed = player.currentTime - lastPlayedTimestamp;
    if (!player.paused && timeElapsed > secondsToStopVideo) {
      player.pause();
      alert("Are you still watching?");
    }
  };

  return (
    <>
      <MuxPlayer
        playbackId={playbackId}
        onPlaying={handleAllUserActivity}
        onSeeking={handleAllUserActivity}
        onRateChange={handleAllUserActivity}
        onVolumeChange={handleAllUserActivity}
        onTimeUpdate={handleTimeUpdate}
      />
    </>
  );
}

Not loading multiple videos on one webpage

Since Mux customers are charged for any delivered video, if a video player is loaded on a webpage it may pre-load some amount of video before playback has been initiated.

This would result in minutes delivered just on page load before the viewer even hits the play button.

If you're displaying multiple videos on page load for each viewer, this could end up multiplying your bill as many videos are causing delivery charges at once. This could be very costly.

Limit the duration of your uploads

If you're a looking to put a duration cap on your videos, you can set duration limits upon upload.

This is done usually by UGC platforms (social media) given the short form content focus, but also by platforms looking to make sure they're not paying for unnecessary ingests costs.

Was this page helpful?