CoProducer Measure a mix
A lacquer-black mastering desk with three glowing LUFS needles—momentary, short-term, and integrated—in cyan and warm amber, on black marble

Loudness · 12 October 2026 · 8 min

Short-term LUFS is not your target

NoDAW Labs · Lacquer Vol. 05

Streaming and stores care about integrated LUFS over the whole file. A drop that hits −9 short-term can still miss −14 integrated—or look “quiet” while the chorus is already crushed. Read both meters, then decide.

You’ve seen this one. The hook meter needles into the red, short-term sitting somewhere around −9, and it feels competitive. You bounce, upload, and the store report says −16 integrated. Or the opposite: the whole-song number looks soft, so you shove another dB into the limiter and suddenly the chorus is brickwalled while the verses still sit in the mud.

Neither meter lied. You asked them different questions and treated the answers as the same number.

Three windows, three jobs

Loudness meters in the EBU R128 / BS.1770 family give you three reads that move at different speeds:

Meter Window What it’s for
Momentary ~400 ms Catching peaks and hits while you work. Not a delivery target.
Short-term 3 seconds Sectional truth—verse vs hook, drop vs breakdown.
Integrated Whole file (gated) What Spotify, YouTube, Apple Sound Check, and most stores use for playback gain.

Integrated is the delivery lane. Short-term is how the arrangement actually breathes. Momentary is the warning light on the desk. Chasing short-term on the hook and calling it done is how you either over-limit the whole song or leave the integrated number in the wrong place.

A quick mental model: if the chorus is 6 LU hotter than the verse on short-term, and the chorus is half the song, the integrated number will land somewhere between them—not at the chorus. Push the chorus to “competitive” short-term and the integrated reading can still look quiet. Leave the verses alone and the store average never catches the hook.

Measure both before you touch the limiter

Here’s a small script that runs ffmpeg’s ebur128 meter on a bounce and prints integrated loudness, loudness range, true peak, max short-term, and the gap between the hottest short-term window and the whole-song average. That’s the number that tells you whether the hook is doing all the work.

#!/usr/bin/env python3
"""shortterm_check.py — integrated vs max short-term on one bounce.
Usage: python3 shortterm_check.py master.wav
Needs: ffmpeg on PATH. Uses ffmpeg's EBU R128 meter (same family as a LUFS plugin)."""
import re, subprocess, sys
def run(path):
    out = subprocess.run(
        ["ffmpeg", "-hide_banner", "-nostats", "-i", path,
         "-filter_complex",
         "ebur128=metadata=1:peak=true,ametadata=print:key=lavfi.r128.S:file=-",
         "-f", "null", "-"],
        capture_output=True, text=True, check=True,
    )
    # Live short-term samples (3 s windows, updated ~10×/sec)
    times = [float(t) for t in re.findall(r"pts_time:([\d.]+)", out.stdout)]
    shorts = [float(v) for v in re.findall(r"lavfi\.r128\.S=(-?[\d.]+|-inf)", out.stdout)]
    pairs = [(t, s) for t, s in zip(times, shorts) if s != float("-inf") and s > -70]
    # Summary block on stderr
    integ = float(re.findall(r"I:\s+(-?[\d.]+) LUFS", out.stderr)[-1])
    lra = float(re.findall(r"LRA:\s+([\d.]+) LU", out.stderr)[-1])
    tp = float(re.findall(r"Peak:\s+(-?[\d.]+) dBFS", out.stderr)[-1])
    return integ, lra, tp, pairs
def mmss(s):
    return f"{int(s // 60)}:{int(s % 60):02d}"
integ, lra, tp, pairs = run(sys.argv[1])
if not pairs:
    sys.exit("No short-term samples above −70 LUFS.")
max_s = max(pairs, key=lambda x: x[1])
# Skip the first ~3 s while the short-term window fills
usable = [(t, s) for t, s in pairs if t >= 3.0] or pairs
median_s = sorted(s for _, s in usable)[len(usable) // 2]
print(f"integrated     : {integ:6.1f} LUFS")
print(f"loudness range : {lra:6.1f} LU")
print(f"true peak      : {tp:6.1f} dBTP")
print(f"max short-term : {max_s[1]:6.1f} LUFS  at {mmss(max_s[0])}")
print(f"median short   : {median_s:6.1f} LUFS  (after window fill)")
print(f"hook vs song   : {max_s[1] - integ:+6.1f} LU  (max short-term minus integrated)")
if max_s[1] - integ >= 6:
    print("note           : hook is 6+ LU hotter than the whole-song average.")
    print("                 Don’t push the limiter to chase the hook number.")

Run it like python3 shortterm_check.py master.wav. On a synthetic two-minute file—verse at roughly −18 LUFS short-term for a minute, then a chorus 6 LU hotter—the script reports something like integrated around −15.5, max short-term near −12, and a “hook vs song” gap of about +3.5 LU. Same file, if you only watched short-term on the drop, you’d swear you were already competitive. The store would still turn you up a little, and the chorus would get louder than you meant.

The opposite synthetic—same average energy smashed flat so short-term barely moves—lands integrated near the short-term reading and a tiny LRA. That’s the crushed master that “hits −14” while the hook has nowhere left to go.

When the hook is 6+ LU hotter than the verse

That’s not a bug. Arrangement is supposed to move. The mistake is treating the hook’s short-term as the delivery target.

If integrated is quiet and the hook is already hot. Don’t add more limiting. The verses are dragging the average down, which is often what you want for drama. Trim fake silence at the edges first (quiet intros that still count still pull integrated), then decide whether the arrangement needs a louder verse bed—or whether −15 integrated with a −9 short-term hook is the record you meant to make. Streaming will turn a quiet file up; the question is whether the noise floor and true-peak headroom survive that turn-up.

If integrated is already near −14 and the hook short-term is −8 or hotter. The chorus is doing almost all the loudness work. More limiter input gain will mostly crush the drop and barely move the song average. Pull a dB or two out of the hook bus, or shorten how long the biggest texture stays in, before you ask the master chain for another LU.

If short-term and integrated are almost the same. You’ve flattened the sectional contrast. That can be right for some club and hip-hop delivery, but it’s a choice—not an accident. Check crest / dynamic range next to the LUFS row so you know what you spent.

Across genres the gap looks different on purpose. A ballad can sit with 8–10 LU between verse and chorus short-term and still land a polite integrated number. Trap and drill often keep the short-term closer together because the 808 and hats never really leave. EDM drops can spike short-term hard for eight bars and still average near −14 if the breakdowns are long. None of those need the same limiter preset.

Read the bounce, then decide

Once the mix bounce is done, measure integrated and true peak the way a store will. CoProducer’s analyze table puts integrated LUFS, true peak, and clips next to each other so you’re not chasing a short-term needle that the distributor never sees. If the hook feels soft next to a reference, match levels on short sections by ear—then confirm the whole-file number hasn’t left the lane.

Should I master to −9 short-term LUFS?
No. Short-term is a sectional readout, not a delivery target. Aim the whole file near the store lane (often around −14 integrated, Apple closer to −16), and use short-term to see whether the hook is carrying the loudness or the arrangement still has contrast.
Why does my chorus meter hot but the upload report says I’m quiet?
The store averages the gated whole file. A hot chorus over quieter verses, long intros that still count, or fades can pull integrated down even when short-term on the drop looks competitive. Measure both, trim fake edges, then decide.

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.