The Problem: Videos That Won't Play Until Fully Downloaded
You embed an MP4 video on your website using an HTML5 <video> tag. A visitor clicks play and nothing happens. The browser shows a spinner, the progress bar has no duration, and the video refuses to start. The visitor waits a few seconds, gives up, and leaves your page.
This is one of the most common video problems on the web, and it has nothing to do with your internet speed, server configuration, or CDN. The video file itself is the problem — specifically, the position of its metadata within the file.
When a browser encounters an MP4 file, it needs to read the metadata first to understand the video: which codec is used, how many frames there are, the duration, frame timestamps, and the byte offset of each frame within the file. Without this information, the browser cannot decode or display a single frame.
If this metadata is at the end of the file, the browser must download the entire file before it can begin playback. For a 100 MB video on a typical connection, that means the user waits 30–60 seconds before seeing anything. On a slow connection, they might wait several minutes. Most users will leave long before then.
What Is the Moov Atom?
MP4 files are structured as a hierarchy of "atoms" (also called "boxes" in the MPEG specification). Each atom has a type and contains either data or other atoms. The two most important atoms for understanding faststart are:
moov(movie atom) — contains all the metadata: codec parameters, frame locations (byte offsets), timestamps, duration, track information, and sample tables. This is the "table of contents" for the entire video file.mdat(media data atom) — contains the actual compressed video and audio data. This is the bulk of the file.
When an encoder creates an MP4 file, it writes the mdat atom first because it is writing the compressed frames as they are encoded. The encoder does not know the final frame offsets and sizes until encoding is complete, so the moov atom — which contains this information — is written last.
This means a freshly encoded MP4 has the following structure:
[ftyp] — file type declaration (tiny, ~20 bytes)
[mdat] — compressed video + audio data (99%+ of file size)
[moov] — metadata, frame index, timestamps (small, typically <1% of file)
A browser downloading this file progressively (via HTTP) reads from the beginning. It encounters ftyp (good), then mdat (the actual media data), but it cannot interpret mdat without moov because it does not know the codec, frame boundaries, or timestamps. So it keeps downloading, waiting for moov to appear. It finally reaches moov at the very end of the file — after downloading the entire thing.
How Faststart Fixes It
Faststart is a post-processing step that moves the moov atom from the end to the beginning of the file. After applying faststart, the file structure becomes:
[ftyp] — file type declaration
[moov] — metadata, frame index, timestamps (NOW AT THE BEGINNING)
[mdat] — compressed video + audio data
Now when a browser downloads the file progressively, the sequence is:
- Read
ftyp— confirm it is a valid MP4. - Read
moov— learn the codec, duration, frame index, and byte offsets for every frame inmdat. - Begin downloading
mdat— the browser now knows exactly where each frame starts, so it can begin decoding and displaying video immediately.
The result: playback starts within the first 1–2 seconds of download, regardless of total file size. The duration bar shows the full length immediately. Seeking works correctly because the browser has the complete frame index. The user experience goes from "broken" to seamless.
Faststart also enables pseudo-streaming — the ability to seek to any position in the video without downloading everything before that point. When the browser has the moov atom, it knows the exact byte offset of any frame and can issue an HTTP Range request to jump directly to that position on the server.
Who Needs Faststart
Faststart is essential for any MP4 file that will be played via progressive download over HTTP. This includes:
- Web developers embedding video with HTML5
<video>tags - Content creators sharing video links (the recipient's browser or app uses progressive download)
- Videos served from CDN or S3 — cloud storage serves files via HTTP, so progressive download behavior applies
- Email campaigns with embedded or linked video
- CMS platforms (WordPress, Squarespace, Wix) that host video files directly
- Social media uploads — platforms re-encode your video, but having faststart on your source file ensures their ingest pipeline processes it efficiently
Faststart is not needed for:
- Local playback — desktop video players (VLC, mpv, Windows Media Player) read the entire file from disk, so
moovposition is irrelevant - Adaptive streaming (HLS, DASH) — these protocols segment the video into small chunks with separate manifests, so the
moovatom is not used for playback
How to Check If Your MP4 Has Faststart
You can check whether the moov atom appears before or after mdat using ffprobe. Run this command:
ffprobe -v trace input.mp4 2>&1 | grep -E "type:'(moov|mdat)'" | head -2
The output shows the atoms in the order they appear in the file. If moov appears first, faststart is already enabled:
# Faststart enabled (moov before mdat) — good for web
type:'moov'
type:'mdat'
# Faststart NOT enabled (mdat before moov) — will buffer
type:'mdat'
type:'moov'
Another way to check is with the atomicparsley tool or by examining the first few bytes of the file with a hex editor. But ffprobe is the most accessible method since it comes bundled with FFmpeg.
Adding Faststart Without Re-encoding
The most important thing to understand about faststart is that it does not require re-encoding. It is a metadata rearrangement operation that copies the moov atom from the end of the file to the beginning and updates the byte offsets within it. The video and audio data in mdat remain bit-for-bit identical.
This means the operation is:
- Instant — processing time is a few seconds regardless of file size, because only the small
moovatom is moved - Lossless — no decoding or encoding occurs, so quality is unchanged
- No file size increase — the output is the same size as the input (actually a few bytes smaller in some cases due to atom header optimization)
Use FFmpeg with stream copy (-c copy) and the movflags option:
ffmpeg -i input.mp4 -c copy -movflags +faststart output.mp4
The -c copy flag tells FFmpeg to copy all streams without re-encoding. The -movflags +faststart flag tells it to move the moov atom to the beginning. This works on any MP4 file regardless of the video codec (H.264, H.265, VP9, AV1) or audio codec (AAC, MP3, Opus) inside it.
If you are encoding a new video from scratch, include faststart in the same command:
ffmpeg -i input.mov -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 192k -movflags +faststart output.mp4
FFmpeg handles the faststart operation after encoding completes. Internally, it writes the moov atom at the end (as usual during encoding), then performs a second pass to move it to the beginning. This second pass adds only a few seconds to the total processing time.
HandBrake's "Web Optimized" Checkbox
If you use HandBrake instead of FFmpeg, the faststart option is available under a different name. In the Summary tab, check the box labeled "Web Optimized". This is exactly the same as FFmpeg's -movflags +faststart — it moves the moov atom to the beginning of the file.
HandBrake's documentation describes it as: "Optimizes MP4 files for HTTP streaming (fast start)." Despite the vague description, all it does is rearrange the atom order. It does not change encoding settings, quality, or file size.
The "Web Optimized" checkbox is not enabled by default in HandBrake. If you are encoding video for web playback, always check this box. Forgetting it is one of the most common mistakes that leads to buffering videos on websites.
Our Converter Applies Faststart Automatically
Every MP4 file produced by Convertio includes the -movflags +faststart flag. When you convert a MOV (or any other format) to MP4 using our converter, the output file has the moov atom at the beginning, ready for instant web playback.
You do not need to enable any special option or checkbox — faststart is applied automatically to every conversion. The output file is ready to embed in HTML5 <video> tags, upload to your CMS, host on a CDN, or share via direct link.
Automatic faststart on every MP4. Our converter applies -movflags +faststart automatically to every MP4 output. Your converted videos are ready for instant web playback — no extra steps, no post-processing required.
Common Mistakes to Avoid
Even experienced developers sometimes get tripped up by faststart. Here are the most common pitfalls:
- Forgetting faststart when re-encoding. If you re-encode a video with FFmpeg but omit
-movflags +faststart, the output will havemoovat the end — even if the input had faststart. The flag must be specified on every encode. - Assuming cloud platforms add it automatically. AWS S3, Google Cloud Storage, and Cloudflare R2 serve files exactly as uploaded. If you upload an MP4 without faststart, that is what your users will download. The storage provider does not modify your files.
- Confusing faststart with streaming protocols. Faststart enables progressive download (HTTP-based playback). It is not the same as HLS or DASH adaptive streaming. For adaptive streaming, you need to segment the video into chunks and create a manifest. Faststart is for simple MP4 files served as single files.
- Using
-movflags faststartwithout the+. The+prefix is important when combining multiple movflags. Without it,-movflags faststartreplaces all other movflags instead of adding to them. Always use+faststartto be safe:-movflags +faststart.