CoProducer Measure a mix
Phone screen in a dark room

Social · 21 August 2026 · 8 min

What LUFS for Reels, TikTok and Shorts? Why vertical video is a loudness trap

NoDAW Labs · Lacquer Vol. 02

There isn’t an official number to hit. TikTok, Instagram Reels and YouTube Shorts don’t publish a LUFS target the way Spotify publishes −14, so mastering to “the TikTok LUFS” means chasing a rumour. Master the clip you actually export instead: true peak at or below −1 dBTP after the editing app has encoded it, an opening three seconds that isn’t buried, the voice clearly on top of the beat, and a quick check in mono on a phone.

You know the move. The beat video sounds huge in the session, you cut 15 seconds of the hook, drop it into the editor, export, post. Then you watch it on your phone between two other clips and it’s either a whisper or it crunches on the snare. Nothing about the music changed. The trip from the timeline to the feed did.

It looks like delivery is done when you hit export. It isn’t. Your audio gets encoded by the editor, encoded again by the platform, levelled by a player you don’t control, and played through a tiny speaker. Here’s what you can control, with a test you can run on your own clips.

What LUFS should a Reel, TikTok or Short be?

Here’s what is actually documented, as far as we can find:

If you want a starting point, around −14 LUFS integrated is a sane habit: nothing has to lift you much, and no normaliser has to turn you down hard. It isn’t a rule, and it’s rarely why a clip fails on a phone.

Why does my Reel sound quieter (or more crushed) than everyone else’s?

A few usual suspects:

Does the editing app change my audio when I export?

Almost always, yes. A typical MP4 export carries lossy AAC audio, so pick the highest audio bitrate your editor offers. Lossy encoders rebuild the waveform rather than copying it, and the rebuilt peaks can come out higher than the ones you limited. Then the platform encodes it again.

We measured it on synthetic test material (no real songs; trust the shape more than the decimals). The “chorus clip” is 15 seconds cut from a dense synthetic beat that was pushed 6 dB into a plain sample-peak limiter set to −0.1 dBFS, the way a lot of loud masters get made. We exported it the way an editor might, AAC at 128 kbps, using FFmpeg’s built-in encoder.

Synthetic clipIntegratedTrue peak before exportTrue peak after AAC 128k
Chorus clip, as limited−7.6 LUFS+0.7 dBTP+2.3 dBTP
Same clip, trimmed to −2.0 dBTP first−10.3 LUFS−2.0 dBTP−1.6 dBTP
Talking intro, beat drops at 9 s−10.5 LUFS+0.7 dBTP+1.7 dBTP
Voice over a beat, balanced−15.5 LUFS−1.1 dBTP−1.3 dBTP

The limiter promised −0.1 dBFS, yet the clip measured +0.7 dBTP before export, because a sample-peak limiter doesn’t see the peaks between samples. After the AAC export it was +2.3 dBTP, with decoded samples above full scale that will clip anywhere the playback chain is fixed-point. Trimming 2.7 dB first left it at −1.6 dBTP. Encoders differ, so measure the exported file, not the timeline.

On any platform that levels loudness, that trim costs you nothing. The player was going to turn a −7.6 LUFS clip down anyway.

How do I check a clip before I post it?

You don’t need a special plugin. If you have FFmpeg installed, this reads the audio straight out of a video file and gives you the numbers that matter for a short clip. It uses FFmpeg’s ebur128 filter, which follows the ITU-R BS.1770 loudness and true-peak method.

#!/usr/bin/env python3
"""clip_check.py: a loudness check for short vertical clips (Reels, Shorts, TikTok).
    python3 clip_check.py my_reel.mp4 [more files...]
Works on video or audio files (anything ffmpeg can read). Prints integrated loudness,
the loudest 3-second stretch (max short-term), how far that jumps above the average,
the opening 3 seconds (where people decide to keep watching), true peak, and how much
level the clip loses when it is played in mono (0 = nothing lost)."""
import re, subprocess, sys

