CoProducer Measure a mix
A polished brass drumstick resting on a snare drum on black marble, a sharp cyan spike of light rising from the drumhead above a low magenta glow, a vintage compressor with brass knobs and blurred studio monitors behind

Dynamics · 26 October 2026 · 8 min

Compressor killing your drums’ punch? Slow the attack down

NoDAW Labs · Lacquer Vol. 06

When a compressor kills the punch of your drums, the attack is usually too fast. It clamps down on the first few milliseconds of the hit, the crack you hear as punch, and turns it down along with everything else. Slow the attack until the front of the hit gets through and the compressor works on the body behind it, then set the release so it lets go before the next hit.

The snare sounds great soloed. Then you put a compressor on it because that’s what you do, pull the threshold down until the meter moves, and it gets smaller. Thicker maybe, rounder, but the smack is gone. Turn the makeup gain up to match and it’s just a louder, duller snare.

The compressor did exactly what you asked. It was just faster than the part you wanted to keep.

Where the punch actually is

A drum hit is two things in a row. First a crack that lasts a few milliseconds: the stick, the beater, the click at the front of the sample. Then the body that rings after it: shell, wires, room. Punch is mostly the gap in level between the two, how far the crack sticks up out of the body.

A compressor slow enough to miss the crack turns down only the body, so the gap grows and the drum hits harder. One fast enough to catch the crack turns both down, and the gap shrinks or disappears. That’s the whole trick, and the attack knob decides which one you get.

In the simple compressor we used for the tests below, attack is a time constant: the time it takes to get about 63% of the way to the gain reduction the threshold and ratio ask for. Here’s what that means in milliseconds, plus how much time you have between hits at a few tempos:

$ python3 attack_math.py
gain reduction applied after:   1 ms    3 ms   10 ms
  attack  0.1 ms                100%    100%    100% 
  attack    1 ms                 63%     95%    100% 
  attack   10 ms                 10%     26%     63% 
  attack   30 ms                  3%     10%     28% 

time between hits:  quarter    eighth      16th
   85 BPM            706 ms     353 ms     176 ms 
  100 BPM            600 ms     300 ms     150 ms 
  140 BPM            429 ms     214 ms     107 ms 
  170 BPM            353 ms     176 ms      88 ms 

A 10 ms attack has applied only 10% of its gain reduction one millisecond in, and 26% at three. A 0.1 ms attack is fully clamped before the first millisecond is over. Plugins don’t all define attack the same way. Some measure to a different point, and some change it with the material on purpose. So read the number on the knob as “faster or slower,” and let your ears decide the rest.

We measured it on a snare

This script runs a basic compressor over a drum file and measures every hit: the crack (the peak of the first 5 ms), the body (the RMS level from 20 to 150 ms), and the punch, the gap between them:

#!/usr/bin/env python3
"""What does a compressor's attack do to the punch of a drum? Runs a simple feed-forward compressor
(peak detector, hard knee, one-pole attack/release on the gain) over a drum file and measures, per hit:
the crack (peak of the first 5 ms) and the body (RMS from 20 to 150 ms), before and after.
'Punch' here = crack level minus body level, in dB. Usage:
python3 punch_check.py snare.wav [threshold dBFS] [ratio] [release ms] [hit spacing s] [attacks ms, comma-separated]"""
import sys, wave, numpy as np
with wave.open(sys.argv[1]) as w:
    sr = w.getframerate(); x = np.frombuffer(w.readframes(w.getnframes()), "<i2") / 32768.0
thr = float(sys.argv[2]) if len(sys.argv) > 2 else -24
ratio = float(sys.argv[3]) if len(sys.argv) > 3 else 4
rel = float(sys.argv[4]) if len(sys.argv) > 4 else 60
gap = float(sys.argv[5]) if len(sys.argv) > 5 else 0.6
db = lambda v: 20 * np.log10(v + 1e-12)

