A step-by-step guide for teams migrating from custom, multi-service video infrastructure (AWS MediaConvert, S3, CloudFront, FFmpeg, etc.) to Mux.
This guide is for teams that have built their own video infrastructure by stitching together multiple services — custom transcoding, object storage, general-purpose CDNs, and workflow orchestration — and are considering a move to Mux.
If your current setup involves three or more services and workflows for encoding, storage, delivery, analytics, and playback, this guide will walk you through migrating to Mux.
If you're building a new video product from scratch rather than migrating, check out our Mux fundamentals guide instead.

Before migrating, take stock of your current video infrastructure. A typical DIY video workflow involves many different processes across multiple services. Mux replaces this entire stack with a single API:
To start using Mux, follow these steps. You can sign up for a free account.
Mux supports both small and large libraries, so you can migrate any number of videos in a similar way.
Truckload is a migration tool that handles bulk content import. It runs as a hosted service with no infrastructure setup required, or you can self-host and customize it for your specific migration needs since it's open source.
Truckload runs on Inngest, a background job orchestration platform.
If you have specific requirements or if you're working with a CMS, You can run the migration yourself using the Mux API.
video.asset.ready webhook events and use them to automatically update the corresponding record in your CMS the moment an asset is ready for playback.Here's an example migration script that lists videos in your S3 bucket and ingests them into Mux:
import Mux from '@mux/mux-node';
import { S3Client, ListObjectsV2Command } from '@aws-sdk/client-s3';
const mux = new Mux();
const s3 = new S3Client({ region: 'us-east-1' });
// List videos in your S3 bucket
const { Contents: objects = [] } = await s3.send(
new ListObjectsV2Command({
Bucket: 'my-video-bucket',
Prefix: 'videos/',
})
);
for (const obj of objects) {
const asset = await mux.video.assets.create({
inputs: [{ url: `https://my-video-bucket.s3.amazonaws.com/${obj.Key}` }],
playback_policies: ['public'],
video_quality: 'basic',
passthrough: obj.Key, // Link back to your S3 key
});
console.log(`Created asset ${asset.id} for ${obj.Key}`);
// Store asset.id and asset.playback_ids[0].id in your database
}Test first. Always test your migration flow with a small batch of sample content before migrating your full library.
Mux offers multiple video quality tiers to balance quality and cost based on your needs:
You can set a default quality tier for your entire library and override it on a per-asset basis when needed. Basic and Plus are commonly used for general content, while Premium is useful when higher visual fidelity is required.
Understand Mux API rate limits for bulk operations during migration. For specific limits and 429 handling guidance, see API rate limits. When migrating a large library, use a background job queue to keep within limits and get reliable, retryable job processing.
Enqueue a job per video, control concurrency, and let the queue handle retries on failure. Rather than polling Mux to check asset status, listen for the video.asset.ready webhook and trigger a job to update your database or CMS when it fires.
A DIY stack involves multiple services and line items — storage, bandwidth, transcoding, compute, and engineering overhead. Mux uses a single usage‑based pricing model.
| Cost dimension | Self-managed | Mux |
|---|---|---|
| Storage | Per-GB object storage (S3 or equivalent), billed monthly for all stored data | Per-minute of stored video — no GB math needed. See Video pricing |
| Delivery | Per-GB bandwidth from your CDN (CloudFront, Cloudflare, etc.), tiered by region | Per-minute of delivered video, including multi-CDN. See Video pricing |
| Transcoding | Per-minute or per-job from your transcoding service (MediaConvert, etc.), varies by codec and resolution | Per-minute of input video at time of encoding — one price regardless of output renditions. See Video pricing |
| Player | Build your own or license a third-party player | Mux Player included at no additional cost |
| Analytics | Separate service or build your own | Mux Data included with every stream |
| Engineering overhead | Ongoing maintenance of orchestration, monitoring, error handling, and scaling across services | No infrastructure to manage or scale. You maintain an integration only |
To estimate costs with a DIY stack, you'd calculate separate line items for each service:
With Mux, you'd estimate three line items:
If you're converting from GB-based billing, these approximations can help: 720p ≈ 40 min/GB, 1080p ≈ 25 min/GB, 2K ≈ 15 min/GB, 4K ≈ 10 min/GB. See Estimating video costs for more detail.
Use the Mux pricing calculator to plug in your actual numbers and get a cost estimate. For tips on keeping costs optimized for your use case, see Optimizing video costs.
Use this checklist to track your migration progress.
video.asset.readytitle, creator_id, external_id) using asset metadataOnce your content is migrated, you can access additional features available on the platform.
Now that your video is in Mux, you can access the primitives of each asset (audio, captions, summaries, key moments) to trigger AI-driven workflows: