Cheat sheet

Capacity and spectral efficiency cheat sheet

Shannon capacity, the Eb/N0 floor of −1.59 dB, ergodic and outage capacity in Rayleigh fading, MIMO capacity, and the NR CQI efficiencies from TS 38.214, with code and a chart.

Last verified 15 Nov 2026· 3GPP TS 38.214 V19.5.0 (Release 19); NumPy 2.5

This sheet is for engineers who need to know how far a design sits from the limit, or what spectral efficiency a given SNR can support. It covers the AWGN limit, fading, multiple antennas and the efficiencies 5G NR actually signals. The theory follows chapters 5 and 7 of Tse and Viswanath’s Fundamentals of Wireless Communication. The noise, SNR and capacity lesson builds it up from the start.

The AWGN limit

C = B log2(1 + SNR)          bit/s, SNR = P / (N0 B)
eta = C / B                  bit/s/Hz, the spectral efficiency
Eb/N0 >= (2^eta - 1) / eta   at spectral efficiency eta
SNR Capacity Notes
−10 dB 0.14 bit/s/Hz Power-limited. Capacity roughly linear in SNR
0 dB 1.00 bit/s/Hz
10 dB 3.46 bit/s/Hz
20 dB 6.66 bit/s/Hz Bandwidth-limited. Each extra 3 dB buys about 1 bit/s/Hz
30 dB 9.97 bit/s/Hz

Shannon capacity is a bound on reliable rate, not a modem’s rate. Practical codes operate some distance from it, and the distance grows as blocks get shorter.

The two regimes

Tse and Viswanath (section 5.2.2) separate a bandwidth-limited regime at high SNR, where capacity grows with bandwidth, from a power-limited regime at low SNR, where capacity tends to (P / N0) log2 e as bandwidth grows without limit. Setting C = P / Eb in that limit gives the smallest Eb/N0 any scheme can use, −1.59 dB, which they also derive. The values below come from the third formula above:

Spectral efficiency η Minimum Eb/N0
η → 0 ln 2 = −1.59 dB
0.5 bit/s/Hz −0.82 dB
1 bit/s/Hz 0.00 dB
2 bit/s/Hz 1.76 dB
4 bit/s/Hz 5.74 dB
6 bit/s/Hz 10.21 dB
8 bit/s/Hz 15.03 dB

Compare with the uncoded Eb/N0 values in the BER sheet. QPSK at BER 10⁻⁵ needs 9.6 dB for 2 bit/s/Hz, so the gap to the limit is almost 8 dB. Coding exists to close that gap.

Fading

Quantity Formula Notes
Ergodic capacity (fast fading, receiver knows h) E[log2(1 + abs(h)² SNR)] Coding spans many fades
Outage probability, Rayleigh (Tse and Viswanath eq. 5.55) p_out(R) = 1 − exp(−(2^R − 1) / SNR) Falls only as 1/SNR at high SNR
ε-outage capacity (eq. 5.57) log2(1 + F⁻¹(1 − ε) SNR), F the complementary CDF of abs(h)² For Rayleigh, F⁻¹(1 − ε) = −ln(1 − ε), close to ε

At 1 % outage in Rayleigh fading, the receiver needs about 20 dB more SNR than over AWGN for the same rate. Tse and Viswanath note that at low SNR the 1 % outage capacity is only about 1 % of the AWGN capacity. Diversity changes this sharply: with L independent branches the outage probability falls as 1/SNR^L.

Multiple antennas

Channel known at the transmitter (Tse and Viswanath eq. 7.10, waterfilling):
  C = sum_i log2(1 + P_i* lambda_i^2 / N0),  i = 1 .. n_min = min(n_t, n_r)

Channel unknown at the transmitter, equal power over n_t antennas:
  C = log2 det(I + (SNR / n_t) H H^H)

The λ_i are the singular values of the channel matrix H. At high SNR, i.i.d. Rayleigh MIMO capacity grows by about n_min bits/s/Hz for every 3 dB of SNR, against 1 bit/s/Hz for one antenna. That slope is the spatial multiplexing gain.

0102030-100102030AWGNRayleigh, ergodicRayleigh, 1 % outage2 x 2 MIMO, ergodic4 x 4 MIMO, ergodiccapacity (bit/s/Hz)SNR (dB)
Capacity in bit/s/Hz against SNR for AWGN, the ergodic capacity of a Rayleigh fading link, the 1 % outage capacity of a slow Rayleigh fading link, and ergodic capacity of 2 by 2 and 4 by 4 i.i.d. Rayleigh MIMO with equal power. Values printed by the code block below.

What NR signals: CQI Table 2

The UE reports channel quality as a 4-bit index. TS 38.214 (NR physical layer procedures for data) Table 5.2.2.1-3, the 256-QAM CQI table, maps each index to a modulation, a code rate × 1024 and an efficiency in bit per resource element. Efficiency = bits per symbol × code rate.