def compress(x, att_ms, rel_ms):
    want = np.maximum(db(np.abs(x)) - thr, 0) * (1 - 1 / ratio)       # gain reduction the knee asks for
    a, r = np.exp(-1 / (att_ms * 1e-3 * sr)), np.exp(-1 / (rel_ms * 1e-3 * sr))
    gr = np.empty_like(want); g = 0.0
    for i, v in enumerate(want):
        c = a if v > g else r
        g = c * g + (1 - c) * v; gr[i] = g
    return x * 10 ** (-gr / 20), gr

def measure(y):
    starts = np.arange(0, len(y) - int(0.15 * sr), int(gap * sr))
    crack = np.mean([db(np.abs(y[s:s + int(0.005 * sr)]).max()) for s in starts])
    body = np.mean([db(np.sqrt(np.mean(y[s + int(0.02 * sr):s + int(0.15 * sr)] ** 2))) for s in starts])
    return crack, body, starts

c0, b0, starts = measure(x)
print(f"threshold {thr:g} dBFS, ratio {ratio:g}:1, release {rel:g} ms, hits {gap*1000:.0f} ms apart")
print(f"dry:            crack {c0:6.1f} dBFS  body {b0:6.1f} dBFS  punch {c0-b0:5.1f} dB")
atts = [float(a) for a in sys.argv[6].split(",")] if len(sys.argv) > 6 else (0.1, 1, 10, 30)
for att in atts:
    y, gr = compress(x, att, rel)
    c, b, _ = measure(y)
    at_crack = np.mean([gr[s:s + int(0.005 * sr)].max() for s in starts])
    left = np.mean([gr[s - 1] for s in starts[1:]])
    print(f"attack {att:4g} ms:  crack {c:6.1f} ({c-c0:+5.1f})  body {b:6.1f} ({b-b0:+5.1f})  "
          f"punch {c-b:5.1f} dB ({(c-b)-(c0-b0):+5.1f})  GR in first 5 ms {at_crack:4.1f} dB, "
          f"still on at next hit {left:4.1f} dB")

The test file is a synthetic snare from make_snare.py: eight hits at 100 BPM, each a short noise crack over a 190 Hz shell tone and a noisy body, peaking at −3 dBFS. Threshold −20 dBFS, ratio 4:1, release 60 ms:

$ python3 punch_check.py snare.wav -20 4 60
threshold -20 dBFS, ratio 4:1, release 60 ms, hits 600 ms apart
dry:            crack   -3.0 dBFS  body  -21.9 dBFS  punch  18.9 dB
attack  0.1 ms:  crack   -8.7 ( -5.7)  body  -26.7 ( -4.8)  punch  18.0 dB ( -0.9)  GR in first 5 ms  7.8 dB, still on at next hit  0.0 dB
attack    1 ms:  crack   -3.9 ( -0.9)  body  -25.9 ( -4.0)  punch  21.9 dB ( +3.0)  GR in first 5 ms  5.1 dB, still on at next hit  0.0 dB
attack   10 ms:  crack   -3.1 ( -0.1)  body  -24.2 ( -2.3)  punch  21.1 dB ( +2.2)  GR in first 5 ms  1.3 dB, still on at next hit  0.0 dB
attack   30 ms:  crack   -3.0 ( -0.0)  body  -23.1 ( -1.2)  punch  20.1 dB ( +1.2)  GR in first 5 ms  0.5 dB, still on at next hit  0.0 dB

At 0.1 ms the compressor caught the crack and took 5.7 dB off it, more than the 4.8 dB it took off the body, so the punch went down 0.9 dB. That’s the flattened snare. At 1 ms the crack lost only 0.9 dB while the body lost 4.0, and the punch went up 3.0 dB, the most of the four. 10 ms still added 2.2 dB. At 30 ms the compressor was late for almost everything: the crack untouched and only 1.2 dB off the body.