def ebur128(path, mono=False):
    af = ("pan=stereo|c0=0.5*c0+0.5*c1|c1=0.5*c0+0.5*c1," if mono else "") + "ebur128=peak=true"
    err = subprocess.run(["ffmpeg", "-hide_banner", "-nostats", "-i", path, "-vn", "-af", af,
                          "-f", "null", "-"], capture_output=True, text=True).stderr
    I = float(re.findall(r"I:\s+(-?[\d.]+) LUFS", err)[-1])
    tp = float(re.findall(r"Peak:\s+(-?[\d.]+|-inf) dBFS", err)[-1])
    # per-100 ms lines: "t: 3.1  ... M: -14.2 S: -15.0 ..."; skip the first 3 s (window not full yet)
    S = [(float(t), float(s)) for t, s in re.findall(r"t:\s*([\d.]+).*?S:\s*(-?[\d.]+)", err)]
    full = [s for t, s in S if t >= 3.0]
    opening = min(full[0:1] or [-70.0])  # the first full 3 s window
    return I, max(full), opening, tp

for path in sys.argv[1:]:
    I, smax, opening, tp = ebur128(path)
    Im = ebur128(path, mono=True)[0]
    notes = []
    if tp > -1.0: notes.append("true peak above -1 dBTP")
    if smax - I > 5.0: notes.append("loudest 3 s jumps more than 5 LU over the average")
    if opening - I < -4.0: notes.append("opening 3 s is much quieter than the rest")
    if Im - I < -3.0: notes.append("loses a lot in mono: check wideners/polarity")
    print(f"{path}\n  integrated {I:6.1f} LUFS | loudest 3 s {smax - I:+5.1f} LU | opening 3 s {opening - I:+5.1f} LU"
          f" | true peak {tp:+5.1f} dBTP | mono {Im - I:+5.1f} LU")
    print("  " + ("; ".join(notes) if notes else "nothing flagged"))

Run on the synthetic clips above (example data, not real songs):

$ python3 clip_check.py clip_chorus.wav clip_chorus_export.m4a clip_chorus_trim2_export.m4a clip_dropintro.wav clip_widebed.wav
clip_chorus.wav
  integrated   -7.6 LUFS | loudest 3 s  +0.3 LU | opening 3 s  -0.1 LU | true peak  +0.7 dBTP | mono  -0.2 LU
  true peak above -1 dBTP
clip_chorus_export.m4a
  integrated   -7.7 LUFS | loudest 3 s  +0.2 LU | opening 3 s  -0.2 LU | true peak  +2.3 dBTP | mono  -0.2 LU
  true peak above -1 dBTP
clip_chorus_trim2_export.m4a
  integrated  -10.4 LUFS | loudest 3 s  +0.3 LU | opening 3 s  -0.1 LU | true peak  -1.6 dBTP | mono  -0.2 LU
  nothing flagged
clip_dropintro.wav
  integrated  -10.5 LUFS | loudest 3 s  +3.2 LU | opening 3 s  -5.6 LU | true peak  +0.7 dBTP | mono  -0.2 LU
  true peak above -1 dBTP; opening 3 s is much quieter than the rest
clip_widebed.wav
  integrated  -14.1 LUFS | loudest 3 s  +0.2 LU | opening 3 s  -0.2 LU | true peak  +0.3 dBTP | mono  -5.1 LU
  true peak above -1 dBTP; loses a lot in mono: check wideners/polarity

How to read it: loudest 3 s and opening 3 s are short-term loudness relative to the whole clip. Mono is how much level the clip loses when left and right are summed and played on both sides; 0 means nothing lost. The flag thresholds are our rules of thumb, not a standard. Measure the file you’re about to upload, after export, not the session.

Why do the first three seconds matter so much?