CQI Modulation Code rate × 1024 Efficiency
0 Out of range
1 QPSK 78 0.1523
2 QPSK 193 0.3770
3 QPSK 449 0.8770
4 16QAM 378 1.4766
5 16QAM 490 1.9141
6 16QAM 616 2.4063
7 64QAM 466 2.7305
8 64QAM 567 3.3223
9 64QAM 666 3.9023
10 64QAM 772 4.5234
11 64QAM 873 5.1152
12 256QAM 711 5.5547
13 256QAM 797 6.2266
14 256QAM 885 6.9141
15 256QAM 948 7.4063

Table 5.2.2.1-2 (up to 64QAM, top efficiency 5.5547) sits alongside it, as does Table 5.2.2.1-5 (‘table4-r17’), which reaches 1024QAM. TS 38.214 defines each index by a transport block error probability of at most 0.1 on a reference resource (10⁻⁵ for the low-rate Table 5.2.2.1-4), not by an SNR. The SNR at which a UE reports each index depends on its receiver. Per-resource-element efficiency is not carrier throughput: reference signals, control channels, guard bands and the cyclic prefix all take a share. See the numerology sheet for the grid.

Code

Complex Gaussian channels are generated with NumPy (complex128). The block runs in under a second.

import numpy as np

rng = np.random.default_rng(3)
snr_db = np.array([-10, -5, 0, 5, 10, 15, 20, 25, 30])
snr = 10 ** (snr_db / 10)

# AWGN: C = log2(1 + SNR) bit/s/Hz
c_awgn = np.log2(1 + snr)

# Ergodic capacity, Rayleigh fast fading, receiver knows h: E[log2(1 + |h|^2 SNR)]
g = rng.exponential(1.0, 200_000)
c_erg = np.array([np.mean(np.log2(1 + g * s)) for s in snr])

# 1 % outage capacity, Rayleigh slow fading: log2(1 + F^-1(1 - eps) SNR), F^-1(1 - eps) = -ln(1 - eps)
eps = 0.01
c_out = np.log2(1 + -np.log(1 - eps) * snr)

# MIMO, i.i.d. Rayleigh, equal power over nt antennas, no CSI at the transmitter
def mimo_ergodic(n: int, s: float, trials: int = 4000) -> float:
    h = (rng.standard_normal((trials, n, n)) + 1j * rng.standard_normal((trials, n, n))) / np.sqrt(2)
    m = np.eye(n) + (s / n) * h @ np.conj(np.transpose(h, (0, 2, 1)))
    return float(np.mean(np.log2(np.linalg.det(m).real)))

c_2x2 = np.array([mimo_ergodic(2, s) for s in snr])
c_4x4 = np.array([mimo_ergodic(4, s) for s in snr])

print("SNR_dB  AWGN  Rayleigh_ergodic  1%_outage  2x2  4x4")
for row in zip(snr_db, c_awgn, c_erg, c_out, c_2x2, c_4x4):
    print(f"{row[0]:6d} " + " ".join(f"{v:6.2f}" for v in row[1:]))

# Minimum Eb/N0 for a spectral efficiency eta: (2^eta - 1) / eta
for eta in [0.001, 0.5, 1, 2, 4, 6, 8]:
    print(f"eta = {eta:5g} bit/s/Hz: Eb/N0 >= {10*np.log10((2**eta - 1)/eta):6.2f} dB")

Expected output:

SNR_dB  AWGN  Rayleigh_ergodic  1%_outage  2x2  4x4
   -10   0.14   0.13   0.00   0.26   0.53
    -5   0.40   0.36   0.00   0.72   1.43
     0   1.00   0.86   0.01   1.68   3.35
     5   2.06   1.72   0.05   3.34   6.54
    10   3.46   2.91   0.14   5.54  10.90
    15   5.03   4.34   0.40   8.29  16.24
    20   6.66   5.89   1.00  11.31  22.13
    25   8.31   7.51   2.06  14.47  28.40
    30   9.97   9.15   3.47  17.69  34.88
eta = 0.001 bit/s/Hz: Eb/N0 >=  -1.59 dB
eta =   0.5 bit/s/Hz: Eb/N0 >=  -0.82 dB
eta =     1 bit/s/Hz: Eb/N0 >=   0.00 dB
eta =     2 bit/s/Hz: Eb/N0 >=   1.76 dB
eta =     4 bit/s/Hz: Eb/N0 >=   5.74 dB
eta =     6 bit/s/Hz: Eb/N0 >=  10.21 dB
eta =     8 bit/s/Hz: Eb/N0 >=  15.03 dB

The 1 % outage curve at 30 dB equals the AWGN curve at 10 dB, which is the 20 dB fade margin in numbers. The 4 × 4 curve gains about 6.3 to 6.5 bit/s/Hz per 5 dB at high SNR, against about 1.7 for AWGN.

Pitfalls

  • Quoting capacity at the SNR of the best user. Cell capacity depends on the SNR distribution.
  • Using ergodic capacity for a slow-fading link with short packets. Outage is the right measure there.
  • Assuming MIMO gain without rich scattering. A line-of-sight channel can have rank one.
  • Comparing an SNR measured over the occupied bandwidth with one measured over the whole channel.
  • Reading CQI efficiency as throughput per hertz of carrier.

Sources