So slower isn’t automatically better. Too slow and you’re barely compressing the hit at all. On this snare the sweet spot was 1 to 10 ms. On a real kit it moves: a kick with a long beater click, a snare sample with a fat front, a room mic with no crack at all. Start in that range, slow it down if the hit sounds pushed back, and speed it up if the front pokes out too much.

Release: let go before the next hit

Release is how fast the compressor stops compressing. If it’s still holding down when the next hit arrives, that hit’s crack gets turned down before the attack even matters. The room you have is the gap between hits, from the second half of the table above: 16th notes at 100 BPM are 150 ms apart, and at 140 BPM only 107 ms.

We rendered a 16th-note roll at 100 BPM, hits 150 ms apart, and ran it at 10 ms attack with a 60 ms and a 400 ms release:

$ python3 punch_check.py roll.wav -20 4 60 0.15 10
threshold -20 dBFS, ratio 4:1, release 60 ms, hits 150 ms apart
dry:            crack   -3.0 dBFS  body  -22.3 dBFS  punch  19.3 dB
attack   10 ms:  crack   -3.6 ( -0.6)  body  -24.5 ( -2.2)  punch  20.9 dB ( +1.6)  GR in first 5 ms  1.5 dB, still on at next hit  0.6 dB

$ python3 punch_check.py roll.wav -20 4 400 0.15 10
threshold -20 dBFS, ratio 4:1, release 400 ms, hits 150 ms apart
dry:            crack   -3.0 dBFS  body  -22.3 dBFS  punch  19.3 dB
attack   10 ms:  crack   -5.7 ( -2.7)  body  -26.1 ( -3.8)  punch  20.4 dB ( +1.1)  GR in first 5 ms  3.2 dB, still on at next hit  3.1 dB

With the 60 ms release, 0.6 dB of gain reduction was still on when each next hit landed, and the crack lost 0.6 dB. With 400 ms, 3.1 dB was still on and the crack lost 2.7 dB. Same attack, same threshold. The long release took the punch because the compressor never let go. On busy parts like hats, rolls and fast trap hi-hat patterns, a release longer than the gap between hits turns the compressor into a fader that’s always half down.

Setting it in the session

  1. Start in the middle. Attack around 10 ms, a release that finishes before the next hit, and the threshold down until the meter moves on every hit, not just the loudest.
  2. Sweep the attack and listen to the front. Go from slow to fast. The moment the crack goes soft, back off a little.
  3. Set the release by the meter. The gain reduction should get back to zero, or close, before the next hit. Watch it at the busiest part of the song, not the intro.
  4. Compare at the same level. Match the output with makeup gain and toggle bypass. Louder always sounds better, which is the trap in pick one monitoring level.
  5. Want weight and crack? Blend a slammed, fast copy under the untouched drums. Check the latency first, or the blend comes out thin, as in parallel compression sounds thin.

If you’d rather see it than trust your ears at 3 a.m., bounce the drum bus once with the compressor bypassed and once engaged, and put both through CoProducer. Its dynamic-range readouts sit next to LUFS and true peak in the report, so a bus that got flattened shows up as a smaller number, not just a feeling. Why that number isn’t loudness is in crest factor is not loudness.

Genre notes

Why does compression make my drums lose punch?
The attack is catching the first few milliseconds of the hit, the crack, and turning it down along with the body. Slow the attack so the crack gets through and the compressor works on the body instead.
What attack time should I use on drums?
There’s no single number, because plugins define attack differently. On our test snare, 1 to 10 ms added the most punch, 0.1 ms flattened it and 30 ms barely compressed it. Start around 10 ms and adjust by ear.
What release should I use on a drum compressor?
Short enough that the gain reduction gets back to zero before the next hit. At 100 BPM, 16th notes are 150 ms apart. A 400 ms release on a 16th-note roll left 3.1 dB of gain reduction on every hit.
Does a slow attack make drums louder?
It makes the peaks stick out further above the body, so drums hit harder at the same loudness. It also leaves taller peaks for the limiter to deal with, so check the master afterwards.

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.