Because that’s when someone decides whether to keep watching, and it’s often the quietest part. Take the talking-intro clip: nine seconds of speech over a soft bed, then the beat drops. Its integrated loudness (−10.5 LUFS) is set mostly by the drop. The opening three seconds sit 5.6 LU under that, and the loudest three seconds sit 3.2 LU over it, so there’s close to 9 LU between what people hear first and the loudest moment.

When a player levels that clip to a shared target, it levels the average. The talking gets turned down along with the drop, and the opener ends up playing well under the clip before it in the feed.

Broadcast has a rule for the opposite problem. For adverts and promos, EBU R 128 s1 keeps the loudest 3-second short-term reading within +5 LU of the programme’s loudness target, so a short spot can’t sneak in one massive moment (EBU R 128 s1). It’s a useful ceiling for clips too. For a scroll feed, also watch the floor: bring the talking up, tuck the bed under it, or open on the hook and talk after.

How loud should my voice be over the beat?

There’s no official ratio. What helps is measuring the voice and the bed separately instead of guessing from the mix: solo each, export, and run the same script on both.

In our balanced example the voice measured −16.0 LUFS and the bed −24.0 LUFS, so the bed sat 8 LU under the voice. Treat that as a starting point, not a rule, and judge it the only way that counts: on a phone, at normal volume, next to a clip you like. For a beat showcase with a spoken intro, automate the bed down under the talking and back up after.

For sung vocals over a beat, see how loud the vocal should sit.

Why does my clip sound thin or hollow on a phone?

Two reasons. First, phone speakers don’t reproduce much real bass, so an 808 that carries the track on headphones can vanish (see why your 808 disappears on phone speakers). Give the low end some harmonics higher up.

Second, mono. Our wide-bed clip has a pad through a careless “widener” that flips one side’s polarity. Summed to mono it lost 5.1 LU, because the pad cancels itself and only the voice survives. If your mono number drops more than a few LU, find the plugin doing it. Wide mixes fail in mono walks through the mid/side check.

What should I check before I batch-export?

  1. Pick the hero clip: the loudest moment or the most talking.
  2. Cut from a loud master? Trim it to about −2 dBTP true peak.
  3. Check the opening isn’t more than a few LU under the clip.
  4. Export, then measure the exported file: true peak at or below −1 dBTP, little mono loss.
  5. Listen once on a phone speaker, next to a clip you like.
  6. Only then batch-resize the visuals with the same audio settings.

If you’d rather not run scripts, export the clip’s audio as a WAV and drop it into CoProducer’s analyzer. It reads integrated LUFS, true peak and clipped samples on your machine, so you can see the problem before your followers hear it.

What LUFS should I use for TikTok, Reels and Shorts?
None of them publishes a LUFS target the way Spotify publishes −14, so there is no official number to hit. Around −14 LUFS integrated is a common working habit. What matters more is the exported file: true peak at or below −1 dBTP, a strong opening and a clear voice.
Do TikTok and Spotify use the same loudness target?
Don’t assume it. Spotify documents −14 LUFS for music playback. TikTok doesn’t publish a target, and Meta says Reels and Stories bring clips to a common target level in the player but doesn’t publish the number. Treat each platform as its own lane, and still keep true peak under −1 dBTP everywhere.
Why does my video sound quieter after I upload it?
Usually because it was louder than the platform’s reference, so the player turned it down. Meta describes this kind of loudness management for Reels and Stories, and YouTube shows it as content loudness in Stats for nerds. A crushed clip that gets turned down just sounds small next to the clip before it.
Can I resize and master a clip in one step?
Keep them separate. Fix the sound first, export one hero clip, measure the exported file, then batch-resize the visuals with the same audio settings. Re-check the audio any time the export preset changes.

A free one-pager

The checklist we run before every release.

Loudness, true peak, mono, tails, export settings and the metadata basics, on one page. Leave your email and it opens straight away, or read it here first. No email needed for that.