3. The Physical Layer
Every abstraction in this book eventually rests on a voltage, a light pulse, or a radio wave travelling through matter — and this chapter is where the abstractions stop and physics begins. We cover how information is represented as a signal, the hard mathematical limits on how fast any channel can carry it, the encodings and modulations used to approach those limits, the media that carry the signals, how one medium is shared, and the devices that operate here. Understanding this layer is what separates engineers who can explain why a link is slow from those who can only observe that it is.
<a id="31-signals-and-data-transmission"></a>
3.1 Signals and Data Transmission
This subchapter establishes the vocabulary of signalling and then derives the two theorems that bound every communication channel ever built, before examining the physical effects that stop real links from reaching those bounds.
Analog vs Digital Signals
Theory
A network moves information by varying some physical quantity over time — voltage on copper, optical power in fibre, electric field strength in air. That varying quantity is a signal, and the first question is what set of values it is allowed to take.
An analog signal varies continuously: at any instant it can hold any value in a range, and between any two values lie infinitely many others. A microphone diaphragm, a vinyl groove, and the voltage on a traditional telephone line are analog. A digital signal takes only a finite set of discrete values, changing between them at defined instants. Two voltage levels representing 0 and 1 is the simplest case.
The critical insight — and the reason essentially all modern networking is digital — is regeneration. Every real medium degrades a signal: it attenuates, it distorts, it adds noise. With an analog signal, degradation is permanent. You can amplify it, but amplification multiplies the noise along with the signal, so a chain of amplifiers accumulates hiss until the message drowns. With a digital signal, a receiver only needs to answer "is this closer to the 0 level or the 1 level?" If noise is small relative to the gap between levels, the answer is right, and the receiver emits a perfectly clean new signal. Noise does not accumulate across a chain of regenerators.
The analogy: photocopying a photograph degrades it a little each generation, and the hundredth copy is mud. Retyping a page of text degrades nothing, provided each letter is still legible — because the typist makes a decision about each character rather than reproducing a smear of ink.
| Property | Analog | Digital |
|---|---|---|
| Values | Continuous | Discrete (finite alphabet) |
| Noise behaviour | Accumulates irreversibly | Removed at each regeneration |
| Repeater type | Amplifier (amplifies noise too) | Regenerator (reshape, retime, retransmit) |
| Multiplexing | Frequency division | Time division (and others) |
| Encryption, compression | Difficult | Natural |
| Typical modern use | The radio waveform itself, the copper waveform | Everything the network carries |
A subtlety worth stating early: the distinction is about representation, not about the medium. The voltage on a Cat6 cable is a physical continuum — it must be, since nature has no steps. What makes it digital is that the transmitter deliberately drives it toward a small number of target levels and the receiver deliberately decides among them. Between those two decisions it is a wobbling analog wave, and the whole art of the physical layer is keeping the wobble smaller than the gap.
Finally, note that "digital data" and "digital signal" are independent choices. All four combinations exist and are used:
- Digital data over a digital signal: Ethernet over copper.
- Digital data over an analog signal: Wi-Fi, DSL, 5G — modulation.
- Analog data over a digital signal: a voice call encoded by G.711 — codecs.
- Analog data over an analog signal: AM radio.
Examples
Noise on the two representations
ANALOG: the received wave IS the message; noise is now part of it, forever
sent: /\ /\ recovered: /\~ /`\
/ \ / \ / ~\ /~ \
noise -> irreversible distortion; amplifying makes it louder, not cleaner
DIGITAL: the receiver DECIDES, then emits a clean signal
sent: ___|‾‾‾|___|‾‾‾ received (noisy): _~_|‾~‾|_~_|‾‾~
| |
decision threshold ------------------------------+-----+------
regenerated: ___|‾‾‾|___|‾‾‾
noise is GONE, not reduced — as long as it never crossed the threshold
import random
def transmit(bits, noise_amplitude, regenerate: bool, hops: int):
"""Push a signal through several hops, with and without regeneration."""
HIGH, LOW, THRESHOLD = 1.0, 0.0, 0.5
signal = [HIGH if b else LOW for b in bits]
for _ in range(hops):
# Every hop adds noise to whatever waveform arrives.
signal = [v + random.uniform(-noise_amplitude, noise_amplitude) for v in signal]
if regenerate:
# Decide, then emit a mathematically perfect new signal.
signal = [HIGH if v > THRESHOLD else LOW for v in signal]
return [1 if v > THRESHOLD else 0 for v in signal]
original = [random.randint(0, 1) for _ in range(10_000)]
analog_style = transmit(original, 0.2, regenerate=False, hops=10) # amplify only
digital_style = transmit(original, 0.2, regenerate=True, hops=10) # regenerate
err_a = sum(a != b for a, b in zip(original, analog_style))
err_d = sum(a != b for a, b in zip(original, digital_style))
print(f"after 10 hops — accumulating noise: {err_a} bit errors")
print(f"after 10 hops — regenerated: {err_d} bit errors")
# after 10 hops — accumulating noise: 2143 bit errors <- noise summed to ~0.63 swing
# after 10 hops — regenerated: 0 bit errors <- each hop reset the damage
Key takeaways
- An analog signal takes continuous values; a digital signal takes a finite set of discrete values.
- Digital signalling permits regeneration: the receiver decides which symbol was sent and emits a clean copy, so noise does not accumulate across hops.
- Analog amplification boosts signal and noise together, so degradation is cumulative and permanent.
- The physical medium is always analog; what makes a link digital is the transmitter's targeting of discrete levels and the receiver's decision among them.
- Data and signal are independent: digital data often travels as an analog signal (Wi-Fi, DSL), and analog data often travels digitally (voice codecs).
🧪 Practice
- Classify each as digital data or analog data, and digital signal or analog signal: an MP3 over Wi-Fi, FM radio, a fax over a phone line, 1000BASE-T Ethernet.
- In the simulation above, raise
noise_amplitudeuntil the regenerated path also produces errors. What does that threshold correspond to physically?- Interview-style: Transatlantic fibre has repeaters every 50–100 km. Why does adding more repeaters not progressively degrade the data as it would on an analog line? (Hint: state what the repeater actually does with the waveform it receives.)
Bit Rate, Baud Rate, and Symbols
Theory
"Speed" is ambiguous at the physical layer, and conflating two measurements is the most common beginner error. The distinction hinges on the word symbol.
A symbol is one distinguishable state of the signal, held for one signalling interval. The transmitter selects a symbol, holds it for a fixed duration, then selects the next. If the signalling scheme offers only two symbols (say, two voltage levels), each symbol carries one bit. If it offers four distinguishable levels, each symbol selects among four possibilities and therefore carries two bits — because two bits are exactly what is needed to name one of four things.
That gives the definitions and the relationship between them:
- Baud rate (symbol rate, measured in baud or symbols/second) — how many symbols are transmitted per second. This is a property of the signalling and is limited by the channel's bandwidth.
- Bit rate (measured in bits/second) — how much information is transmitted per second.
bit rate = baud rate × log₂(M)
where M is the number of distinct symbols in the alphabet (the constellation size or number of levels).
The analogy: baud is how many times per second you hold up a flag; bit rate is how much you communicate, which also depends on how many different flags you own. Two flags let you say one bit per wave. Sixteen flags let you say four bits per wave, at the same waving speed — but your colleague must be able to tell them apart across the field, which is exactly where noise enters the story.
The two rates are equal only when M = 2. Every modern high-speed link uses M > 2, so quoting baud where bit rate is meant understates the link by a large factor:
| Scheme | Levels/states (M) | Bits per symbol | Example |
|---|---|---|---|
| NRZ (binary) | 2 | 1 | 10BASE-T conceptually, older serial links |
| MLT-3 | 3 | ~1 (coded) | 100BASE-TX |
| PAM-4 | 4 | 2 | 200G/400G Ethernet, DDR5 |
| PAM-5 | 5 | 2 (plus coding) | 1000BASE-T |
| QPSK | 4 phases | 2 | Satellite, LTE control channels |
| 16-QAM | 16 | 4 | Wi-Fi in moderate conditions |
| 256-QAM | 256 | 8 | Wi-Fi 5 at close range, DOCSIS 3.1 |
| 4096-QAM | 4096 | 12 | Wi-Fi 7 at very close range |
Two practical notes. First, 1000BASE-T's headline number is a good exercise: it runs 125 Mbaud on each of 4 twisted pairs using PAM-5, giving 125 × 10⁶ × 2 bits × 4 pairs = 1 Gb/s. The cable never carries a 1 GHz signal; it carries 125 Mbaud, which is why Cat5e (rated to 100 MHz) suffices.
Second, raising M is not free. Squeezing more levels into the same voltage range shrinks the gap between them, so each step up demands a better signal-to-noise ratio — roughly 6 dB more SNR per additional bit per symbol. This is the trade the next two topics formalise.
Examples
Same baud rate, different alphabets, different bit rates
2 levels (1 bit/symbol), 4 symbol periods = 4 bits
1 0 1 1
‾‾|__|‾‾‾‾|‾‾‾‾ decision threshold: 1 line, wide margins
4 levels (2 bits/symbol), 4 symbol periods = 8 bits
11 00 10 01
=== == three thresholds now fit in the SAME voltage
_ __ _ _ range -> each margin is 1/3 as wide
Same number of transitions per second. Twice the data. Triple the
vulnerability to noise.
import math
def bit_rate(baud, levels):
return baud * math.log2(levels)
schemes = [
("10BASE-T NRZ/Manchester", 20e6, 2, 1), # (name, baud, M, pairs)
("100BASE-TX MLT-3", 125e6, 2, 1), # 4B/5B coded, ~1 bit/symbol net
("1000BASE-T PAM-5", 125e6, 4, 4), # 4 usable levels + 1 for coding
("10GBASE-T PAM-16", 800e6, 16, 4),
]
for name, baud, m, pairs in schemes:
total = bit_rate(baud, m) * pairs
print(f"{name:<30} {baud/1e6:>5.0f} Mbaud x {int(math.log2(m))} bit/sym "
f"x {pairs} pair = {total/1e9:>5.2f} Gb/s")
# 10BASE-T NRZ/Manchester 20 Mbaud x 1 bit/sym x 1 pair = 0.02 Gb/s
# 100BASE-TX MLT-3 125 Mbaud x 1 bit/sym x 1 pair = 0.12 Gb/s
# 1000BASE-T PAM-5 125 Mbaud x 2 bit/sym x 4 pair = 1.00 Gb/s
# 10GBASE-T PAM-16 800 Mbaud x 4 bit/sym x 4 pair = 12.80 Gb/s
# ^ raw; coding overhead brings this to 10 Gb/s
# The SNR cost of each extra bit per symbol:
for bits in range(1, 9):
print(f"{2**bits:>4}-QAM: {bits} bits/symbol, needs roughly "
f"{6*bits:>2} dB SNR to demodulate reliably")
# 2-QAM: 1 bits/symbol, needs roughly 6 dB SNR ...
# 256-QAM: 8 bits/symbol, needs roughly 48 dB SNR ...
Key takeaways
- A symbol is one signalling state held for one interval; baud rate counts symbols per second, bit rate counts bits per second.
- bit rate = baud rate × log₂(M), where M is the number of distinguishable symbols.
- The two are equal only for binary signalling (M = 2); all modern fast links use M > 2.
- Increasing M raises data rate without raising baud rate — but shrinks noise margins, costing roughly 6 dB of required SNR per extra bit per symbol.
- 1000BASE-T achieves 1 Gb/s at only 125 Mbaud by using 4 pairs and multi-level PAM-5, which is why Cat5e's 100 MHz rating is sufficient.
🧪 Practice
- A link runs at 2400 baud using 8 distinguishable phases. What is its bit rate? What baud rate would a binary scheme need for the same bit rate?
- Explain why a "9600 baud modem" and a "9600 bps modem" may or may not be the same thing, and under what condition they are identical.
- Interview-style: Wi-Fi drops from 1024-QAM to QPSK as you walk away from the access point. Explain what is being traded and why the device does it automatically. (Hint: relate constellation density to the noise margin between adjacent symbols.)
Nyquist Theorem
Theory
Why can a link not simply run infinitely fast? The first of two hard limits comes from the channel's bandwidth — used here in its original, literal sense: the width of the range of frequencies the channel passes, measured in hertz. A voice telephone circuit passes roughly 300 Hz to 3400 Hz, so its bandwidth is about 3100 Hz. Cat5e passes DC to 100 MHz. This is a physical property of the wire, the filters, and the electronics, and it is not the same as the "bandwidth" meaning data rate used elsewhere in networking.
Here is the intuition. To send symbols quickly, the signal must change quickly. But rapid changes are, mathematically, high-frequency content — a perfectly square pulse contains frequency components extending to infinity. A channel with limited bandwidth removes the high-frequency components, so pulses arrive rounded and smeared. Smear them enough and consecutive symbols overlap, a condition called intersymbol interference (ISI), and the receiver can no longer tell where one symbol ends and the next begins.
Nyquist's sampling theorem (1924) puts a number on it. Over a noiseless channel of bandwidth B hertz, the maximum symbol rate that can be received without ISI is:
maximum symbol rate = 2B baud
Combining with the bit-rate relation from the previous topic gives the Nyquist capacity for a noiseless channel with M signal levels:
C = 2B × log₂(M) bits/second
The analogy: bandwidth is how quickly the channel can change its mind. A heavy bell rings slowly and cannot strike distinct notes faster than its decay allows; a small bell can. Nyquist says the channel can resolve at most two distinct decisions per cycle of its highest passable frequency.
Two implications deserve attention.
The 2B factor is why symbol rate is roughly twice the bandwidth in real specifications. 100BASE-TX signals at 125 Mbaud and uses MLT-3 specifically to fold the fundamental frequency down to about 31.25 MHz so it fits comfortably within Cat5's 100 MHz. Engineering at the physical layer is largely the art of getting the required frequency content inside the channel's passband.
The formula has no noise term, so it says capacity is unbounded. Take M to a million levels and C grows without limit. This is obviously false in reality, and the reason is the missing ingredient: noise. Nyquist gives the limit imposed by time and bandwidth; Shannon, next, gives the limit imposed by noise. A real channel is bound by whichever is lower — and it is almost always Shannon.
Examples
Bandwidth limits how fast the channel can change
Transmitted (ideal square pulses, 1 0 1 1 0):
_|‾|_|‾‾‾|_ ... contains frequency content far above B
Received through a channel of bandwidth B — high frequencies removed:
generous bandwidth (symbol rate << 2B):
_/‾\_/‾‾‾\_ rounded, but each symbol still clearly resolved
"eye" is open: \ /
\/
/\
/ \
insufficient bandwidth (symbol rate > 2B):
_/‾\/‾‾\_ symbols bleed into each other = ISI
"eye" is closed: XXXX -> receiver cannot decide
import math
def nyquist_capacity(bandwidth_hz, levels):
"""Maximum bit rate on a NOISELESS channel (Nyquist, 1924)."""
return 2 * bandwidth_hz * math.log2(levels)
channels = [
("Voice-grade phone line", 3_100, 2),
("Voice-grade phone line", 3_100, 16), # more levels, same wire
("Cat5e (100 MHz)", 100_000_000, 2),
("Cat6a (500 MHz)", 500_000_000, 16),
]
for name, bw, m in channels:
c = nyquist_capacity(bw, m)
print(f"{name:<26} B={bw/1e6:>7.4f} MHz M={m:>3} "
f"max symbol rate={2*bw/1e6:>7.2f} Mbaud C={c/1e6:>9.3f} Mb/s")
# Voice-grade phone line B= 0.0031 MHz M= 2 max symbol rate= 0.01 Mbaud C= 0.006 Mb/s
# Voice-grade phone line B= 0.0031 MHz M= 16 max symbol rate= 0.01 Mbaud C= 0.025 Mb/s
# Cat5e (100 MHz) B=100.0000 MHz M= 2 max symbol rate= 200.00 Mbaud C= 200.000 Mb/s
# Cat6a (500 MHz) B=500.0000 MHz M= 16 max symbol rate=1000.00 Mbaud C= 4000.000 Mb/s
# The formula's flaw, made obvious:
print(nyquist_capacity(3_100, 2**40) / 1e6, "Mb/s over a phone line with 2^40 levels")
# 0.248 Mb/s ... and with 2^1000 levels it would promise gigabits.
# Nyquist alone permits infinite capacity. Reality disagrees — see Shannon.
Key takeaways
- Bandwidth at the physical layer means the width of the passable frequency range in hertz, not the data rate.
- Limited bandwidth rounds and smears pulses; enough smearing produces intersymbol interference, closing the receiver's decision "eye".
- Nyquist: maximum symbol rate is 2B baud, so C = 2B·log₂(M) bits/s on a noiseless channel.
- Real signalling schemes are designed to fit their fundamental frequency inside the medium's passband — MLT-3 exists precisely for this.
- Nyquist ignores noise and therefore predicts unlimited capacity from unlimited levels; it must be paired with Shannon's limit.
🧪 Practice
- A channel has 1 MHz of bandwidth. Compute the Nyquist capacity for M = 2, 4, and 64 levels.
- Cat6 is rated to 250 MHz. What is the highest symbol rate it can carry without ISI, and how does that compare with 10GBASE-T's 800 Mbaud per pair? What must 10GBASE-T do to work at all?
- Interview-style: Nyquist says capacity grows without bound as you add signal levels. Why can you not build a terabit modem for a telephone line? (Hint: name the physical quantity Nyquist's formula omits entirely.)
Shannon Capacity and Noise
Theory
Nyquist tells you how fast you may signal; Shannon tells you how much information can survive the journey. Claude Shannon's 1948 paper founded information theory and produced the single most important formula in communications:
C = B × log₂(1 + S/N)
where C is capacity in bits per second, B is bandwidth in hertz, and S/N is the signal-to-noise ratio as a linear power ratio — not decibels. Since SNR is almost always quoted in dB, the conversion is mandatory and is where most errors happen:
SNR_linear = 10^(SNR_dB / 10)
The reasoning behind the formula is the noise-margin argument from earlier, made rigorous. Noise blurs each received symbol into a cloud of uncertainty. You may pack as many symbols into the signal range as you like, but once the clouds overlap, the receiver cannot distinguish them and adding more symbols conveys no additional information. The SNR determines how many reliably distinguishable levels fit, and Shannon computes the resulting information rate exactly.
What makes the theorem extraordinary is its strength in both directions. It is an upper bound: no coding scheme, however clever, however much processing power, can exceed C over that channel — this is not an engineering limitation but a mathematical impossibility, like exceeding the speed of light. And it is an achievability result: coding schemes exist that approach C with arbitrarily small error probability. Modern LDPC and turbo codes get within a fraction of a dB of the Shannon limit, which is why progress in link rates now comes overwhelmingly from more bandwidth (wider channels, more fibre wavelengths) and better SNR, not from cleverer codes.
The real capacity of a channel is min(Nyquist, Shannon). Shannon is almost always the binding constraint.
| SNR (dB) | SNR (linear) | Bits/s per Hz | Where you see it |
|---|---|---|---|
| 0 | 1 | 1.00 | Signal equals noise — marginal link |
| 10 | 10 | 3.46 | Poor Wi-Fi, edge of coverage |
| 20 | 100 | 6.66 | Usable Wi-Fi |
| 30 | 1,000 | 9.97 | Good Wi-Fi, 256-QAM territory |
| 40 | 10,000 | 13.29 | Excellent wired or very close wireless |
Noise itself has sources worth naming: thermal noise (Johnson–Nyquist noise, present in every conductor above absolute zero, and the irreducible floor), crosstalk (signal coupling from an adjacent pair), impulse noise (lightning, motors, switching transients — the main cause of burst errors), and intermodulation distortion.
Examples
import math
def shannon_capacity(bandwidth_hz, snr_db):
snr_linear = 10 ** (snr_db / 10) # dB -> power ratio; NOT optional
return bandwidth_hz * math.log2(1 + snr_linear)
def nyquist_capacity(bandwidth_hz, levels):
return 2 * bandwidth_hz * math.log2(levels)
links = [
("Telephone line", 3_100, 35),
("Wi-Fi 80 MHz, close", 80e6, 40),
("Wi-Fi 80 MHz, far", 80e6, 12),
("Cat6a 10GBASE-T", 500e6, 30),
]
for name, bw, snr in links:
c = shannon_capacity(bw, snr)
print(f"{name:<22} B={bw/1e6:>7.3f} MHz SNR={snr:>2} dB "
f"C={c/1e6:>9.2f} Mb/s ({c/bw:>5.2f} bit/s per Hz)")
# Telephone line B= 0.003 MHz SNR=35 dB C= 0.04 Mb/s ( 11.64 bit/s per Hz)
# Wi-Fi 80 MHz, close B= 80.000 MHz SNR=40 dB C= 1063.15 Mb/s ( 13.29 bit/s per Hz)
# Wi-Fi 80 MHz, far B= 80.000 MHz SNR=12 dB C= 329.77 Mb/s ( 4.12 bit/s per Hz)
# Cat6a 10GBASE-T B=500.000 MHz SNR=30 dB C= 4985.35 Mb/s ( 9.97 bit/s per Hz)
# The real limit is whichever bound is lower:
bw, snr, levels = 3_100, 35, 2**20
print(f"Nyquist says {nyquist_capacity(bw, levels)/1000:.1f} kb/s; "
f"Shannon says {shannon_capacity(bw, snr)/1000:.1f} kb/s -> "
f"actual limit {min(nyquist_capacity(bw, levels), shannon_capacity(bw, snr))/1000:.1f} kb/s")
# Nyquist says 124.0 kb/s; Shannon says 36.1 kb/s -> actual limit 36.1 kb/s
# This is exactly why 56k modems stopped there and never reached 128k.
# Read a real SNR and watch the rate adapt to it.
$ iw dev wlan0 link
# Connected to 4c:ed:fb:11:22:33 (on wlan0)
# signal: -45 dBm <- received signal power
# rx bitrate: 1201.0 MBit/s VHT-MCS 11 80MHz short GI VHT-NSS 2
# ^ high MCS index = dense constellation
# Move away from the AP:
# signal: -78 dBm <- 33 dB weaker
# rx bitrate: 58.5 MBit/s VHT-MCS 2 80MHz
# ^ the radio fell back to a sparse
# constellation because Shannon said so
Key takeaways
- Shannon: C = B·log₂(1 + S/N), with SNR expressed as a linear power ratio, converted from dB by 10^(dB/10).
- The result is both an absolute upper bound no coding can beat and an achievability proof that good codes can approach it.
- Real channel capacity is min(Nyquist, Shannon), and Shannon is normally the binding limit.
- Roughly 3 dB of extra SNR buys about 1 additional bit/s/Hz in the high-SNR region.
- Modern codes (LDPC, turbo) already operate near the limit, so rate improvements now come from more bandwidth or better SNR.
- Noise sources: thermal (irreducible), crosstalk, impulse (causes burst errors), and intermodulation.
🧪 Practice
- Compute Shannon capacity for a 20 MHz Wi-Fi channel at 25 dB SNR. Then recompute at 80 MHz and explain why channel width is the more powerful lever.
- A vendor claims 100 Mb/s over a 1 MHz channel. What SNR in dB would that require? Comment on whether this is plausible.
- Interview-style: Your Wi-Fi shows full signal bars but transfers are slow. Give two physical-layer explanations. (Hint: signal strength is only the numerator of the ratio that actually matters.)
Attenuation, Distortion, and Interference
Theory
Shannon says capacity depends on SNR. Real media attack SNR in three distinct ways, and distinguishing them is the core of physical-layer troubleshooting: attenuation weakens the signal, distortion deforms it, and interference and noise add unwanted energy to it.
Attenuation is the loss of signal power with distance, caused by resistance in copper, scattering and absorption in fibre, and spreading in free space. It is measured in decibels, a logarithmic unit that turns the multiplicative nature of loss into simple addition:
dB = 10 × log₁₀(P_out / P_in)
Memorising three anchor values makes link budgets mental arithmetic: −3 dB = half the power, −10 dB = one tenth, −20 dB = one hundredth. Because decibels add, a link with 2 dB of connector loss, 12 dB of fibre loss, and 1 dB of splice loss has 15 dB total. Note that copper attenuation increases with frequency, which is precisely why a cable rated to 100 MHz fails at 500 MHz: the high-frequency components arrive too weak while the low ones arrive strong.
Distortion is deformation of the signal's shape even when its power is adequate. Two mechanisms matter:
- Delay distortion / dispersion — different frequency components travel at different speeds, so a pulse launched sharp arrives spread out. In fibre this appears as modal dispersion (different light paths in multi-mode fibre have different lengths) and chromatic dispersion (different wavelengths travel at different speeds). This is what limits multi-mode fibre distance far more than attenuation does.
- Amplitude distortion — the channel attenuates some frequencies more than others, changing the pulse shape.
Both produce the same end result: pulse spreading, leading to intersymbol interference.
Interference and noise add energy that was never sent. Crosstalk is the dominant form on twisted pair, and comes in named varieties you will meet on any cable tester:
| Measurement | Meaning | Why it matters |
|---|---|---|
| NEXT (Near-End Crosstalk) | Coupling into an adjacent pair measured at the transmitting end | Worst case, because the interfering signal is at full strength |
| FEXT (Far-End Crosstalk) | Coupling measured at the far end | Both signals have attenuated |
| ACR-F / ACR-N | Attenuation-to-crosstalk ratio | The real figure of merit: signal margin over crosstalk |
| Return loss | Power reflected by impedance mismatches | Bad terminations and kinks show up here |
| Alien crosstalk (AXT) | Coupling from a different cable in the bundle | The limiting factor for 10GBASE-T; why Cat6a is thicker |
Each has a characteristic fix: attenuation is solved by shorter runs, better cable, or regeneration; distortion by equalisation, better cable, or single-mode fibre; interference by shielding, twisting, physical separation, and differential signalling. Twisting deserves special mention — it is why twisted pair exists. An interfering field couples nearly equally into both conductors of a twisted pair, and because the receiver reads only the difference between them, the common-mode interference cancels. Tighter twists reject better, which is why Cat6a has a tighter lay than Cat5e.
Examples
Three impairments, three distinct signatures
ORIGINAL ATTENUATION DISTORTION INTERFERENCE
_|‾|_|‾|_ _.-.._.-.._ _/‾\__/‾\_ _|‾|/\|‾|~_
full swing same shape, same power, right shape,
less power smeared in time plus foreign energy
Fix: amplify Fix: equalise, Fix: shield, twist,
or shorter run, separate, use
regenerate better fibre differential signalling
Why twisting works (differential signalling):
conductor A: signal + noise \ receiver computes A - B:
conductor B: -signal + noise / = 2 x signal + 0 x noise
the noise coupled EQUALLY into both and therefore subtracts away
import math
def db(p_out, p_in):
return 10 * math.log10(p_out / p_in)
def apply_loss(power_mw, loss_db):
return power_mw * 10 ** (-loss_db / 10)
# Anchor values worth memorising
for loss in (3, 10, 20, 30):
print(f"-{loss:>2} dB leaves {10**(-loss/10)*100:>6.2f}% of the power")
# - 3 dB leaves 50.12% of the power
# -10 dB leaves 10.00% of the power
# -20 dB leaves 1.00% of the power
# -30 dB leaves 0.10% of the power
# A fibre link budget: does it close?
tx_power_dbm = -3.0 # transceiver output
rx_sensitivity = -18.0 # minimum power the receiver can decode
losses = {"connector pairs (4 x 0.5 dB)": 2.0,
"fibre 10 km @ 0.35 dB/km": 3.5,
"splices (2 x 0.1 dB)": 0.2}
total_loss = sum(losses.values())
rx_power = tx_power_dbm - total_loss # dB values simply ADD
margin = rx_power - rx_sensitivity
for item, loss in losses.items():
print(f" {item:<30} -{loss:>4.1f} dB")
print(f" {'TOTAL LOSS':<30} -{total_loss:>4.1f} dB")
print(f"Rx power {rx_power:+.1f} dBm vs sensitivity {rx_sensitivity:+.1f} dBm "
f"-> margin {margin:.1f} dB {'OK' if margin > 3 else 'TOO TIGHT'}")
# connector pairs (4 x 0.5 dB) - 2.0 dB
# fibre 10 km @ 0.35 dB/km - 3.5 dB
# splices (2 x 0.1 dB) - 0.2 dB
# TOTAL LOSS - 5.7 dB
# Rx power -8.7 dBm vs sensitivity -18.0 dBm -> margin 9.3 dB OK
# Impairments as a cable tester reports them.
$ # Certification report for a Cat6a permanent link, 88 m
# PASS Wire map .................... correct, no split pairs
# PASS Insertion loss (attenuation) 31.2 dB @ 500 MHz (limit 36.4) margin 5.2
# PASS NEXT ........................ 42.1 dB worst pair (limit 38.0) margin 4.1
# FAIL Return loss ................. 7.2 dB @ 220 MHz (limit 8.0) margin -0.8
# ^ a reflection: usually a bad termination, a kink, or a mismatched patch cord
# The same story on a live optic — read the actual received power:
$ ethtool -m eth0 | grep -iE 'power|temperature'
# Laser output power : -2.51 dBm
# Receiver signal average optical power : -8.74 dBm <- compare to sensitivity
# Module temperature : 41.23 degrees C
Key takeaways
- Attenuation (power loss), distortion (shape deformation), and interference (added energy) are three separate impairments with three separate fixes.
- Decibels are logarithmic and additive: −3 dB is half power, −10 dB is one tenth, −20 dB is one hundredth.
- Copper attenuation rises with frequency, which is why cable categories are specified by a maximum frequency rather than a data rate.
- Dispersion (modal and chromatic) spreads pulses in fibre and limits multi-mode distance more than attenuation does.
- Crosstalk measurements — NEXT, FEXT, ACR, return loss, and alien crosstalk — are the standard certification metrics for twisted pair.
- Twisting plus differential signalling cancels common-mode interference, which is the entire reason twisted pair works.
🧪 Practice
- A signal enters a cable at 10 mW and exits at 0.1 mW. Express the loss in dB. If you concatenate two such cables, what is the total loss and output power?
- Compute whether a link closes: transmitter +1 dBm, receiver sensitivity −22 dBm, 40 km of fibre at 0.25 dB/km, 6 connector pairs at 0.4 dB each. State the margin.
- Interview-style: A 90 m Cat6 run passes attenuation tests but fails NEXT. What physical causes would you investigate, and why does untwisting the pairs at the jack matter so much? (Hint: think about what the twist is doing and over what distance the cancellation is lost.)
<a id="32-encoding-and-modulation"></a>
3.2 Encoding and Modulation
Having established what a channel permits, this subchapter covers how bits are actually turned into signals: line codes for baseband copper and fibre, block codes that fix their weaknesses, the clock-recovery problem that motivates both, and the modulation schemes used when the signal must ride on a carrier.
NRZ, NRZI, and Manchester Encoding
Theory
A line code is the rule mapping bits to signal levels for baseband transmission — signalling directly on the medium without a carrier. The naive rule seems obviously correct, and understanding exactly why it fails motivates everything else in this subchapter.
NRZ (Non-Return-to-Zero) is that naive rule: hold one voltage for a 1 and another for a 0, for the whole bit period. ("Non-return-to-zero" distinguishes it from older schemes that dropped back to 0 V between bits.) In NRZ-L the level is the value. It is maximally efficient — 1 bit per symbol, and the signal only changes when the data changes, so the required bandwidth is minimal. It also has two fatal flaws:
- No clock recovery on long runs. Transmit 10,000 consecutive zeros and the line sits flat for 10,000 bit periods. The receiver's clock, running on its own crystal, drifts. After enough identical bits it miscounts, and every bit thereafter is garbage. This is a synchronisation failure, not a noise failure.
- DC bias / baseline wander. A long run of the same value gives the signal a non-zero average. Real receivers are AC-coupled through transformers and capacitors that cannot pass DC, so the baseline drifts toward the mean and the decision threshold ends up in the wrong place.
NRZI (Non-Return-to-Zero Inverted) fixes half of one problem by encoding data in transitions rather than levels: a 1 causes a transition, a 0 causes no transition (the common convention). Now a run of ones is a rapid alternation — self-clocking and DC-balanced. A run of zeros is still flat, so NRZI alone is not enough; it is always paired with a block code that guarantees frequent ones, as in USB and FDDI.
NRZI has a second, underrated virtue: because information lives in changes rather than absolute levels, inverting the wires does not corrupt the data. Differential schemes are immune to polarity reversal.
Manchester encoding solves the clock problem completely and pays a heavy price. Every bit period contains a mid-bit transition, and the direction of that transition carries the value. Under IEEE 802.3's convention, a 0 is a high-to-low transition and a 1 is a low-to-high transition. The consequences:
- Perfectly self-clocking. A transition occurs in every single bit period regardless of data, so the receiver can resynchronise continuously. No run-length problem exists.
- Perfectly DC-balanced. Every bit spends half its period high and half low, so the average is always zero.
- 100 percent bandwidth overhead. Two signal elements per bit means the baud rate is twice the bit rate: 10BASE-T at 10 Mb/s signals at 20 Mbaud and needs 20 MHz of bandwidth for 10 Mb/s of data.
That overhead is why Manchester was abandoned above 10 Mb/s. Differential Manchester (used in Token Ring) is a variant where a transition at the start of the bit means 0 and no start transition means 1, with the mid-bit transition always present for clocking — combining self-clocking with polarity independence.
| Code | Transitions guaranteed? | DC balanced? | Baud per bit | Used by |
|---|---|---|---|---|
| NRZ-L | No | No | 1.0 | Simple serial, internal buses |
| NRZI | Only on 1s | Only if 1s are frequent | 1.0 | USB, FDDI (with 4B/5B) |
| Manchester | Yes, every bit | Yes | 2.0 | 10BASE-T, RFID, some IoT radios |
| Differential Manchester | Yes, every bit | Yes | 2.0 | Token Ring (802.5) |
| MLT-3 | With scrambling | Approximately | ~1.0 | 100BASE-TX |
Examples
The bit sequence 1 0 1 1 0 0 0 1 in four line codes
bits 1 0 1 1 0 0 0 1
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
NRZ-L ‾‾‾‾‾|_____|‾‾‾‾‾‾‾‾‾‾‾|_________________|‾‾‾‾‾
level = value. Note the flat stretch of three 0s:
with 10,000 of them the receiver loses count entirely.
NRZI ‾‾‾‾‾|_____ _____|‾‾‾‾‾|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|_____
^transition ^no ^transition ^still flat for the 0 run
on 1 transition on 1 -> needs 4B/5B to help
on 0
MANCHESTER (802.3: 0 = high->low, 1 = low->high)
_|‾ ‾|_ _|‾ _|‾ ‾|_ ‾|_ ‾|_ _|‾
^every single bit period has a mid-bit transition
^^ two signal elements per bit -> 2x the bandwidth
DIFFERENTIAL MANCHESTER (transition at START = 0)
_|‾ |‾|_ ‾|_ _|‾ |_|‾ |‾|_ |_|‾ ‾|_
^start transition marks a 0; mid-bit always present
def nrz_l(bits):
return list(bits) # level IS the value; nothing to compute
def nrzi(bits, start_level=0):
"""A 1 flips the level; a 0 holds it."""
level, out = start_level, []
for b in bits:
if b == 1:
level ^= 1 # transition encodes the one
out.append(level)
return out
def manchester(bits):
"""Each bit becomes TWO half-bit levels -> doubles the symbol rate."""
# IEEE 802.3: 0 -> (high, low) = 1,0 ; 1 -> (low, high) = 0,1
out = []
for b in bits:
out.extend([0, 1] if b == 1 else [1, 0])
return out
bits = [1, 0, 1, 1, 0, 0, 0, 1]
print("bits ", bits)
print("NRZ-L ", nrz_l(bits))
print("NRZI ", nrzi(bits))
print("Manchester", manchester(bits), f"<- {len(manchester(bits))} symbols for "
f"{len(bits)} bits = {len(manchester(bits))/len(bits):.0%} overhead")
# bits [1, 0, 1, 1, 0, 0, 0, 1]
# NRZ-L [1, 0, 1, 1, 0, 0, 0, 1]
# NRZI [1, 1, 0, 1, 1, 1, 1, 0]
# Manchester [0,1, 1,0, 0,1, 0,1, 1,0, 1,0, 1,0, 0,1] <- 16 symbols for 8 bits = 200% overhead
# Quantifying the run-length danger of NRZ:
def longest_run(seq):
best = run = 1
for a, b in zip(seq, seq[1:]):
run = run + 1 if a == b else 1
best = max(best, run)
return best
payload = [0] * 5000 + [1, 0, 1] # a long stretch of zero bytes in a file
print("longest flat run, NRZ-L:", longest_run(nrz_l(payload))) # 5000
print("longest flat run, Manchester:", longest_run(manchester(payload))) # 2
# 5000 bit periods with no edge will desynchronise any practical receiver.
Key takeaways
- A line code maps bits to baseband signal levels; the requirements are clock recoverability, DC balance, and bandwidth efficiency.
- NRZ-L is bandwidth-efficient but fails on long identical runs: no clock edges and accumulating DC bias.
- NRZI encodes data as transitions (1 = transition, 0 = none), giving polarity independence but still failing on runs of zeros.
- Manchester guarantees a mid-bit transition every bit, so it is self-clocking and DC-balanced, at the cost of doubling the required bandwidth.
- Manchester's 100 percent overhead is why 10BASE-T needs 20 MHz for 10 Mb/s, and why faster Ethernet abandoned it for block codes.
🧪 Practice
- Encode
1 1 0 1 0 0 1in NRZ-L, NRZI (starting low), and Manchester. Draw all three.- Explain why 100BASE-TX could not simply use Manchester, computing the bandwidth it would have required and comparing with Cat5's 100 MHz rating.
- Interview-style: Why is DC balance a requirement rather than a nicety? (Hint: consider what transformer coupling and capacitors in the receiver front end can and cannot pass.)
4B/5B and 8B/10B Line Codes
Theory
Manchester guarantees transitions by spending an entire extra signal element per bit — a 100 percent tax. The insight behind block coding is that you do not need a transition in every bit period; you only need transitions often enough that the receiver's clock never drifts too far. So instead of a fixed per-bit rule, map blocks of data bits to slightly larger blocks of code bits, choosing only those code words with good properties.
4B/5B maps every 4-bit nibble to a 5-bit code word. There are 32 possible 5-bit words and only 16 nibbles to encode, so the designers selected the 16 output words that contain no more than one leading zero and no more than two trailing zeros — guaranteeing that no valid data stream ever has more than three consecutive zeros. Combined with NRZI (where a 1 produces a transition), this bounds the gap between transitions and solves the clock problem. Overhead is 5/4 = 25 percent, so 100BASE-TX carries 100 Mb/s of data at 125 Mbaud — a vast improvement over Manchester's 200 Mbaud.
The 16 unused code words are not wasted. They become control symbols: 11000 11000 (the J-K pair) marks the start of a stream, 01101 is IDLE, 00111 is HALT. This is a recurring and important pattern — an out-of-band signalling alphabet distinct from any possible data, letting the physical layer mark boundaries unambiguously without any risk of a data pattern imitating a delimiter.
8B/10B, developed at IBM by Widmer and Franaszek in 1983, maps 8 data bits to 10 code bits. Same 25 percent overhead, but it adds a property 4B/5B lacks: exact DC balance, enforced by a mechanism called running disparity.
Each 10-bit code word has either five ones and five zeros (perfectly balanced, used as-is) or a 6/4 or 4/6 split. Words in the latter class come in two versions, one with a positive imbalance and one with negative. The encoder tracks the cumulative disparity of everything it has sent and always picks the version that pushes it back toward zero. The result is a signal whose DC content stays bounded forever, regardless of the data — exactly what AC-coupled receivers and optical links require.
8B/10B also defines comma characters (notably K28.5, containing a bit pattern that cannot appear at any other alignment) used for byte alignment: the receiver hunts for the comma to learn where code word boundaries lie in the raw bit stream. It is used by Gigabit Ethernet (1000BASE-X), Fibre Channel, SATA, PCIe generations 1 and 2, and DisplayPort.
At 10 Gb/s and beyond, 25 percent overhead becomes intolerable, so 64B/66B takes over: 64 data bits plus a 2-bit synchronisation header, for just 3.1 percent overhead. It cannot guarantee run length by construction, so it uses a self-synchronising scrambler to make long runs statistically negligible, with the 2-bit header (always 01 or 10, never 00 or 11) providing block alignment. PCIe 3.0 onward uses the same idea as 128B/130B.
| Code | Ratio | Overhead | Guarantees | Used by |
|---|---|---|---|---|
| Manchester | 1:2 | 100% | Transition every bit | 10BASE-T |
| 4B/5B | 4:5 | 25% | ≤ 3 consecutive zeros | 100BASE-TX, FDDI |
| 8B/10B | 8:10 | 25% | Bounded DC + ≤ 5 run + commas | 1000BASE-X, SATA, PCIe 1/2 |
| 64B/66B | 64:66 | 3.1% | Statistical (scrambler) | 10GBASE-R and faster |
| 128B/130B | 128:130 | 1.6% | Statistical | PCIe 3.0+ |
Examples
Why a 25% tax beats a 100% tax
10 Mb/s Manchester : 20 Mbaud needed (2.0 x)
100 Mb/s 4B/5B : 125 Mbaud needed (1.25 x) <- then MLT-3 folds the
fundamental down to 31.25 MHz
1 Gb/s 8B/10B : 1250 Mbaud needed (1.25 x)
10 Gb/s 64B/66B : 10.3125 Gbaud (1.03 x) <- 25% would have cost 2.5 Gbaud
8B/10B running disparity in action (RD starts negative):
byte chosen code word ones/zeros RD after
D21.1 1010101001 5/5 unchanged (balanced word)
D10.2 0101010101 5/5 unchanged
D23.1 1110100010 5/5 unchanged
D30.1 0111100010 (RD-) 5/5 unchanged
D2.0 1011010100 (RD-) 5/5 unchanged
...a 6/4 word would flip RD to +, forcing the NEXT unbalanced word
to be chosen from the 4/6 column. The average NEVER drifts.
# 4B/5B: the real table, and the run-length guarantee it provides.
FOUR_B_FIVE_B = {
0x0:"11110", 0x1:"01001", 0x2:"10100", 0x3:"10101",
0x4:"01010", 0x5:"01011", 0x6:"01110", 0x7:"01111",
0x8:"10010", 0x9:"10011", 0xA:"10110", 0xB:"10111",
0xC:"11010", 0xD:"11011", 0xE:"11100", 0xF:"11101",
}
CONTROL = {"IDLE":"11111", "J":"11000", "K":"10001", "HALT":"00100"}
# Note: none of the control words can be produced by encoding data.
def encode_4b5b(data: bytes) -> str:
out = []
for byte in data:
out.append(FOUR_B_FIVE_B[byte >> 4]) # high nibble first
out.append(FOUR_B_FIVE_B[byte & 0x0F]) # then low nibble
return "".join(out)
def longest_zero_run(s: str) -> int:
return max((len(r) for r in s.split("1")), default=0)
worst_case = bytes([0x00] * 20) # 160 consecutive zero bits raw
raw = "".join(f"{b:08b}" for b in worst_case)
coded = encode_4b5b(worst_case)
print(f"raw : longest zero run = {longest_zero_run(raw)} bits")
print(f"4B/5B : longest zero run = {longest_zero_run(coded)} bits "
f"({len(coded)} bits for {len(raw)} -> {len(coded)/len(raw)-1:.0%} overhead)")
# raw : longest zero run = 160 bits <- receiver clock would be lost
# 4B/5B : longest zero run = 3 bits <- guaranteed by construction
# 4B/5B : (200 bits for 160 -> 25% overhead)
# Overhead comparison across the generations:
for name, din, dout in [("Manchester",1,2), ("4B/5B",4,5), ("8B/10B",8,10),
("64B/66B",64,66), ("128B/130B",128,130)]:
print(f"{name:<12} {dout/din:.4f}x symbols per bit "
f"= {(dout/din - 1)*100:5.1f}% overhead")
Key takeaways
- Block codes map n data bits to m > n code bits, choosing only code words with good transition density and DC properties.
- 4B/5B guarantees no more than three consecutive zeros at 25 percent overhead, and its 16 spare code words become control symbols distinguishable from all data.
- 8B/10B adds exact DC balance via running disparity — alternating between positive and negative versions of unbalanced words — plus comma characters for byte alignment.
- 64B/66B cuts overhead to 3.1 percent by replacing construction-based guarantees with a scrambler plus a 2-bit sync header.
- Reserving code words for control symbols that cannot occur in data is a general and powerful physical-layer technique.
🧪 Practice
- Encode the byte
0xA5using the 4B/5B table above and state the longest zero run in the result.- 1000BASE-X uses 8B/10B. Compute the line symbol rate required for 1 Gb/s of user data, then do the same for 10GBASE-R with 64B/66B at 10 Gb/s.
- Interview-style: Why did 10 Gigabit Ethernet abandon 8B/10B in favour of a scrambler-based code? (Hint: compute the raw line rate 8B/10B would have demanded, and consider what that costs in optics and power.)
Clock Recovery and Synchronization
Theory
Two topics have now referred to "the receiver losing count". This topic explains exactly what that means, because synchronisation is the hidden requirement behind nearly every physical-layer design decision.
Consider what the receiver must do. Symbols arrive as a continuous voltage. To decode, the receiver must sample that voltage at the right instant in each symbol period — ideally dead centre, where the eye is widest and the noise margin best. But nothing on the wire announces "sample now". The receiver must derive the timing itself.
The naive fix — run a local crystal at the same nominal rate — fails because no two crystals are identical. A typical crystal is specified to ±100 ppm (parts per million). Two devices could differ by 200 ppm, meaning the receiver gains or loses one full bit period every 5,000 bits. On a gigabit link that is a slip roughly every 5 microseconds. Without correction, the link is useless within moments.
The solution is clock recovery: extract timing from the data signal itself, using the transitions as timing references. A phase-locked loop (PLL) does this. It contains an oscillator running near the expected rate, a phase detector comparing the oscillator's edges to the incoming signal's transitions, and a feedback filter that nudges the oscillator to stay aligned. Every transition is a correction opportunity; between transitions, the PLL coasts on its own inertia.
This is why transition density is non-negotiable. The PLL can coast for a bounded number of symbol periods before drifting out of the sampling window, so the line code must guarantee transitions within that bound. Every scheme in the previous two topics exists to serve this requirement:
| Technique | How it guarantees transitions | Cost |
|---|---|---|
| Manchester | One per bit, unconditionally | 100% bandwidth |
| 4B/5B + NRZI | ≤ 3 zeros between ones | 25% bandwidth |
| 8B/10B | ≤ 5 identical bits, DC-bounded | 25% bandwidth |
| Scrambling (64B/66B) | Statistically, by XOR with a pseudorandom sequence | 3.1%, no hard guarantee |
| Separate clock line | A dedicated wire carries the clock | An extra conductor; only viable over short distances |
| Preamble / training sequence | A known pattern before each frame lets the PLL lock | Per-frame overhead |
Three further concepts complete the picture.
Scrambling deserves explanation because it seems like magic. The transmitter XORs the data with a pseudorandom bit sequence generated by a linear feedback shift register; the receiver runs an identical LFSR and XORs again to recover the original. Since XOR is its own inverse, the data comes back exactly. What has changed is the statistics: a pathological input like 10,000 zeros becomes pseudorandom, so long runs become vanishingly improbable rather than impossible. Self-synchronising scramblers derive their state from the received data, so no separate synchronisation is needed.
Alignment is a separate problem from timing. A PLL tells you when each bit arrives; it does not tell you where a byte or code word begins. That requires a distinguishable marker: the 8B/10B comma character, 64B/66B's sync header, or Ethernet's preamble and start-of-frame delimiter.
Plesiochronous operation and elastic buffers. Two ends of a link may run from independent clocks that are nominally equal but not exactly so. Over time the receiver accumulates surplus or deficit. Elastic buffers absorb the difference, and Ethernet leaves a deliberate margin by allowing the interframe gap to shrink or stretch slightly — the receiver can drop or insert idle symbols between frames without harming data.
Examples
The eye diagram: the single most useful physical-layer picture
Overlay hundreds of received symbol periods on top of each other:
‾‾‾‾\ /‾‾‾‾ <- the "1" rail
\ /
\ /
---------- \ / ------------ optimal sampling instant (eye centre)
\ / <- vertical opening = noise margin
\/ <- horizontal opening = timing margin
/\ (how much clock JITTER is tolerable)
/ \
_____ / \ _____ <- the "0" rail
A wide-open eye = healthy link. A closing eye = ISI, noise, or jitter.
The PLL's job is to place the sampling instant exactly at the widest point.
# How fast does an uncorrected clock lose alignment?
def slip_time(bit_rate_bps, ppm_error):
"""Seconds until accumulated drift equals one full bit period."""
bits_until_slip = 1_000_000 / ppm_error # drift of 1 bit per this many bits
return bits_until_slip / bit_rate_bps, bits_until_slip
for rate, label in [(10e6, "10 Mb/s"), (1e9, "1 Gb/s"), (10e9, "10 Gb/s")]:
secs, bits = slip_time(rate, 200) # 200 ppm combined mismatch
print(f"{label:>8}: slips one bit every {bits:,.0f} bits = {secs*1e6:,.2f} us")
# 10 Mb/s: slips one bit every 5,000 bits = 500.00 us
# 1 Gb/s: slips one bit every 5,000 bits = 5.00 us
# 10 Gb/s: slips one bit every 5,000 bits = 0.50 us
# Without clock recovery, a gigabit link desynchronises 200,000 times per second.
# A self-synchronising scrambler: X^58 + X^39 + 1, as used by 64B/66B.
class Scrambler:
def __init__(self, state=0x3FFFFFFFFFFFFFF):
self.state = state # 58-bit LFSR
def process(self, bit):
# Feedback taps at positions 39 and 58 produce the pseudorandom bit.
fb = ((self.state >> 38) ^ (self.state >> 57)) & 1
out = bit ^ fb # XOR is its own inverse
self.state = ((self.state << 1) | out) & ((1 << 58) - 1)
return out
tx, rx = Scrambler(), Scrambler()
pathological = [0] * 200 # 200 zeros: a PLL's nightmare
on_wire = [tx.process(b) for b in pathological]
recovered = [rx.process(b) for b in on_wire] # descrambling with identical state
def longest_run(seq):
best = run = 1
for a, b in zip(seq, seq[1:]):
run = run + 1 if a == b else 1
best = max(best, run)
return best
print("input longest run:", longest_run(pathological)) # 200
print("on wire longest run:", longest_run(on_wire)) # e.g. 7
print("recovered == input:", recovered == pathological) # True
# The wire never sees the pathological pattern; the data is bit-identical.
Key takeaways
- The receiver must sample each symbol at the correct instant, and must derive that timing from the signal because no separate clock is available.
- Independent crystals differ by tens to hundreds of ppm, so an uncorrected receiver slips a bit every few thousand bits.
- A phase-locked loop locks onto signal transitions and coasts between them, which is why line codes must guarantee transition density.
- Scrambling XORs data with an LFSR sequence to make long runs statistically improbable; XOR is self-inverse so the data is recovered exactly.
- Bit timing and byte/block alignment are different problems: alignment needs a distinguishable marker such as a comma character, sync header, or preamble.
- Elastic buffers and a variable interframe gap absorb the small clock-rate differences between independently clocked devices.
🧪 Practice
- Two devices have ±50 ppm crystals. Compute the worst-case mismatch and how many bits pass before a full bit period of drift accumulates.
- Explain why a scrambler provides no guarantee about run length, and why this is acceptable at 10 Gb/s when it would not have been for 10BASE-T.
- Interview-style: A link shows intermittent CRC errors that worsen at higher temperatures. Give a physical-layer hypothesis involving clocking. (Hint: think about what temperature does to crystal frequency and to the width of the eye opening.)
ASK, FSK, and PSK Modulation
Theory
Everything so far assumed baseband signalling — putting the data waveform directly on the medium. That works on a dedicated wire, but it fails whenever the channel does not pass low frequencies (radio, where an antenna for a baseband signal would be kilometres long), or whenever many signals must share one medium at once (cable TV, Wi-Fi, DSL).
The solution is modulation: take a steady high-frequency carrier wave, $A\sin(2\pi f t + \phi)$, and vary one of its three parameters in step with the data. A sine wave offers exactly three things to modulate, which is why there are exactly three fundamental digital modulation schemes.
ASK (Amplitude Shift Keying) varies the amplitude A. In its simplest binary form — on-off keying — the carrier is present for a 1 and absent for a 0. Trivially simple, and used in optical fibre (the laser is on or off) and cheap remote controls. Its weakness is that amplitude is exactly what noise and fading attack most directly, so ASK alone is poor on radio channels.
FSK (Frequency Shift Keying) varies the frequency f: one frequency for a 1, another for a 0. Because the information is in frequency rather than amplitude, FSK is robust against amplitude noise and fading. This is why it was used for early modems (Bell 103 at 300 baud), why it is the basis of Bluetooth's GFSK, and why LoRa's chirp modulation — a frequency-based scheme — achieves extraordinary range. The cost is spectral inefficiency: each symbol needs its own frequency slot, so bandwidth grows with constellation size.
PSK (Phase Shift Keying) varies the phase φ: the carrier's amplitude and frequency stay constant while its timing shifts. With constant amplitude, PSK is resilient to amplitude noise and spectrally efficient, which is why it dominates modern systems.
- BPSK uses two phases 180° apart — 1 bit per symbol, maximum robustness. Deep-space probes use it.
- QPSK uses four phases 90° apart — 2 bits per symbol at the same bandwidth. Used by satellite links, LTE control channels, and Wi-Fi at low rates.
- 8-PSK uses eight phases — 3 bits per symbol, but the phases are now only 45° apart and errors climb.
Beyond 8-PSK, packing more points onto a circle becomes inefficient: the points crowd together angularly while the interior of the constellation goes unused. The fix is to vary amplitude and phase together — which is QAM, the next topic.
A practical note: differential variants (DBPSK, DQPSK) encode data in the change of phase between consecutive symbols rather than in absolute phase. The receiver then needs no absolute phase reference, greatly simplifying the demodulator — the same trick NRZI plays at baseband.
| Scheme | Parameter varied | Noise resilience | Spectral efficiency | Typical use |
|---|---|---|---|---|
| ASK / OOK | Amplitude | Poor | Moderate | Fibre optics, IR remotes, RFID |
| FSK | Frequency | Good | Poor | Bluetooth, LoRa, legacy modems |
| PSK | Phase | Good | Good | Satellite, Wi-Fi, LTE, DVB |
| QAM | Amplitude + phase | Depends on density | Excellent | Wi-Fi, DOCSIS, LTE data, DSL |
Examples
The same bits 1 0 1 1 on one carrier, three ways
ASK /\/\/\ ------ /\/\/\ /\/\/\
\/\/\/ (off) \/\/\/ \/\/\/
amplitude carries the data; fading looks exactly like a 0
FSK /\/\/\ /‾\_/‾\_ /\/\/\ /\/\/\
fast slow fast fast
frequency carries the data; amplitude may vary freely
PSK /\/\/\ \/\/\/\ /\/\/\ /\/\/\
^abrupt 180 deg phase reversal at the symbol boundary
amplitude and frequency constant throughout
Constellations (I/Q plane):
BPSK QPSK 8-PSK
| | |
o---+---o o | o o o | o o
| | o | o
| o | o o o | o o
1 bit/sym 2 bits/sym 3 bits/sym
180 deg apart 90 deg apart 45 deg apart <- shrinking margins
import math, cmath
def psk_constellation(bits_per_symbol):
"""Evenly spaced points on the unit circle."""
m = 2 ** bits_per_symbol
return [cmath.exp(2j * math.pi * k / m) for k in range(m)]
for bps in (1, 2, 3, 4):
pts = psk_constellation(bps)
# Minimum distance between adjacent points determines error resilience.
d_min = abs(pts[0] - pts[1])
print(f"{2**bps:>3}-PSK: {bps} bit/sym, phase step {360/2**bps:>5.1f} deg, "
f"min distance {d_min:.3f}")
# 2-PSK: 1 bit/sym, phase step 180.0 deg, min distance 2.000
# 4-PSK: 2 bit/sym, phase step 90.0 deg, min distance 1.414
# 8-PSK: 3 bit/sym, phase step 45.0 deg, min distance 0.765
# 16-PSK: 4 bit/sym, phase step 22.5 deg, min distance 0.390
# Each added bit roughly HALVES the distance between neighbours -> why PSK
# stops at 8 and QAM takes over.
def modulate_qpsk(bits):
"""Map bit PAIRS to one of four phases (Gray-coded)."""
GRAY = {(0,0): 45, (0,1): 135, (1,1): 225, (1,0): 315} # adjacent symbols
out = [] # differ by ONE bit
for i in range(0, len(bits), 2):
pair = (bits[i], bits[i+1])
out.append(GRAY[pair])
return out
print(modulate_qpsk([1,0, 1,1, 0,0, 0,1]))
# [315, 225, 45, 135] <- 8 bits carried in 4 symbol periods
# Gray coding matters: a phase error to an ADJACENT symbol corrupts only 1 bit.
Key takeaways
- Modulation varies a carrier's amplitude, frequency, or phase in step with the data, enabling radio transmission and frequency sharing.
- ASK varies amplitude — simple, used in fibre, but vulnerable to fading and amplitude noise.
- FSK varies frequency — robust against amplitude impairments but spectrally inefficient.
- PSK varies phase at constant amplitude — robust and efficient; BPSK carries 1 bit/symbol, QPSK 2.
- Adding bits to a PSK constellation roughly halves the distance between adjacent points, so PSK stops being practical beyond 8-PSK.
- Gray coding assigns adjacent constellation points labels differing in one bit, so the most likely symbol errors corrupt only one bit.
- Differential variants encode data in phase changes, removing the need for an absolute phase reference.
🧪 Practice
- A system transmits at 2000 baud using 8-PSK. Compute the bit rate, and state how much more SNR it needs than QPSK at the same baud rate.
- Explain why fibre-optic links use simple on-off keying while Wi-Fi uses complex phase and amplitude schemes, referring to the noise environment of each.
- Interview-style: Why does Bluetooth use FSK while Wi-Fi uses QAM, when both share the 2.4 GHz band? (Hint: compare what each protocol optimises for — power and robustness, or throughput.)
QAM and Constellation Diagrams
Theory
PSK stalls because evenly spacing points around a circle wastes the interior of the signal space. QAM (Quadrature Amplitude Modulation) uses the whole plane, varying amplitude and phase simultaneously, and it is the modulation behind essentially every high-rate link you use.
The mechanism rests on an elegant fact: two carriers of the same frequency that differ in phase by 90° are orthogonal — they do not interfere, and a receiver can separate them perfectly. So the transmitter runs two independent amplitude-modulated streams on the same frequency:
s(t) = I × cos(2πft) − Q × sin(2πft)
The I ("in-phase") and Q ("quadrature") values are just coordinates. Plot them on a plane and you get the constellation diagram: each point is one symbol, its distance from the origin is the symbol's amplitude, and its angle is the symbol's phase. A constellation with M points carries log₂(M) bits per symbol.
The analogy: PSK is like communicating by pointing in one of several compass directions from a fixed distance. QAM lets you also choose how far to walk — using the whole field instead of just its perimeter, so many more distinguishable positions fit.
| Scheme | Points | Bits/symbol | Approx. SNR needed | Where used |
|---|---|---|---|---|
| QPSK (= 4-QAM) | 4 | 2 | ~10 dB | Satellite, LTE control, weak Wi-Fi |
| 16-QAM | 16 | 4 | ~18 dB | Mid-range Wi-Fi, LTE |
| 64-QAM | 64 | 6 | ~24 dB | Good Wi-Fi, DVB-T, LTE |
| 256-QAM | 256 | 8 | ~31 dB | Wi-Fi 5, DOCSIS 3.1, cable |
| 1024-QAM | 1024 | 10 | ~37 dB | Wi-Fi 6, close range |
| 4096-QAM | 4096 | 12 | ~43 dB | Wi-Fi 7, very close range |
The constellation diagram is also the primary diagnostic tool of RF engineering, because different impairments distort it in visually distinct ways. A clean link shows tight dots; noise fuzzes each point into a cloud; phase noise smears points into arcs; amplitude compression pulls outer points inward; and I/Q imbalance skews the grid. EVM (Error Vector Magnitude) quantifies this as the RMS distance between received points and their ideal positions, expressed as a percentage or in dB.
This explains adaptive modulation and coding, the behaviour you observe every time you walk away from an access point. The transmitter continuously estimates SNR and selects the densest constellation the channel currently supports — an MCS (Modulation and Coding Scheme) index. Strong signal, 1024-QAM; weak signal, QPSK. The rate change you see in iw dev wlan0 link is the device choosing a constellation, and it is Shannon's theorem being obeyed in real time.
Two related refinements complete the modern picture. OFDM (Orthogonal Frequency Division Multiplexing) splits the channel into hundreds of narrow subcarriers, each independently QAM-modulated — this turns one frequency-selective channel into many flat ones and is used by Wi-Fi, LTE, 5G, DSL, and DVB. MIMO uses multiple antennas to send independent spatial streams simultaneously, multiplying capacity beyond what a single channel allows.
Examples
16-QAM constellation: 4 bits per symbol, Gray-coded
Q
^
1011 | 1001 1101 1111 amplitude = distance from origin
o | o o o phase = angle from +I axis
|
1010 | 1000 1100 1110
o | o o o Adjacent points differ in exactly
-------+-------------------> I ONE bit (Gray coding), so the most
0010 | 0000 0100 0110 likely error costs 1 bit, not 4.
o | o o o
|
0011 | 0001 0101 0111
o | o o o
What impairments look like:
clean noise phase noise compression
o o o .:. .:. o o o o o o
o o o .:. .:. \ | / o o o <- outer points
o o o .:. .:. arcs o o o pulled inward
tight dots fuzzy clouds rotational smear grid warped
import math, itertools, random
def qam_constellation(bits_per_symbol):
"""Square QAM: a k x k grid of I/Q points, normalised to unit average power."""
m = 2 ** bits_per_symbol
k = int(math.sqrt(m))
levels = [2*i - (k-1) for i in range(k)] # e.g. k=4 -> [-3,-1,1,3]
pts = [complex(i, q) for i in levels for q in levels]
avg_power = sum(abs(p)**2 for p in pts) / len(pts)
return [p / math.sqrt(avg_power) for p in pts] # normalise for fair comparison
print(f"{'scheme':<10} {'bits/sym':>8} {'min distance':>13} {'extra SNR vs QPSK':>18}")
for bps in (2, 4, 6, 8, 10, 12):
pts = qam_constellation(bps)
# Smallest gap between any two symbols = the error-resilience bottleneck.
d_min = min(abs(a-b) for a, b in itertools.combinations(pts, 2))
if bps == 2:
d_ref = d_min
print(f"{2**bps:>4}-QAM {bps:>8} {d_min:>13.4f} "
f"{20*math.log10(d_ref/d_min):>15.1f} dB")
# 4-QAM 2 1.4142 0.0 dB
# 16-QAM 4 0.6325 7.0 dB
# 64-QAM 6 0.3086 13.2 dB
# 256-QAM 8 0.1534 19.3 dB
# 1024-QAM 10 0.0766 25.3 dB
# 4096-QAM 12 0.0383 31.3 dB
# Each extra 2 bits/symbol costs about 6 dB — exactly the rule of thumb.
def evm(received, ideal):
"""Error Vector Magnitude: RMS deviation from ideal points, as a percentage."""
err = sum(abs(r - i)**2 for r, i in zip(received, ideal)) / len(ideal)
ref = sum(abs(i)**2 for i in ideal) / len(ideal)
return math.sqrt(err / ref) * 100
ideal = qam_constellation(6) # 64-QAM
noisy = [p + complex(random.gauss(0, 0.05), random.gauss(0, 0.05)) for p in ideal]
print(f"EVM = {evm(noisy, ideal):.2f}% (64-QAM typically requires < 4%)")
# EVM = 7.07% -> this link would be forced down to 16-QAM
# Adaptive modulation, observed live.
$ watch -n1 'iw dev wlan0 link | grep -E "signal|bitrate"'
# signal: -41 dBm
# tx bitrate: 1729.4 MBit/s VHT-MCS 11 160MHz short GI VHT-NSS 2
# ^^^^^^^^^ MCS 11 = 1024-QAM, rate 5/6
# ... walk to another room ...
# signal: -71 dBm
# tx bitrate: 175.5 MBit/s VHT-MCS 3 80MHz VHT-NSS 2
# ^^^^^^^^ MCS 3 = 16-QAM — the radio gave up 4 bits
# per symbol to keep the error rate usable
Key takeaways
- QAM modulates two orthogonal carriers (I and Q) simultaneously, using the whole signal plane instead of only a circle.
- A constellation diagram plots symbols as I/Q points; distance from origin is amplitude, angle is phase, and M points carry log₂(M) bits.
- Each additional 2 bits per symbol halves the minimum distance between points and costs roughly 6 dB of required SNR.
- Constellation distortions are diagnostic: fuzzy clouds indicate noise, arcs indicate phase noise, inward-pulled corners indicate amplifier compression.
- EVM measures RMS deviation from ideal constellation points and is the standard quality metric.
- Adaptive modulation and coding selects the densest constellation the measured SNR supports — Shannon's limit enforced in real time.
- OFDM divides a channel into many narrow QAM-modulated subcarriers; MIMO adds parallel spatial streams.
🧪 Practice
- How many bits per symbol does 128-QAM carry? Sketch why a non-square constellation is needed for odd bit counts.
- A Wi-Fi link reports MCS 9 (256-QAM) on an 80 MHz channel with 2 spatial streams. Estimate the PHY rate, then recompute after a drop to 64-QAM.
- Interview-style: Your constellation display shows points smeared into arcs rather than fuzzy circles. What impairment does this indicate, and how does it differ from thermal noise? (Hint: an arc is movement in one specific coordinate of the I/Q plane — which one, and what physical quantity does it correspond to?)
<a id="33-transmission-media"></a>
3.3 Transmission Media
This subchapter surveys the physical substances signals travel through — copper, glass, and air — with the engineering parameters that decide which one a given link needs.
Twisted Pair Categories and Shielding
Theory
Twisted pair is the most deployed transmission medium on Earth: two insulated copper conductors twisted around each other, bundled four pairs to a cable. Its dominance comes from being cheap, flexible, easy to terminate, and — thanks to the twist — far better at rejecting interference than its cost suggests.
The twist is the whole invention, and it does two jobs. First, as established earlier, it makes interference couple equally into both conductors so that differential reception cancels it. Second, it stops the pair from acting as an efficient antenna, reducing both emission and reception of radio energy. Critically, each pair in a cable has a different twist rate — this prevents adjacent pairs from coupling into each other in a sustained way, which would otherwise be the dominant source of crosstalk.
Cables are sorted into categories, and the key realisation is that a category specifies a bandwidth in MHz, not a data rate. The data rate follows from that bandwidth combined with the encoding scheme, which is why the same Cat5e carries 100 Mb/s or 1 Gb/s depending on the Ethernet variant in use.
| Category | Bandwidth | Typical rating | Notes |
|---|---|---|---|
| Cat3 | 16 MHz | 10 Mb/s | Legacy; telephone and 10BASE-T |
| Cat5 | 100 MHz | 100 Mb/s | Obsolete, superseded by Cat5e |
| Cat5e | 100 MHz | 1 Gb/s to 100 m | "Enhanced": tighter crosstalk limits |
| Cat6 | 250 MHz | 1 Gb/s to 100 m; 10 Gb/s to 55 m | Often has a plastic spline separating pairs |
| Cat6a | 500 MHz | 10 Gb/s to 100 m | "Augmented"; thicker, controls alien crosstalk |
| Cat7 / Cat7a | 600 / 1000 MHz | 10 Gb/s | ISO-only; uses non-RJ45 connectors, rare |
| Cat8 | 2000 MHz | 25/40 Gb/s to 30 m | Data-centre top-of-rack only |
Two hard numbers anchor all copper Ethernet design. The 100 metre limit for a horizontal run is not arbitrary: it is 90 m of solid-core permanent cable plus 10 m of stranded patch cords at each end. And stranded versus solid matters — solid conductors have lower attenuation and belong in walls; stranded conductors survive flexing and belong in patch cords.
Shielding adds a conductive barrier against interference, at the cost of stiffness, expense, and a new failure mode. The naming is a standardised two-part code, XX/YZZ, where the first part describes the overall cable shield and the second the individual pair shield:
| Designation | Common name | Overall shield | Per-pair shield |
|---|---|---|---|
| U/UTP | UTP | None | None |
| F/UTP | FTP, ScTP | Foil | None |
| S/FTP | STP | Braid | Foil per pair |
| F/FTP | — | Foil | Foil per pair |
The essential caveat: a shield must be properly grounded at one end, and only one end. Grounding both ends of a long run can create a ground loop — a current path between two points at slightly different earth potentials — which turns the shield into an antenna and makes the cable perform worse than unshielded. Badly installed shielded cable is a common and counterintuitive fault.
A final trap for the unwary: RJ45 pin order. The two standard pinouts, T568A and T568B, differ by swapping the orange and green pairs. Either works, but both ends of a cable must use the same one — mixing them produces a crossover cable, which modern gear silently fixes with Auto-MDI-X but which will confuse anyone reading a cable tester. Splitting a pair across two non-twisted conductors ("split pair") is worse: it passes a continuity test but destroys crosstalk performance.
Examples
Why twisting works, and why twist rates differ per pair
Interference field couples into BOTH conductors equally:
___/‾‾‾\___/‾‾‾\___ conductor A: +signal + noise
‾‾‾\___/‾‾‾\___/‾‾‾ conductor B: -signal + noise
receiver computes A - B = 2*signal + 0*noise
Different twist rates per pair (turns per metre, illustrative):
pair 1 (blue) : ~ 34 tpm
pair 2 (orange) : ~ 38 tpm no two pairs stay aligned for long,
pair 3 (green) : ~ 42 tpm so coupling between them averages out
pair 4 (brown) : ~ 46 tpm
T568B pinout (the common choice in new installations):
pin 1 white/orange pin 5 white/blue
pin 2 orange pin 6 green <- note 3 and 6 are ONE pair,
pin 3 white/green pin 7 white/brown which is why naive
pin 4 blue pin 8 brown "straight across" wiring
splits a pair
# Category ratings, and the 100 m budget that governs every horizontal run.
CATEGORIES = {
"Cat5e": {"mhz": 100, "10g_m": 0, "1g_m": 100},
"Cat6": {"mhz": 250, "10g_m": 55, "1g_m": 100},
"Cat6a": {"mhz": 500, "10g_m": 100, "1g_m": 100},
"Cat8": {"mhz": 2000, "10g_m": 30, "1g_m": 30},
}
def can_run(category, speed_gbps, length_m):
spec = CATEGORIES[category]
limit = spec["10g_m"] if speed_gbps >= 10 else spec["1g_m"]
return limit >= length_m, limit
for cat in CATEGORIES:
for speed, length in [(1, 90), (10, 90), (10, 45)]:
ok, limit = can_run(cat, speed, length)
print(f"{cat:<6} {speed:>2} Gb/s over {length:>3} m: "
f"{'OK' if ok else 'NO':<3} (limit {limit} m)")
print()
# Cat5e 1 Gb/s over 90 m: OK (limit 100 m)
# Cat5e 10 Gb/s over 90 m: NO (limit 0 m)
# Cat5e 10 Gb/s over 45 m: NO (limit 0 m)
# Cat6 1 Gb/s over 90 m: OK (limit 100 m)
# Cat6 10 Gb/s over 90 m: NO (limit 55 m)
# Cat6 10 Gb/s over 45 m: OK (limit 55 m) <- Cat6 DOES do 10G, but short
# ...
# The 100 m budget is a sum, not a single cable:
budget = {"patch cord, wiring closet": 5, "permanent link in walls": 90,
"patch cord, work area": 5}
print(f"total channel = {sum(budget.values())} m (TIA-568 maximum: 100 m)")
# Verify what is actually installed before blaming the network.
$ ethtool eth0 | grep -E 'Speed|Duplex'
# Speed: 1000Mb/s
# Duplex: Full
# Running 1 Gb/s where 10 Gb/s was expected often means Cat5e in the walls.
# Some switches can measure cable length and locate faults electrically (TDR):
$ ethtool --cable-test eth0 ; ethtool --cable-test-result eth0
# Pair A code Open <- a broken conductor
# Pair A, fault length: 43.00m <- 43 m from this end: that is where to look
# Pair B code OK
# Pair C code OK
# Pair D code OK
Key takeaways
- Twisting makes interference couple equally into both conductors so differential reception cancels it; per-pair twist rates differ to limit crosstalk between pairs.
- Cable categories specify bandwidth in MHz, not data rate; the achievable rate depends on the encoding used.
- Key ratings: Cat5e 100 MHz / 1 Gb/s, Cat6 250 MHz / 10 Gb/s to 55 m, Cat6a 500 MHz / 10 Gb/s to 100 m, Cat8 2 GHz / 40 Gb/s to 30 m.
- The 100 m channel limit is 90 m of solid permanent cable plus up to 10 m of stranded patch cords.
- Shielding notation is
overall/per-pair: U/UTP, F/UTP, S/FTP; shields must be grounded at one end only or a ground loop makes things worse. - T568A and T568B must be used consistently at both ends; a split pair passes continuity tests while destroying crosstalk performance.
🧪 Practice
- An installer has 65 m of Cat6 in the walls plus 8 m of patch cords. Can this channel carry 10GBASE-T? What about 1000BASE-T?
- Explain why Cat6a cable is noticeably thicker than Cat6, naming the specific impairment the extra diameter addresses.
- Interview-style: A shielded Cat6a run performs worse than the unshielded run beside it. Give the most likely cause. (Hint: think about what happens electrically when a shield is bonded to earth at both ends of a long cable.)
Coaxial Cable
Theory
Coaxial cable solves the interference problem with geometry rather than cancellation. A central conductor carries the signal; a dielectric insulator surrounds it; a conductive shield (braid, foil, or both) surrounds that; and a jacket protects the whole. The signal conductor and shield share the same axis — hence "co-axial".
The consequence of this geometry is that the electromagnetic field is entirely contained between the inner conductor and the shield. Almost nothing radiates out, and almost nothing gets in. This is fundamentally more robust than twisted pair's cancellation approach, and it is why coax supports far higher frequencies over far longer distances.
The property that defines a coax type is characteristic impedance, measured in ohms — determined by the conductor diameters and the dielectric, and independent of cable length. Impedance matters because of reflections: when a signal meets a junction where the impedance changes, part of it bounces back. Reflections cause return loss, standing waves, and — on the old shared-bus Ethernets — data corruption. Every element of a coax system (cable, connectors, terminators, equipment) must present the same impedance.
| Type | Impedance | Typical use |
|---|---|---|
| RG-6 | 75 Ω | Cable TV, satellite, DOCSIS broadband, CCTV |
| RG-59 | 75 Ω | Legacy CCTV, short video runs |
| RG-58 | 50 Ω | 10BASE2 "thinnet", radio, test equipment |
| RG-8 / RG-213 | 50 Ω | 10BASE5 "thicknet", amateur radio |
| Hardline / heliax | 50 or 75 Ω | Cellular tower feeds, broadcast |
The 50/75 Ω split is not arbitrary: 50 Ω is roughly the optimum for power handling in transmitters, while 75 Ω minimises attenuation for signal distribution — hence radio uses 50 and video uses 75.
Coax has historical importance in Ethernet. 10BASE5 ("thicknet", 1980s) used a rigid RG-8 bus up to 500 m, tapped with "vampire taps" that pierced the jacket. 10BASE2 ("thinnet") used flexible RG-58 up to 185 m with BNC T-connectors. Both were shared buses: every host tapped the same cable, every transmission reached everyone, and a single break or a single missing 50 Ω terminator at either end took down the entire segment. This fragility — an entire office down because someone knocked a T-connector loose — is exactly why structured star wiring with twisted pair replaced them, and it is the historical origin of the collision domain discussed later in this chapter.
Coax is far from dead. DOCSIS delivers gigabit broadband over cable-TV coax using OFDM and 4096-QAM, and hybrid fibre-coax plants remain the dominant residential access technology in many countries. Coax also survives in cellular tower feeds, test equipment, and CCTV.
Examples
Coaxial geometry: the field is trapped inside
jacket ------------------------------
shield ============================= <- braid and/or foil
dielectric /////////////////////// <- insulator, sets impedance
centre --------------------------- <- signal conductor
dielectric ///////////////////////
shield =============================
jacket ------------------------------
^ EM field exists ONLY between centre and shield
-> minimal radiation out, minimal interference in
The 10BASE2 bus, and why it was fragile:
[50 ohm term]--T---------T---------T---------T--[50 ohm term]
| | | |
host A host B host C host D
Break the cable ANYWHERE, or lose EITHER terminator, and reflections
corrupt the whole segment: all four hosts lose connectivity at once.
import math
def reflection_coefficient(z_source, z_load):
"""Fraction of signal AMPLITUDE reflected at an impedance mismatch."""
return (z_load - z_source) / (z_load + z_source)
def return_loss_db(gamma):
return -20 * math.log10(abs(gamma)) if gamma else float("inf")
cases = [
("Correctly terminated 50 ohm", 50, 50),
("50 ohm cable, 75 ohm load", 50, 75), # wrong cable type used
("Open circuit (missing term)", 50, 1e12), # the classic 10BASE2 failure
("Short circuit (crushed)", 50, 0.001),
]
for name, zs, zl in cases:
g = reflection_coefficient(zs, zl)
power_reflected = g ** 2
print(f"{name:<30} gamma={g:+.3f} {power_reflected*100:>5.1f}% power reflected "
f"return loss={return_loss_db(g):.1f} dB")
# Correctly terminated 50 ohm gamma=+0.000 0.0% power reflected return loss=inf dB
# 50 ohm cable, 75 ohm load gamma=+0.200 4.0% power reflected return loss=14.0 dB
# Open circuit (missing term) gamma=+1.000 100.0% power reflected return loss=0.0 dB
# Short circuit (crushed) gamma=-1.000 100.0% power reflected return loss=0.0 dB
# A missing terminator reflects EVERYTHING — which is why one loose
# connector killed an entire 10BASE2 segment.
Key takeaways
- Coax confines the electromagnetic field between an inner conductor and a coaxial shield, giving excellent interference immunity by geometry rather than cancellation.
- Characteristic impedance must match throughout the system; mismatches cause reflections measured as return loss.
- 50 Ω types (RG-58, RG-8) serve radio and legacy Ethernet; 75 Ω types (RG-6, RG-59) serve video and cable broadband.
- 10BASE5 (500 m) and 10BASE2 (185 m) were shared buses requiring 50 Ω terminators at both ends; any break or missing terminator took down the whole segment.
- That fragility drove the move to structured star wiring with twisted pair.
- Coax remains dominant in DOCSIS cable broadband, cellular tower feeds, and CCTV.
🧪 Practice
- Compute the reflected power percentage when a 75 Ω cable is terminated in 50 Ω. Would this be acceptable on a cable TV feed?
- Explain why 10BASE2 required terminators while 10BASE-T does not, referring to the topology of each.
- Interview-style: DOCSIS 3.1 delivers gigabit speeds over coax installed decades ago for analog television. What physical property of coax makes this possible? (Hint: consider the bandwidth of the medium versus the bandwidth the original application consumed.)
Single-Mode vs Multi-Mode Fiber
Theory
Optical fibre transmits information as pulses of light through a glass core, and it outperforms copper on every axis that matters for distance and rate: enormous bandwidth, very low attenuation, complete immunity to electromagnetic interference, no crosstalk, no ground loops, and no electrical conduction (so it cannot carry a lightning surge between buildings).
The physics is total internal reflection. A fibre has a core of glass surrounded by cladding of slightly lower refractive index. Light entering within a certain angle — the acceptance cone — strikes the core-cladding boundary at a shallow enough angle to reflect completely, bouncing along the fibre rather than escaping. The core and cladding are both glass; the difference in refractive index is small, typically under one percent.
The single most important distinction in fibre is core diameter, because it determines how many distinct paths light can take.
Multi-mode fibre (MMF) has a wide core — 50 µm or 62.5 µm — wide enough that light can propagate along many different paths, or modes. A ray bouncing steeply travels further than one going straight down the middle, so the two arrive at different times. A sharp input pulse therefore emerges spread out: this is modal dispersion, and it is the fundamental limit on multi-mode distance. Push the data rate up, and the spreading pulses overlap into intersymbol interference sooner. MMF uses cheap 850 nm VCSEL lasers and is the standard for short runs inside buildings and data centres.
Single-mode fibre (SMF) has a core of only 8–10 µm — comparable to the wavelength of the light itself — which permits exactly one propagation mode. With no modal dispersion, the distance limit jumps by orders of magnitude: tens to hundreds of kilometres versus hundreds of metres. The remaining limits are attenuation and chromatic dispersion (different wavelengths travelling at slightly different speeds), both manageable. SMF uses 1310 nm and 1550 nm lasers, which are more expensive but reach further because glass attenuates least at those wavelengths.
| Property | Multi-mode (MMF) | Single-mode (SMF) |
|---|---|---|
| Core diameter | 50 or 62.5 µm | 8–10 µm |
| Cladding | 125 µm | 125 µm |
| Modes | Many | One |
| Wavelength | 850 nm, 1300 nm | 1310 nm, 1550 nm |
| Light source | VCSEL (cheap) | DFB / Fabry-Pérot laser (costly) |
| Attenuation | ~3 dB/km @ 850 nm | ~0.35 dB/km @ 1310, ~0.20 @ 1550 |
| Typical reach at 10 Gb/s | 300–550 m | 10–80 km and beyond |
| Jacket colour convention | Aqua (OM3/OM4), lime (OM5), orange (OM1/2) | Yellow |
| Relative cost | Cheaper optics, dearer fibre per bit-km | Dearer optics, far cheaper per bit-km |
Multi-mode grades are standardised as OM categories, and the distances are worth knowing because they decide data-centre cabling choices:
| Grade | Core | 1 Gb/s | 10 Gb/s | 100 Gb/s |
|---|---|---|---|---|
| OM1 | 62.5 µm | 275 m | 33 m | — |
| OM2 | 50 µm | 550 m | 82 m | — |
| OM3 | 50 µm | 1000 m | 300 m | 70 m |
| OM4 | 50 µm | 1100 m | 400 m | 100 m |
| OM5 | 50 µm | 1100 m | 400 m | 150 m (with SWDM) |
Single-mode grades are OS1 (indoor, tight-buffered) and OS2 (outdoor, loose tube, lower loss).
A practical note that costs real money: you cannot mix them. Connecting a single-mode transceiver to multi-mode fibre, or vice versa, produces enormous loss or a non-functioning link. Colour conventions exist precisely to prevent this, and the mismatch is a very common field fault.
Examples
Why core diameter decides everything
MULTI-MODE (50 um core): many paths, many arrival times
____________________________________
\ /\ /\ /\ /\ / <- high-order mode: long path
\ / \ / \ / \ / \ /
--\/----\/----\/----\/----\/----- <- low-order mode: short path
____________________________________
input pulse: _|‾|_ output: _/‾‾‾\_ MODAL DISPERSION
spread out -> ISI at high rates
SINGLE-MODE (9 um core): one path only
____________________________________
------------------------------------ <- the ONLY mode that propagates
____________________________________
input pulse: _|‾|_ output: _|‾|_ shape preserved
Cross-section (both have 125 um cladding — the connectors are identical):
MMF SMF
+-----------+ +-----------+
| /////// | 125 um | . | 125 um
| /////// | cladding | . | cladding
+-----------+ +-----------+
^ 50 um core ^ 9 um core
# Does a fibre link close? Attenuation budget plus a dispersion sanity check.
FIBRE = {
"OM3 850nm": {"db_per_km": 3.0, "max_km": 0.3},
"OM4 850nm": {"db_per_km": 3.0, "max_km": 0.4},
"OS2 1310nm": {"db_per_km": 0.35, "max_km": 10.0},
"OS2 1550nm": {"db_per_km": 0.20, "max_km": 80.0},
}
def link_budget(fibre, km, connectors, tx_dbm, rx_sensitivity_dbm):
spec = FIBRE[fibre]
fibre_loss = spec["db_per_km"] * km
conn_loss = connectors * 0.5 # 0.5 dB per mated connector pair
rx = tx_dbm - fibre_loss - conn_loss
margin = rx - rx_sensitivity_dbm
reach_ok = km <= spec["max_km"] # dispersion limit, separate from loss
return rx, margin, reach_ok
for fibre, km in [("OM4 850nm", 0.35), ("OM4 850nm", 2.0),
("OS2 1310nm", 8.0), ("OS2 1550nm", 60.0)]:
rx, margin, ok = link_budget(fibre, km, 4, tx_dbm=-3, rx_sensitivity_dbm=-18)
verdict = "OK" if (margin > 3 and ok) else ("DISPERSION LIMIT" if not ok else "NO MARGIN")
print(f"{fibre:<12} {km:>5.2f} km: Rx={rx:>6.2f} dBm margin={margin:>5.2f} dB {verdict}")
# OM4 850nm 0.35 km: Rx= -6.05 dBm margin= 11.95 dB OK
# OM4 850nm 2.00 km: Rx=-11.00 dBm margin= 7.00 dB DISPERSION LIMIT
# ^ note: enough POWER arrives, but the pulses have smeared together.
# Loss budget alone is not sufficient to validate a multi-mode link.
# OS2 1310nm 8.00 km: Rx= -7.80 dBm margin= 10.20 dB OK
# OS2 1550nm 60.00 km: Rx=-17.00 dBm margin= 1.00 dB NO MARGIN
Key takeaways
- Fibre guides light by total internal reflection between a higher-index core and a lower-index cladding.
- Multi-mode (50/62.5 µm core) allows many light paths, causing modal dispersion that limits distance to hundreds of metres; it uses cheap 850 nm VCSELs.
- Single-mode (8–10 µm core) permits one mode, eliminating modal dispersion and reaching tens to hundreds of kilometres at 1310/1550 nm.
- Both use 125 µm cladding, so connectors look identical — mixing the two is a common and costly field error.
- OM3/OM4 reach 300/400 m at 10 Gb/s; OS2 reaches 10 km at 1310 nm and 80 km at 1550 nm.
- A multi-mode link can fail from dispersion even when the power budget closes comfortably.
- Fibre is immune to EMI and crosstalk and conducts no electricity, making it ideal between buildings.
🧪 Practice
- An OM3 run is 380 m carrying 10 Gb/s. Will it work? What are two ways to fix it?
- Compute the total attenuation of 25 km of OS2 at 1550 nm with 6 mated connector pairs and 3 splices at 0.1 dB each.
- Interview-style: A 2 km multi-mode link shows plenty of received optical power but a high bit error rate. What is happening? (Hint: there are two independent limits on a fibre link, and only one of them is about power.)
Optical Transceivers and Connectors
Theory
A fibre carries light, but a switch processes electrical signals. The transceiver (transmitter + receiver) is the component that converts between them, and modern networking made a decision with enormous practical consequences: rather than building optics into switch ports, make them pluggable modules. One switch chassis can then serve 300 m multi-mode links and 80 km single-mode links simply by fitting different modules, and a failed optic is a two-second swap rather than a chassis replacement.
The form factors follow a clear progression, each defined by the port size and lane structure rather than by any single vendor:
| Form factor | Speed | Lanes | Typical use |
|---|---|---|---|
| SFP | 1 Gb/s | 1 | Access switches, legacy uplinks |
| SFP+ | 10 Gb/s | 1 | Server and switch uplinks |
| SFP28 | 25 Gb/s | 1 | Modern server access |
| QSFP+ | 40 Gb/s | 4 × 10 | Aggregation |
| QSFP28 | 100 Gb/s | 4 × 25 | Spine/leaf data centre |
| QSFP56 / QSFP-DD | 200 / 400 Gb/s | 4 × 50 / 8 × 50 | High-density data centre |
| OSFP | 400/800 Gb/s | 8 | Modern high-end, better thermals |
The "Q" means quad: four parallel lanes in one module. This matters practically because a QSFP28 100 G port can often be broken out into four independent SFP28 25 G links with a splitter cable — a standard data-centre technique for connecting many servers to one switch port.
Connectors are the second half of the story:
| Connector | Description | Where used |
|---|---|---|
| LC | Small form factor, latching, duplex pairs | The modern default: SFP/SFP+/SFP28 |
| SC | Square, push-pull, larger | Older equipment, telecom, some PON |
| ST | Bayonet, round | Legacy multi-mode installations |
| MPO / MTP | Multi-fibre ribbon, 12 or 24 fibres | QSFP parallel optics, trunk cabling |
Two details separate people who have worked with fibre from people who have only read about it.
Polish type. The fibre end face is polished either UPC (Ultra Physical Contact, flat, blue housing) or APC (Angled Physical Contact, an 8° angle, green housing). The angle causes reflections to escape into the cladding rather than bounce back down the fibre, giving much better return loss — essential for PON and high-power single-mode systems. UPC and APC must never be mated: doing so leaves an air gap that wrecks both the loss and the connector end faces.
Contamination is the leading cause of fibre faults. A single dust particle on a 9 µm core blocks a substantial fraction of the light path. The industry maxim is "inspect before you connect" — every disconnection is an opportunity for contamination, and cleaning with proper tools solves a large share of reported fibre faults.
Finally, DOM/DDM (Digital Optical Monitoring) is one of the most useful diagnostic facilities in networking: the transceiver continuously reports its own transmit power, received power, temperature, bias current, and voltage. This turns "the link is flaky" into a measured number you can compare against the module's own thresholds, without any external test equipment.
Examples
Pluggable optics decouple the port from the distance
+--------------------------------------------+
| Switch ASIC (electrical, speed-agnostic) |
+---+--------+--------+--------+--------+-----+
| | | | |
[SFP+] [SFP+] [SFP+] [SFP+] [QSFP28] <- cages
| | | | |
SR LR ER DAC 4x25G breakout
300 m 10 km 40 km copper, to 4 servers
MMF SMF SMF 3 m
^ same port, radically different reach — the module decides
Connector end faces:
UPC (blue) APC (green, 8 degrees)
|| \\
||==== \\==== reflection exits into the
|| reflection bounces \\ cladding instead of returning
|| straight back \\ -> much better return loss
NEVER mate UPC to APC: air gap, huge loss, damaged ferrules
# DOM: the transceiver reports its own health. This is the first command
# to run on any suspected fibre problem.
$ ethtool -m enp5s0f0
# Identifier : 0x03 (SFP)
# Transceiver type : 10G Ethernet: 10G Base-LR
# Vendor name : FS
# Laser wavelength : 1310nm
# Length (SMF,km) : 10km
# Module temperature : 43.52 degrees C
# Laser output power : 0.5623 mW / -2.50 dBm
# Receiver signal average optical power : 0.0891 mW / -10.50 dBm
# Alarm/warning flags:
# Rx power low warning : Off
# Rx power low alarm : Off
#
# Interpretation: Rx -10.50 dBm against an LR sensitivity near -14 dBm
# leaves ~3.5 dB margin. Tight but functional; a dirty connector would
# push it under and produce exactly the "intermittent" symptom reported.
$ ethtool -m enp5s0f1 | grep -i 'Rx power'
# Receiver signal average optical power : 0.0000 mW / -inf dBm
# ^ no light at all: fibre broken, unplugged, TX dead, or Rx/Tx swapped
# Reading a transceiver part number tells you its capabilities.
def decode_optic(name: str) -> str:
reach = {"SR": "short reach, MMF, 850nm, ~300-400 m",
"LR": "long reach, SMF, 1310nm, 10 km",
"ER": "extended reach, SMF, 1550nm, 40 km",
"ZR": "very long reach, SMF, 1550nm, 80 km",
"CR": "direct-attach copper twinax, <= 7 m"}
form, _, kind = name.partition("-")
lanes = 4 if form.startswith("QSFP") else 1
return (f"{name:<14} form={form:<7} lanes={lanes} {reach.get(kind, 'unknown')}")
for optic in ["SFP+-SR", "SFP+-LR", "SFP+-ZR", "QSFP28-SR", "SFP28-CR"]:
print(decode_optic(optic))
# SFP+-SR form=SFP+ lanes=1 short reach, MMF, 850nm, ~300-400 m
# SFP+-LR form=SFP+ lanes=1 long reach, SMF, 1310nm, 10 km
# SFP+-ZR form=SFP+ lanes=1 very long reach, SMF, 1550nm, 80 km
# QSFP28-SR form=QSFP28 lanes=4 short reach, MMF, 850nm, ~300-400 m
# SFP28-CR form=SFP28 lanes=1 direct-attach copper twinax, <= 7 m
# Note CR: for in-rack links, DAC copper is cheaper and lower-power than optics.
Key takeaways
- Pluggable transceivers decouple switch ports from media and distance, so one chassis serves any mix of reaches.
- Form factor progression: SFP (1 G), SFP+ (10 G), SFP28 (25 G), QSFP28 (100 G, 4 lanes), QSFP-DD/OSFP (400 G+).
- "Q" means four parallel lanes, which enables breakout cables splitting one port into four.
- LC is the modern default connector; MPO/MTP carries 12 or 24 fibres for parallel optics.
- UPC (blue) and APC (green, 8° angle) polishes must never be mated; APC gives far better return loss.
- Contaminated end faces are the leading cause of fibre faults — inspect and clean before connecting.
- DOM/DDM reports Tx power, Rx power, temperature, and bias current, turning vague fibre complaints into measurements.
🧪 Practice
- You need 100 Gb/s between two switches 15 km apart. Which form factor and optic type, and which fibre grade?
ethtool -mreports Rx power of −19 dBm on a module whose sensitivity is −14 dBm. Diagnose the link and list three things to check.- Interview-style: Why do data centres often use direct-attach copper for in-rack links rather than optics? (Hint: consider cost, power draw per port, and latency for a 2 m run.)
Radio, Microwave, and Satellite Links
Theory
Wireless media replace a guided path with free space, trading installation cost and mobility for a far harsher and fundamentally shared channel. The physics differs from copper and fibre in three ways that shape every wireless protocol.
Signal strength falls off with the square of distance. In free space, transmitted power spreads over the surface of an expanding sphere, so received power scales as 1/d². The standard engineering formula is free-space path loss:
FSPL (dB) = 20 × log₁₀(d) + 20 × log₁₀(f) + 32.44
with d in kilometres and f in megahertz. The two consequences are that doubling distance costs 6 dB, and that doubling frequency also costs 6 dB — which is why 5 GHz Wi-Fi has visibly shorter range than 2.4 GHz for the same power, and why 60 GHz systems are effectively room-limited.
The medium is shared and unlicensed bands are crowded. Unlike a cable, nobody can be excluded. Every other transmitter on the frequency is interference, which is why wireless protocols need medium access control (Chapter 4) and adaptive modulation (covered earlier).
Propagation is not simply line-of-sight. Signals reflect, diffract around obstacles, scatter, and are absorbed — water absorbs 2.4 GHz strongly, which is why human bodies and foliage attenuate Wi-Fi. Multipath — the same signal arriving via several paths at different delays — causes fading that can be worse than distance loss, though MIMO systems exploit multipath rather than merely suffering it.
Frequency choice is the central design trade:
| Band | Range behaviour | Bandwidth available | Typical use |
|---|---|---|---|
| Sub-1 GHz | Long range, good penetration | Narrow | LoRa, Sigfox, 802.11ah, legacy cellular |
| 2.4 GHz | Good range, heavily congested | ~80 MHz usable | Wi-Fi, Bluetooth, Zigbee, microwaves |
| 5 GHz | Shorter range, much cleaner | ~500 MHz | Wi-Fi 5/6 |
| 6 GHz | Shorter still, very clean | 1200 MHz | Wi-Fi 6E/7 |
| 24–40 GHz (mmWave) | Tens to hundreds of metres, blocked by walls | Multiple GHz | 5G mmWave, fixed wireless |
| 60 GHz | Single room; oxygen absorption | ~14 GHz | WiGig, 802.11ad/ay |
Microwave point-to-point links use highly directional dish antennas to concentrate energy into a narrow beam, achieving tens of kilometres with gigabit capacity. They require genuine line of sight plus a clear Fresnel zone — an ellipsoidal region around the direct path that must stay roughly 60 percent unobstructed, meaning a building or tree near the path degrades the link even without blocking it. They are the standard tool for crossing a river, a valley, or a city block where fibre cannot be laid, and are widely used for cellular backhaul.
Satellite links are defined by orbital altitude, and the resulting propagation delay is what determines their usability for interactive traffic:
| Orbit | Altitude | One-way delay | RTT | Characteristics |
|---|---|---|---|---|
| GEO | 35,786 km | ~120 ms | ~500 ms+ | Fixed position in the sky, 3 satellites cover the globe, unusable for interactive work |
| MEO | 8,000–20,000 km | ~40–70 ms | ~150 ms | GPS, some broadband constellations |
| LEO | 500–2,000 km | ~2–7 ms | ~25–60 ms | Starlink and similar; needs hundreds of satellites and handover as they move |
The GEO round trip is pure physics — the signal must climb 35,786 km and descend again, twice — and no amount of engineering will reduce it. This is why the shift to LEO constellations was transformative: the same bandwidth at a twentieth of the latency, at the cost of needing thousands of satellites and constant handover.
Examples
import math
def fspl_db(distance_km, freq_mhz):
"""Free-space path loss. Doubling EITHER argument costs 6 dB."""
return 20*math.log10(distance_km) + 20*math.log10(freq_mhz) + 32.44
print("Distance doubling:")
for d in (0.01, 0.02, 0.04, 0.08):
print(f" {d*1000:>4.0f} m @ 2400 MHz: {fspl_db(d, 2400):>5.1f} dB loss")
# 10 m @ 2400 MHz: 60.0 dB loss
# 20 m @ 2400 MHz: 66.0 dB loss <- +6 dB per doubling
# 40 m @ 2400 MHz: 72.0 dB loss
# 80 m @ 2400 MHz: 78.0 dB loss
print("\nFrequency doubling at a fixed 20 m:")
for f in (2400, 5000, 6000, 60000):
print(f" {f:>5} MHz: {fspl_db(0.02, f):>5.1f} dB loss")
# 2400 MHz: 66.0 dB loss
# 5000 MHz: 72.4 dB loss <- 5 GHz starts 6.4 dB down on 2.4 GHz
# 6000 MHz: 74.0 dB loss
# 60000 MHz: 94.0 dB loss <- 28 dB worse: mmWave is inherently short-range
# Satellite latency is set by orbital altitude and the speed of light.
C_KM_PER_MS = 299.792
for name, alt in [("GEO", 35786), ("MEO", 10000), ("LEO (Starlink)", 550)]:
one_way = alt / C_KM_PER_MS # ground -> satellite
rtt = 4 * one_way # up, down, and back again
print(f"{name:<16} {alt:>6} km: minimum RTT = {rtt:>6.1f} ms")
# GEO 35786 km: minimum RTT = 477.5 ms
# MEO 10000 km: minimum RTT = 133.4 ms
# LEO (Starlink) 550 km: minimum RTT = 7.3 ms
# Real LEO RTT is 25-60 ms once ground routing and processing are added.
# Fresnel zone clearance for a microwave link:
def fresnel_radius_m(dist_km, freq_ghz):
"""Radius at the midpoint; 60% of this must be obstacle-free."""
return 8.657 * math.sqrt(dist_km / freq_ghz)
for d in (1, 5, 20):
r = fresnel_radius_m(d, 6)
print(f"{d:>2} km @ 6 GHz: Fresnel radius {r:>5.2f} m, "
f"need {0.6*r:.2f} m clear of obstacles at midpoint")
# 1 km @ 6 GHz: Fresnel radius 3.53 m, need 2.12 m clear of obstacles at midpoint
# 5 km @ 6 GHz: Fresnel radius 7.90 m, need 4.74 m clear of obstacles at midpoint
# 20 km @ 6 GHz: Fresnel radius 15.81 m, need 9.48 m clear of obstacles at midpoint
# A treeline that does NOT block the direct line can still break the link.
Key takeaways
- Free-space path loss grows with the square of both distance and frequency: doubling either costs 6 dB.
- Higher frequencies offer more bandwidth but shorter range and worse obstacle penetration — the core wireless trade-off.
- The wireless medium is inherently shared and cannot exclude other transmitters, which is why MAC protocols and adaptive modulation are mandatory.
- Multipath causes fading; MIMO turns it into an advantage by using paths as independent channels.
- Microwave point-to-point links need line of sight plus about 60 percent Fresnel zone clearance — nearby obstacles degrade the link without blocking it.
- Satellite latency follows from altitude: GEO about 500 ms RTT, MEO about 150 ms, LEO about 25–60 ms.
- GEO's delay is irreducible physics, which is why LEO constellations changed satellite broadband fundamentally.
🧪 Practice
- Compute FSPL for a 2 km link at 5.8 GHz. If the transmitter outputs 20 dBm and antennas give 20 dBi gain each, what is the received power?
- Explain why 2.4 GHz Wi-Fi penetrates walls better than 5 GHz, and why 5 GHz is still usually preferred indoors.
- Interview-style: A user on GEO satellite broadband has 25 Mb/s but their video calls are unusable. Explain, and say whether more bandwidth would help. (Hint: separate the two performance metrics from Chapter 1 and identify which one orbital altitude fixes.)
Structured Cabling and Cable Standards
Theory
Everything so far has been about individual links. Structured cabling is about the building: a vendor-neutral, standards-based hierarchy that lets any device plug in anywhere and be reconfigured without pulling new cable. The alternative — running a dedicated cable from each device to wherever it needs to go — produces an unmaintainable tangle where nobody knows which cable serves what, and every move requires new construction.
The governing standard is ANSI/TIA-568 in North America, with ISO/IEC 11801 as the international equivalent. They define a hierarchy of named subsystems:
| Subsystem | What it is | Typical medium |
|---|---|---|
| Entrance facility | Where external circuits enter the building | Provider-dependent |
| Equipment room | Main cross-connect, core switches, servers | — |
| Backbone cabling | Vertical runs between floors and buildings | Single-mode or multi-mode fibre |
| Telecommunications room | Per-floor distribution (IDF), patch panels, access switches | — |
| Horizontal cabling | The floor-level run from the room to each outlet | Cat6/6a twisted pair |
| Work area | The outlet, faceplate, and the patch cord to the device | Stranded patch cord |
The distance rules are the part most often tested and most often violated:
- Horizontal cabling: 90 m maximum of solid-core permanent link, plus up to 10 m total of patch cords, for a 100 m channel maximum.
- Backbone distances depend on medium — 2 km or more for single-mode fibre, far less for copper.
- Each floor should have its own telecommunications room, because the 90 m horizontal limit constrains how much area one room can serve.
The design principle is the permanent link versus channel distinction. The permanent link is the fixed cable in the walls, terminated at a patch panel on one end and a wall outlet on the other. It is installed once and tested once. The channel is the permanent link plus the patch cords, and it is what the equipment actually sees. Moves and changes happen entirely by re-patching — no construction.
Several practical requirements complete the picture:
- Labelling is mandated by TIA-606, and is not bureaucratic overhead. An unlabelled patch panel makes every future change a trace-and-guess exercise.
- Bend radius limits apply to both copper and fibre. Exceeding them changes a twisted pair's impedance (causing return loss) and can cause macrobending loss or permanent damage in fibre. The usual rule is four times the cable diameter for unshielded copper, ten times for fibre.
- Plenum versus riser jacket rating is a fire-safety requirement. Cable run through air-handling spaces must be plenum-rated (CMP) because ordinary PVC jackets emit toxic smoke when burning. This is a legal requirement in most jurisdictions, not a preference.
- Separation from power cabling limits induced 50/60 Hz interference; standards specify minimum separation distances and require crossings at right angles.
Related standards worth recognising: TIA-569 (pathways and spaces), TIA-607 (bonding and grounding), and TIA-942 (data centre infrastructure, which defines the well-known Tier I–IV availability classification).
Examples
The TIA-568 hierarchy in one building
[ Entrance facility ] <- ISP circuits arrive
|
[ Equipment room / MDF ] core switches, servers, main cross-connect
|
backbone cabling (fibre, vertical between floors)
|
+--------+--------+--------+
| | | |
[TR-1] [TR-2] [TR-3] [TR-4] telecommunications room per floor (IDF)
| patch panels + access switches
| horizontal cabling: max 90 m solid-core, star topology
+----+----+----+----+
| | | |
outlets in the work areas
|
patch cord (max 5 m) -> the device
The 100 m channel budget:
[switch]--5m--[patch panel]========90m========[outlet]--5m--[PC]
^ stranded ^ solid core ^ stranded
\________________ channel = 100 m max ______________/
^ permanent link = 90 m, tested once
# Validate a channel against TIA-568 before anyone pulls cable.
def validate_channel(permanent_link_m, patch_cords_m, category, speed_gbps):
channel = permanent_link_m + sum(patch_cords_m)
issues = []
if permanent_link_m > 90:
issues.append(f"permanent link {permanent_link_m} m exceeds 90 m")
if sum(patch_cords_m) > 10:
issues.append(f"patch cords total {sum(patch_cords_m)} m exceeds 10 m")
if channel > 100:
issues.append(f"channel {channel} m exceeds 100 m")
# Category capability is a separate check from the length rules.
limits = {"Cat5e": {1: 100, 10: 0}, "Cat6": {1: 100, 10: 55},
"Cat6a": {1: 100, 10: 100}}
cat_limit = limits[category].get(speed_gbps, 0)
if channel > cat_limit:
issues.append(f"{category} supports {speed_gbps} Gb/s only to {cat_limit} m")
return (not issues), channel, issues
designs = [
("Standard office run", 88, [3, 5], "Cat6a", 10),
("Overlong permanent", 95, [3, 5], "Cat6a", 10),
("Cat6 at 10G, too far", 70, [3, 5], "Cat6", 10),
("Cat6 at 10G, short", 45, [3, 5], "Cat6", 10),
]
for name, pl, cords, cat, speed in designs:
ok, channel, issues = validate_channel(pl, cords, cat, speed)
print(f"{name:<24} channel={channel:>3} m {'PASS' if ok else 'FAIL'}")
for i in issues:
print(f" - {i}")
# Standard office run channel= 96 m PASS
# Overlong permanent channel=103 m FAIL
# - permanent link 95 m exceeds 90 m
# - channel 103 m exceeds 100 m
# - Cat6a supports 10 Gb/s only to 100 m
# Cat6 at 10G, too far channel= 78 m FAIL
# - Cat6 supports 10 Gb/s only to 55 m
# Cat6 at 10G, short channel= 53 m PASS
Key takeaways
- Structured cabling (ANSI/TIA-568, ISO/IEC 11801) defines a vendor-neutral hierarchy: entrance facility, equipment room, backbone, telecommunications room, horizontal cabling, work area.
- Horizontal cabling is limited to 90 m permanent link plus 10 m of patch cords for a 100 m channel.
- The permanent link is fixed and tested once; the channel includes patch cords and is what equipment sees — moves happen by re-patching, not re-cabling.
- Backbone cabling between floors and buildings is normally fibre, both for distance and for electrical isolation.
- TIA-606 labelling, bend-radius limits, plenum-rated (CMP) jackets in air-handling spaces, and separation from power cabling are mandatory practical requirements.
- Related standards: TIA-569 (pathways), TIA-607 (grounding), TIA-942 (data centres and the Tier classification).
🧪 Practice
- A permanent link measures 94 m. State the problem and two acceptable remedies.
- Explain why backbone cabling between floors is normally fibre rather than copper, giving at least three independent reasons.
- Interview-style: Why does the standard separate "permanent link" from "channel" testing? (Hint: consider who installs each part, when each is tested, and which one changes over the building's life.)
<a id="34-multiplexing-and-link-sharing"></a>
3.4 Multiplexing and Link Sharing
A single medium is expensive to install and usually far faster than any one conversation needs; this subchapter covers the four dimensions along which a medium can be divided among many simultaneous users, and the directionality choices that follow.
Frequency Division Multiplexing
Theory
Laying a cable or acquiring spectrum is expensive; the capacity of that medium usually far exceeds what any single conversation requires. Multiplexing is the general technique for carrying many independent signals over one physical medium, and there are only a few dimensions along which to divide it: frequency, time, wavelength, and code. This topic covers the first.
FDM (Frequency Division Multiplexing) divides the medium's available bandwidth into non-overlapping frequency bands and assigns each user a permanent band. Every signal is modulated onto a different carrier frequency, all are summed onto the medium simultaneously, and the receiver uses a bandpass filter to isolate the desired band and demodulate it.
The analogy is broadcast radio, which is literally FDM: many stations transmit at once in the same air, and your tuner selects a frequency. Nothing is taking turns — everyone transmits continuously, forever, in their own slice of spectrum.
The critical engineering detail is the guard band: a deliberately unused strip of spectrum between adjacent channels. Real filters cannot cut off perfectly sharply, and real transmitters leak energy outside their nominal band. Without guard bands, adjacent channels bleed into each other, producing adjacent channel interference. Guard bands are pure overhead — capacity you pay for and never use — and their width is the price of practical filters.
FDM's defining properties:
- Simultaneous, continuous transmission. No user waits for a turn, so there is no scheduling latency.
- Fixed allocation. A user's band is theirs whether they use it or not. If a channel is idle, its capacity is simply wasted — the same inefficiency circuit switching has, for the same reason.
- Analog in origin. FDM predates digital networking by decades and was how telephone carriers stacked thousands of voice calls onto a single coaxial trunk.
Where FDM appears today: broadcast radio and television, cable TV (each channel a 6 or 8 MHz slot on the coax), ADSL (which splits the phone line into a voice band plus hundreds of upstream and downstream carriers), Wi-Fi channel plans, and cellular band allocation. Its modern refinement is OFDM (Orthogonal Frequency Division Multiplexing), which packs subcarriers so that each one's spectral peak falls exactly on its neighbours' nulls — orthogonal rather than merely separated — allowing them to overlap without interfering and eliminating most guard-band waste. OFDM underpins Wi-Fi, LTE, 5G, DVB, and DSL.
When FDM shares a medium among users who must also access it dynamically, it is called FDMA (Frequency Division Multiple Access), the term used in cellular contexts.
Examples
FDM: everyone transmits at once, in their own band
power
^
| ___ ___ ___ ___
| / \ / \ / \ / \
|/ A \ / B \ / C \ / D \
+---------------------------------------> frequency
| |gb| |gb| |gb| |
ch 1 ch 2 ch 3 ch 4
^ guard bands: wasted spectrum, but filters are imperfect
OFDM: subcarriers OVERLAP but are orthogonal — peaks sit on neighbours' nulls
| /\ /\ /\ /\ /\ /\
| / \/ \/ \/ \/ \/ \
+---------------------------> frequency
^ each peak aligns with every other subcarrier's zero crossing
-> no interference despite overlap, and almost no wasted spectrum
# Capacity accounting for FDM, including the guard-band tax.
def fdm_plan(total_bandwidth_hz, channel_hz, guard_hz):
per_slot = channel_hz + guard_hz
n_channels = int(total_bandwidth_hz // per_slot)
used = n_channels * channel_hz
wasted = total_bandwidth_hz - used
return n_channels, used, wasted
plans = [
("Cable TV (6 MHz channels)", 750e6, 6e6, 0.25e6),
("Wi-Fi 2.4 GHz (20 MHz)", 80e6, 20e6, 2e6),
("Narrow channels, big guards",100e6, 5e6, 5e6),
]
for name, total, ch, guard in plans:
n, used, wasted = fdm_plan(total, ch, guard)
print(f"{name:<30} {n:>3} channels "
f"efficiency {used/total:>5.1%} wasted {wasted/1e6:>6.2f} MHz")
# Cable TV (6 MHz channels) 120 channels efficiency 96.0% wasted 30.00 MHz
# Wi-Fi 2.4 GHz (20 MHz) 3 channels efficiency 75.0% wasted 20.00 MHz
# Narrow channels, big guards 10 channels efficiency 50.0% wasted 50.00 MHz
# The guard-band tax grows as channels get narrower relative to the guard.
# The idle-channel problem: fixed allocation wastes whatever is not used.
utilisation = [1.0, 0.1, 0.0, 0.6] # how busy each of 4 channels is
print(f"allocated: 100% of the medium; actually carrying data: "
f"{sum(utilisation)/len(utilisation):.0%}")
# allocated: 100% of the medium; actually carrying data: 43%
# An idle FDM channel cannot be lent to a busy neighbour — that is TDM's advantage.
Key takeaways
- FDM divides a medium's bandwidth into non-overlapping frequency bands, one per user, all transmitting simultaneously and continuously.
- Guard bands between channels prevent adjacent-channel interference but are permanently wasted capacity.
- Allocation is fixed: an idle channel's capacity cannot be reused by a busy one.
- FDM requires no scheduling and introduces no access delay, which suits continuous streams such as broadcast.
- OFDM makes subcarriers orthogonal so they can overlap without interfering, nearly eliminating guard-band waste; it underpins Wi-Fi, LTE, 5G, and DSL.
- In cellular and shared-access contexts the same scheme is called FDMA.
🧪 Practice
- A 100 MHz medium is divided into 12 MHz channels with 1 MHz guard bands. How many channels fit, and what percentage of the spectrum is wasted?
- Explain why the 2.4 GHz Wi-Fi band has only three non-overlapping 20 MHz channels despite appearing to offer 11 or more numbered channels.
- Interview-style: FDM gives every user a dedicated band with no waiting. Why did packet-switched networks abandon it for data? (Hint: recall the burstiness argument from Chapter 1 and what happens to an idle dedicated channel.)
Time Division Multiplexing
Theory
FDM divides the medium in frequency; TDM (Time Division Multiplexing) divides it in time. Each user gets the entire bandwidth of the medium, but only during their assigned time slot. Slots repeat in a frame, and the cycle continues indefinitely.
The analogy is a meeting where everyone speaks in turn on a strict rota. Each speaker has the room's full attention — but only for their allotted seconds, and they must wait for the rota to come around again.
TDM comes in two fundamentally different varieties, and the distinction is the most important idea in this topic.
Synchronous TDM assigns each user a fixed slot in every frame, permanently. Slot 3 belongs to user 3 whether or not user 3 has anything to send. If they do not, the slot is transmitted empty — the capacity is lost. This is simple, gives perfectly predictable latency and jitter, and requires no addressing at all, because position in the frame is the identity. It is the basis of the entire traditional telephone network:
| System | Rate | Channels | Per channel |
|---|---|---|---|
| DS0 | 64 kb/s | 1 | One digitised voice call (8000 samples/s × 8 bits) |
| T1 | 1.544 Mb/s | 24 DS0 | North America and Japan |
| E1 | 2.048 Mb/s | 32 slots (30 usable) | Europe and most of the world |
| T3 | 44.736 Mb/s | 28 T1 | — |
| SONET OC-3 / SDH STM-1 | 155.52 Mb/s | — | Optical backbone |
Statistical TDM (also called asynchronous TDM) fixes synchronous TDM's waste by allocating slots on demand: only users with data to send get slots. Since slot position no longer identifies the sender, each unit must now carry an address — and with that addition, statistical TDM is packet switching. The gain is large, because users are bursty: as computed in Chapter 1, a link can support far more users than its raw capacity divided by peak rate, precisely because they are rarely all active at once. The cost is variable delay and the possibility of congestion when too many users transmit simultaneously.
| Synchronous TDM | Statistical TDM | |
|---|---|---|
| Slot assignment | Fixed, pre-allocated | On demand |
| Idle user | Slot transmitted empty | Slot given to someone else |
| Addressing | Implicit (slot position) | Explicit (header) |
| Delay | Constant, predictable | Variable |
| Congestion possible | No | Yes |
| Efficiency with bursty traffic | Poor | Excellent |
| Example | T1/E1, SONET | Ethernet, IP, all packet networks |
The historical arc is worth noting: the telephone network was built on synchronous TDM because voice is a constant-rate stream, and the entire migration to packet-based networks is the replacement of synchronous with statistical TDM — the same physical-layer argument as circuit versus packet switching in Chapter 1, one layer down.
Examples
Synchronous TDM: fixed slots, empty when unused
frame 1 frame 2 frame 3
+---+---+---+---+ +---+---+---+---+ +---+---+---+---+
| A | B | | D | | A | | | D | | A | B | C | D |
+---+---+---+---+ +---+---+---+---+ +---+---+---+---+
1 2 3 4 1 2 3 4 1 2 3 4
^ C idle: slot transmitted EMPTY, capacity lost forever
No address needed — being in slot 3 means "you are C".
Statistical TDM: slots go to whoever has data
+---+---+---+---+ +---+---+---+---+
|A:1|B:2|A:3|D:4| |A:5|D:6|A:7|A:8| A is busy, so A gets more slots
+---+---+---+---+ +---+---+---+---+
^ each unit now carries an ADDRESS, because position means nothing.
This is exactly what a packet header is.
T1 frame structure (synchronous TDM in the real world):
|F| ch1 | ch2 | ch3 | ... | ch24 | = 1 + 24*8 = 193 bits
^framing bit ^ 8 bits per channel
8000 frames/s x 193 bits = 1.544 Mb/s exactly
# Deriving T1 and E1 from first principles.
SAMPLE_RATE = 8000 # Nyquist: 2 x 4 kHz voice bandwidth
BITS_PER_SAMPLE = 8 # G.711 PCM
ds0 = SAMPLE_RATE * BITS_PER_SAMPLE
print(f"DS0 (one voice channel) = {ds0:,} b/s") # 64,000 b/s
t1_bits_per_frame = 24 * BITS_PER_SAMPLE + 1 # +1 framing bit
t1 = t1_bits_per_frame * SAMPLE_RATE
print(f"T1 = ({24} x 8 + 1) x 8000 = {t1:,} b/s") # 1,544,000 b/s
e1 = 32 * BITS_PER_SAMPLE * SAMPLE_RATE # 32 slots, no extra bit
print(f"E1 = 32 x 8 x 8000 = {e1:,} b/s "
f"({30} usable voice channels + signalling + framing)") # 2,048,000 b/s
# Synchronous vs statistical efficiency with bursty users:
def efficiency(activity_factors, statistical: bool):
if statistical:
# Capacity flows to whoever needs it; only aggregate demand matters.
return min(1.0, sum(activity_factors))
# Fixed slots: each user's share is wasted in proportion to their idleness.
return sum(activity_factors) / len(activity_factors)
users = [0.9, 0.05, 0.0, 0.3, 0.1, 0.0, 0.0, 0.6] # typical bursty data users
print(f"synchronous TDM utilisation : {efficiency(users, False):.1%}")
print(f"statistical TDM utilisation : {efficiency(users, True):.1%}")
# synchronous TDM utilisation : 24.4%
# statistical TDM utilisation : 100.0%
# Same users, same link — the difference is purely how slots are assigned.
Key takeaways
- TDM gives each user the medium's full bandwidth during an assigned time slot, with slots repeating in frames.
- Synchronous TDM pre-allocates fixed slots; idle users' slots go out empty, wasting capacity, but delay is constant and no addressing is needed.
- Statistical TDM allocates slots on demand and therefore requires explicit addressing — which makes it identical in principle to packet switching.
- T1 = 24 × 64 kb/s + framing = 1.544 Mb/s; E1 = 32 × 64 kb/s = 2.048 Mb/s; DS0 = 64 kb/s from 8000 samples/s × 8 bits.
- Statistical TDM vastly outperforms synchronous TDM for bursty data but introduces variable delay and the possibility of congestion.
- The telephone-to-Internet transition is, at this layer, the replacement of synchronous TDM by statistical TDM.
🧪 Practice
- Derive the T1 line rate from first principles, explaining each factor including the framing bit.
- Four users have activity factors 0.8, 0.1, 0.0, and 0.2 on a 10 Mb/s link. Compute the throughput each would achieve under synchronous and statistical TDM.
- Interview-style: Statistical TDM requires addressing while synchronous TDM does not. Explain why, and name the cost this addressing imposes. (Hint: in synchronous TDM, what identifies the sender of a given byte?)
Wavelength Division Multiplexing
Theory
WDM (Wavelength Division Multiplexing) is FDM applied to optical fibre — the frequencies are just so high that it is conventional to speak of wavelength instead. Multiple lasers, each at a slightly different colour, inject light into the same fibre simultaneously; each colour carries an independent data stream; a prism-like device at the far end separates them again.
Why it matters is economics. The expensive, slow, disruptive part of optical networking is putting fibre in the ground — trenching a city street or laying a submarine cable costs enormously more than the equipment at either end. WDM multiplies the capacity of fibre already installed by a factor of 40, 80, or more, purely by changing the endpoint equipment. A fibre buried in 1995 can carry hundreds of times more traffic today than when it was laid, with no digging.
The components are worth naming: a multiplexer combines wavelengths onto one fibre, a demultiplexer separates them, and — crucially — an EDFA (Erbium-Doped Fibre Amplifier) boosts all wavelengths at once, optically, without converting to electrical signals. Before EDFAs, every wavelength needed its own regenerator; the EDFA is what made high-channel-count WDM economically viable.
Two grades exist, and the distinction is about channel spacing:
| CWDM (Coarse) | DWDM (Dense) | |
|---|---|---|
| Channel spacing | 20 nm | 0.8 nm (100 GHz) or 0.4 nm (50 GHz) |
| Channels | Up to 18 | 40, 80, 96, or more |
| Wavelength range | 1270–1610 nm | Mostly C-band, 1530–1565 nm |
| Laser requirement | Uncooled, wide tolerance | Temperature-stabilised, precise |
| Amplification | Generally none | EDFA amplifies the whole C-band |
| Cost | Low | High |
| Typical use | Metro, enterprise, access | Long-haul, submarine, core |
The reason DWDM concentrates on the C-band (1530–1565 nm) is that this is where silica fibre has its lowest attenuation, roughly 0.2 dB/km, and where erbium amplifiers happen to work. That coincidence of physics and chemistry is why the world's backbone runs on those particular wavelengths.
Modern systems layer additional techniques on top: coherent detection with advanced modulation (16-QAM, 64-QAM per wavelength, plus polarisation multiplexing) pushes each channel to 400 Gb/s or 800 Gb/s, so a single fibre pair can carry tens of terabits per second. ROADMs (Reconfigurable Optical Add-Drop Multiplexers) let an operator route individual wavelengths at a site without converting them to electrical signals — switching at the optical layer.
For everyday networking there is also a small-scale relative: BiDi (bidirectional) optics use two wavelengths — typically 1310 nm one way and 1550 nm the other — to run a full-duplex link over a single strand of fibre rather than the usual pair. This halves fibre consumption and is common where fibre count is constrained.
Examples
WDM: one fibre, many colours, each an independent link
[ Tx 1550.12 nm ]---\ /---[ Rx ]
[ Tx 1550.92 nm ]----\ one single-mode fibre /----[ Rx ]
[ Tx 1551.72 nm ]-----[MUX]=========================[DEMUX]----[ Rx ]
[ Tx 1552.52 nm ]----/ | \----[ Rx ]
... / [ EDFA ] \ ...
^ amplifies ALL wavelengths at once,
optically, with no per-channel hardware
Spectrum view (DWDM, 100 GHz spacing in the C-band):
power
^ | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | |
+--+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+---> wavelength
1530 nm <------ C-band, ~35 nm wide ------> 1565 nm
80 channels x 400 Gb/s = 32 Tb/s on ONE fibre pair
C_LIGHT = 299_792_458 # m/s
def nm_to_ghz_spacing(centre_nm, spacing_nm):
"""Convert wavelength spacing to frequency spacing (the ITU grid uses GHz)."""
f1 = C_LIGHT / (centre_nm * 1e-9)
f2 = C_LIGHT / ((centre_nm + spacing_nm) * 1e-9)
return abs(f1 - f2) / 1e9
for label, spacing in [("DWDM 0.8 nm", 0.8), ("DWDM 0.4 nm", 0.4), ("CWDM 20 nm", 20)]:
print(f"{label:<12} @1550 nm = {nm_to_ghz_spacing(1550, spacing):>8.1f} GHz spacing")
# DWDM 0.8 nm @1550 nm = 99.8 GHz spacing <- the classic 100 GHz ITU grid
# DWDM 0.4 nm @1550 nm = 49.9 GHz spacing <- 50 GHz grid, twice the channels
# CWDM 20 nm @1550 nm = 2464.1 GHz spacing <- huge gaps; cheap, sloppy lasers OK
def fibre_capacity(channels, gbps_per_channel, fibre_pairs=1):
return channels * gbps_per_channel * fibre_pairs / 1000 # Tb/s
systems = [
("Single channel 10G", 1, 10),
("CWDM 8ch x 10G", 8, 10),
("DWDM 40ch x 100G", 40, 100),
("Modern DWDM 96ch x 800G", 96, 800),
]
for name, ch, rate in systems:
print(f"{name:<26} {fibre_capacity(ch, rate):>8.2f} Tb/s on one fibre pair")
# Single channel 10G 0.01 Tb/s on one fibre pair
# CWDM 8ch x 10G 0.08 Tb/s on one fibre pair
# DWDM 40ch x 100G 4.00 Tb/s on one fibre pair
# Modern DWDM 96ch x 800G 76.80 Tb/s on one fibre pair
# The GLASS never changed. Only the equipment at the ends did.
Key takeaways
- WDM is FDM for fibre: multiple wavelengths carry independent streams simultaneously through one strand.
- Its value is economic — it multiplies the capacity of already-buried fibre without new trenching.
- CWDM uses 20 nm spacing, up to 18 channels, cheap uncooled lasers, and no amplification; DWDM uses 0.8 or 0.4 nm spacing, 40–96+ channels, and requires precise temperature-stabilised lasers.
- DWDM concentrates on the C-band (1530–1565 nm) because silica attenuation is lowest there and EDFAs amplify there.
- EDFAs amplify all wavelengths at once in the optical domain, which is what made dense WDM economic.
- Modern coherent DWDM systems reach tens of terabits per second per fibre pair.
- BiDi optics use two wavelengths to achieve full duplex over a single strand instead of a pair.
🧪 Practice
- A DWDM system carries 80 channels at 200 Gb/s each. What is the total capacity of one fibre pair? How many 10 Gb/s links would that replace?
- Explain why CWDM lasers can be uncooled while DWDM lasers must be temperature-stabilised, referring to channel spacing.
- Interview-style: An operator needs to double capacity on a congested submarine cable. Compare laying a second cable with upgrading the WDM terminals. (Hint: identify which component of the total cost is dominated by physical construction.)
Code Division Multiple Access
Theory
FDM divides the medium by frequency, TDM by time. CDMA (Code Division Multiple Access) does something that sounds impossible: every user transmits at the same time, on the same frequency, and the receiver still separates them cleanly. The separating dimension is a mathematical one — an assigned code.
The cocktail-party analogy is unusually apt. In a crowded room, many people speak simultaneously in the same air at the same pitch, yet you can follow one conversation. You do it by locking onto the distinguishing characteristics of one voice — a language, a timbre — and treating everything else as background noise. CDMA gives each transmitter a distinct "language" in the form of a code sequence.
The mechanism is direct-sequence spread spectrum:
- Each user is assigned a unique chipping code — a rapid sequence of ±1 values, much faster than the data rate. The ratio of chip rate to bit rate is the spreading factor.
- To transmit a bit, the sender multiplies it by its entire code, producing a fast, wideband, noise-like signal. A 1 sends the code; a 0 sends the code inverted.
- All users' signals add together in the air. The composite looks like noise.
- To recover user A's data, the receiver multiplies the composite by A's code and sums over one bit period — an operation called correlation.
The reason this works is orthogonality. If the codes are chosen so that the dot product of any two different codes is zero, then when the receiver correlates with A's code, A's contribution accumulates to full strength while every other user's contribution sums to exactly zero. Walsh–Hadamard codes are the standard construction for perfectly orthogonal sets.
CDMA has properties no other multiplexing scheme offers:
- Soft capacity. Adding a user does not consume a fixed slot; it raises the noise floor slightly for everyone. The system degrades gracefully rather than refusing admission at a hard limit.
- Interference resistance. Spreading a signal across a wide band means narrowband interference damages only a small fraction of the chips, and the correlation process suppresses it. This is why spread spectrum originated in military anti-jamming work.
- Low power spectral density. The signal is spread so thin that it can sit below the noise floor — hard to detect, and able to coexist with other systems. GPS works this way, which is why satellite signals reach you at power levels far below ambient noise.
- Inherent security. Without the code, the signal is indistinguishable from noise.
The chief practical difficulty is the near-far problem: a transmitter close to the receiver overwhelms a distant one, because orthogonality only cancels signals of comparable strength. CDMA systems therefore need fast, precise power control — cdmaOne and CDMA2000 adjust handset power up to 800 times per second.
CDMA was the basis of the IS-95/CDMA2000 cellular family and of UMTS/WCDMA in 3G. Modern 4G and 5G moved to OFDMA (an OFDM-based scheme) for better spectral efficiency and simpler scheduling, but CDMA principles remain central to GPS, to military communications, and to the spreading used in some IoT radios.
Examples
Two users, same time, same frequency, separated by code
Walsh codes (orthogonal by construction):
A = (+1, +1, +1, +1)
B = (+1, -1, +1, -1)
A . B = 1 - 1 + 1 - 1 = 0 <- orthogonal: this is the whole trick
A sends bit 1 -> transmits (+1, +1, +1, +1)
B sends bit 0 -> transmits (-1, +1, -1, +1) (B's code, inverted)
In the air, the signals simply ADD:
composite = ( 0, +2, 0, +2) <- looks like meaningless noise
Receiver correlates with A's code:
(0)(+1) + (+2)(+1) + (0)(+1) + (+2)(+1) = +4 -> /4 = +1 -> bit 1 CORRECT
Receiver correlates with B's code:
(0)(+1) + (+2)(-1) + (0)(+1) + (+2)(-1) = -4 -> /4 = -1 -> bit 0 CORRECT
Both recovered perfectly from the SAME composite signal.
import numpy as np
def walsh(n):
"""Generate a 2^n x 2^n Hadamard matrix: mutually orthogonal codes."""
h = np.array([[1]])
for _ in range(n):
h = np.block([[h, h], [h, -h]]) # recursive Hadamard construction
return h
codes = walsh(3) # 8 orthogonal codes of length 8
users = {"A": codes[1], "B": codes[2], "C": codes[3], "D": codes[5]}
# Verify orthogonality: every distinct pair must have a dot product of zero.
names = list(users)
for i, n1 in enumerate(names):
for n2 in names[i+1:]:
assert np.dot(users[n1], users[n2]) == 0
print("all code pairs verified orthogonal")
def transmit(data_bits: dict) -> np.ndarray:
"""All users transmit simultaneously; the channel sums their signals."""
composite = np.zeros(len(codes[0]))
for user, bit in data_bits.items():
symbol = 1 if bit else -1 # 1 -> code, 0 -> inverted code
composite += symbol * users[user]
return composite
def receive(composite: np.ndarray, user: str) -> int:
"""Correlate with this user's code; other users sum to exactly zero."""
correlation = np.dot(composite, users[user]) / len(users[user])
return 1 if correlation > 0 else 0
sent = {"A": 1, "B": 0, "C": 1, "D": 1}
air = transmit(sent)
print("composite signal on the air:", air)
# composite signal on the air: [ 2. -2. 2. 2. 2. 2. -2. -2.] <- noise-like
recovered = {u: receive(air, u) for u in users}
print("sent :", sent)
print("recovered:", recovered)
print("perfect :", sent == recovered)
# sent : {'A': 1, 'B': 0, 'C': 1, 'D': 1}
# recovered: {'A': 1, 'B': 0, 'C': 1, 'D': 1}
# perfect : True
# The near-far problem: orthogonality assumes comparable received power.
loud = 20 * users["A"] + 1 * users["B"] # A is 20x stronger (much closer)
print("B recovered correctly with perfect codes:", receive(loud, "B"))
# Still works with PERFECT orthogonality — but any timing misalignment or
# code imperfection scales with A's power, which is why real systems must
# control transmit power hundreds of times per second.
Key takeaways
- CDMA lets all users transmit simultaneously on the same frequency, separated by orthogonal chipping codes.
- The sender multiplies each bit by its code (spreading); the receiver correlates with the same code, so other users' contributions sum to zero.
- Walsh–Hadamard codes provide mutually orthogonal sets by construction.
- Properties unique to CDMA: soft capacity (graceful degradation), interference resistance, low power spectral density, and inherent signal obscurity.
- The near-far problem — a nearby transmitter swamping a distant one — requires fast, precise power control.
- CDMA underpinned 3G cellular and still underpins GPS; 4G and 5G moved to OFDMA for better spectral efficiency.
🧪 Practice
- Given codes A = (+1,−1,+1,−1) and B = (+1,+1,−1,−1), verify they are orthogonal, then compute the composite when A sends 1 and B sends 0, and recover both bits.
- Explain why CDMA has "soft capacity" while TDM and FDM have hard limits, in terms of what adding a user actually consumes.
- Interview-style: GPS signals arrive weaker than the background noise, yet receivers decode them reliably. How? (Hint: think about what correlation over a long code does to a signal versus to uncorrelated noise.)
Simplex, Half-Duplex, and Full-Duplex Modes
Theory
Separate from how many users share a medium is the question of direction: which way can data flow, and can both directions be active at once? Three modes exist.
Simplex transmits in one direction only, permanently. The receiver has no return path at all. Broadcast television, radio, GPS reception, and a keyboard's connection to a computer are simplex. It is rare in networking because virtually all protocols need acknowledgements.
Half-duplex allows both directions, but only one at a time — the participants must take turns. Walkie-talkies are the canonical example, and the "over" convention exists precisely to signal the turn change. In networking, half-duplex requires a mechanism to arbitrate turns and to handle the case where two stations transmit at once: a collision. Legacy Ethernet on hubs and coax used CSMA/CD (listen before transmitting, detect collisions, back off and retry); Wi-Fi is fundamentally half-duplex because a radio cannot listen on the frequency it is transmitting on, so it uses CSMA/CA to avoid collisions rather than merely detect them.
Full-duplex allows simultaneous transmission in both directions. On twisted-pair Ethernet this is achieved by using separate pairs for each direction (or, in 1000BASE-T and above, by transmitting in both directions on all four pairs simultaneously and using echo cancellation to subtract one's own transmission from the received signal). Fibre achieves it with two strands or, in BiDi optics, two wavelengths. Full duplex eliminates collisions entirely — with a dedicated path in each direction, there is nothing to collide with — and doubles aggregate throughput.
| Mode | Directions | Simultaneous? | Collisions possible | Example |
|---|---|---|---|---|
| Simplex | One | N/A | No | Broadcast TV, GPS |
| Half-duplex | Both | No | Yes | Hubs, Wi-Fi, walkie-talkies |
| Full-duplex | Both | Yes | No | Switched Ethernet, fibre pairs |
The practical importance of this topic is duplex mismatch, one of the most instructive faults in networking. Ethernet devices negotiate speed and duplex automatically. If one end has autonegotiation disabled and is hard-set to full duplex while the other end autonegotiates, the autonegotiating end cannot detect duplex and falls back to half duplex by rule. The result: one end transmits whenever it likes; the other end, believing the link is half duplex, interprets incoming frames arriving during its own transmission as collisions.
The symptoms are distinctive and easily misread:
- The link comes up and basic connectivity works, so it "looks fine".
- Throughput is catastrophically poor, often a few percent of line rate — but only under load.
- The half-duplex end logs late collisions and collisions; the full-duplex end logs FCS/CRC errors and runts.
- Performance is worse in both directions at once, which is the giveaway.
The rule that avoids all of this: autonegotiation on both ends, or hard-set on both ends — never one of each. Modern gigabit and faster links require autonegotiation by standard, so the fault is now mostly confined to 10/100 equipment, but it remains a classic interview question because diagnosing it requires understanding what each end believes about the other.
Examples
The three modes
SIMPLEX A -------------------> B one direction, forever
HALF-DUPLEX A <------------------> B both directions, one at a time
A ===> A transmits...
<=== B ...then B does.
A ===> <=== B COLLISION both at once = corrupted
FULL-DUPLEX A ===================> B simultaneous, no collisions
A <=================== B (separate pairs or echo cancellation)
Duplex mismatch: each end believes something different
Switch port (hard-set FULL) NIC (autoneg -> falls back to HALF)
"I can send any time" "I must wait for a clear line"
| |
|--- frame ------------------------->| NIC is mid-transmission
| | -> NIC calls this a COLLISION
|<-- frame (NIC transmitting) -------|
| switch sees a corrupted frame |
| -> logs FCS errors |
Result: link is UP, ping works, throughput is ~2 Mb/s on a 100 Mb/s link.
# Diagnosing a duplex mismatch: the counters tell the whole story.
$ ethtool eth0
# Speed: 100Mb/s
# Duplex: Half <- expected Full: first red flag
# Auto-negotiation: on <- this end negotiated; the peer did not
# Link detected: yes
$ ethtool -S eth0 | grep -iE 'collision|error|carrier'
# tx_late_collisions: 18442 <- LATE collisions: the signature symptom.
# A normal collision happens in the first
# 64 bytes; a late one means the other end
# transmitted while we already were.
# rx_crc_errors: 90213
# tx_carrier_errors: 0
# The peer's view of the same link:
$ show interface GigabitEthernet1/0/7
# Full-duplex, 100Mb/s, media type is 10/100/1000BaseTX
# 0 runts, 0 giants, 90213 CRC, 0 frame <- CRC errors piling up
# Input queue: 0/75/0/0 (size/max/drops/flushes)
# The fix: make both ends agree. Autoneg on both is the standard choice.
$ sudo ethtool -s eth0 autoneg on
# and on the switch:
# interface GigabitEthernet1/0/7
# duplex auto
# speed auto
# Why a mismatch destroys throughput even though the link "works".
def effective_throughput(line_rate_mbps, collision_rate, is_mismatched):
if not is_mismatched:
return line_rate_mbps
# Every collision costs the frame plus an exponential backoff wait,
# and retransmissions collide again, compounding the loss.
usable = (1 - collision_rate) ** 3 # crude model of compounding retries
return line_rate_mbps * usable
for rate in (0.0, 0.3, 0.6, 0.8):
print(f"collision rate {rate:>4.0%}: "
f"{effective_throughput(100, rate, True):>6.2f} Mb/s of 100 Mb/s")
# collision rate 0%: 100.00 Mb/s of 100 Mb/s
# collision rate 30%: 34.30 Mb/s of 100 Mb/s
# collision rate 60%: 6.40 Mb/s of 100 Mb/s
# collision rate 80%: 0.80 Mb/s of 100 Mb/s
# Ping (tiny, infrequent packets) still succeeds throughout — which is exactly
# why the fault gets misdiagnosed as an application problem.
Key takeaways
- Simplex is one-directional; half-duplex alternates directions; full-duplex transmits both ways simultaneously.
- Half-duplex requires collision handling — CSMA/CD on legacy Ethernet, CSMA/CA on Wi-Fi, which is half-duplex because a radio cannot receive on the frequency it is transmitting on.
- Full-duplex eliminates collisions by giving each direction its own path (separate pairs, separate fibres, separate wavelengths, or echo cancellation).
- Duplex mismatch occurs when one end is hard-set to full duplex and the other autonegotiates and falls back to half.
- Its signature is a link that comes up and passes pings but collapses under load, with late collisions on one end and CRC errors on the other.
- The rule: autonegotiate on both ends or hard-set both ends — never one of each.
🧪 Practice
- Classify each as simplex, half-duplex, or full-duplex: a hub-connected LAN, a fibre pair, Wi-Fi, GPS reception, a telephone call.
- Explain why full-duplex operation makes CSMA/CD unnecessary, referring to what a collision physically is.
- Interview-style: A 1 Gb/s link passes pings perfectly but transfers files at 3 Mb/s. Interface counters show late collisions on one side and CRC errors on the other. Diagnose it. (Hint: ask what each end believes about the other's duplex setting, and why small infrequent packets survive while bulk transfer does not.)
<a id="35-physical-layer-devices"></a>
3.5 Physical Layer Devices
This closing subchapter covers the hardware that operates purely at layer 1 — devices that move and regenerate signals without understanding what the signals mean — and the consequences of that ignorance.
Repeaters and Hubs
Theory
A signal degrades with distance until it can no longer be decoded, which caps every medium's reach. A repeater extends that reach by receiving the degraded signal and generating a fresh one.
The important detail is how it does this. A digital repeater performs 3R regeneration:
- Re-amplify — restore the signal's amplitude.
- Re-shape — restore clean edges, undoing the rounding that bandwidth limits caused.
- Re-time — recover the clock and re-emit symbols on a clean timebase, removing accumulated jitter.
Because the repeater makes a decision about each symbol before re-emitting it, noise does not accumulate — the analog-versus-digital argument from the start of this chapter, realised in hardware. A simple analog amplifier does only the first R and would boost the noise along with the signal.
What a repeater does not do is understand the data. It has no idea what a frame is, cannot read a MAC address, and will happily regenerate a corrupted frame just as faithfully as a good one. This is precisely what makes it a layer 1 device.
A hub (or multiport repeater) applies the same logic to more than two ports: a signal arriving on any port is regenerated and sent out every other port. Hubs were the original way to build star-wired Ethernet, and they have three fatal consequences that follow directly from operating at layer 1:
- One collision domain. Since every transmission reaches every port, two stations transmitting simultaneously collide no matter where they are. All stations share the segment and must run CSMA/CD.
- Half-duplex only. A station must listen while transmitting to detect collisions, so it cannot use both directions at once.
- Bandwidth is shared, not per-port. A 100 Mb/s hub with 12 stations gives 100 Mb/s total across all of them, and effective throughput falls further as collisions rise with load.
Add a security consequence: because every frame reaches every port, any host can put its NIC in promiscuous mode and read all traffic on the segment. On a switch, unicast traffic is only sent to the destination port.
A switch looks physically similar but reads destination MAC addresses and forwards selectively — making it a layer 2 device, giving each port its own collision domain, and enabling full duplex. That difference is so decisive that hubs vanished from the market entirely; they survive only in legacy installations, in teaching, and occasionally as a deliberate tool for traffic capture, where their "flood everything" behaviour is the desired feature.
| Hub (layer 1) | Switch (layer 2) | |
|---|---|---|
| Forwarding decision | None — floods all ports | Destination MAC lookup |
| Collision domains | One, shared by all ports | One per port |
| Duplex | Half only | Full |
| Bandwidth | Shared across all ports | Dedicated per port |
| Can other hosts see your traffic? | Yes, all of it | No, only broadcast/multicast |
Examples
3R regeneration: why digital links do not accumulate damage
degraded input repeater clean output
_~-‾~_.-‾~._ decide + re-emit _|‾‾|__|‾‾|_
weak, rounded, --> amplitude restored -> full amplitude
jittery edges shape restored sharp edges
clock recovered correct timing
Hub vs switch, same four hosts:
HUB (one collision domain) SWITCH (four collision domains)
A ---+ A ---+
B ---+---[ HUB ] B ---+---[ SWITCH ]
C ---+ floods all C ---+ forwards by MAC
D ---+ D ---+
A->B also reaches C and D A->B reaches ONLY B
A and C transmitting = collision A->B and C->D run simultaneously
total = 100 Mb/s for everyone total = 400 Mb/s aggregate
# Throughput of a shared collision domain versus switched ports.
def hub_throughput(line_rate_mbps, n_stations, offered_load_fraction):
# Classic CSMA/CD efficiency degrades sharply as contention rises.
contention = min(0.95, offered_load_fraction * n_stations / 2)
efficiency = max(0.05, 1 - contention)
return line_rate_mbps * efficiency, line_rate_mbps * efficiency / n_stations
def switch_throughput(line_rate_mbps, n_stations):
# Each port is its own collision domain, full duplex, non-blocking fabric.
return line_rate_mbps * n_stations, line_rate_mbps
for n in (2, 6, 12, 24):
h_total, h_each = hub_throughput(100, n, 0.3)
s_total, s_each = switch_throughput(100, n)
print(f"{n:>2} stations | hub: {h_total:>6.1f} Mb/s total, {h_each:>5.1f} each"
f" | switch: {s_total:>6.0f} Mb/s total, {s_each:>5.0f} each")
# 2 stations | hub: 70.0 Mb/s total, 35.0 each | switch: 200 Mb/s total, 100 each
# 6 stations | hub: 10.0 Mb/s total, 1.7 each | switch: 600 Mb/s total, 100 each
# 12 stations | hub: 5.0 Mb/s total, 0.4 each | switch: 1200 Mb/s total, 100 each
# 24 stations | hub: 5.0 Mb/s total, 0.2 each | switch: 2400 Mb/s total, 100 each
# A hub gets WORSE as you add stations; a switch scales linearly.
Key takeaways
- A repeater performs 3R regeneration — re-amplify, re-shape, re-time — making a decision about each symbol so noise does not accumulate.
- Repeaters and hubs operate purely at layer 1: they cannot read addresses and regenerate corrupted frames as faithfully as good ones.
- A hub is a multiport repeater that floods every arriving signal to all other ports.
- Consequences: a single shared collision domain, half-duplex operation only, bandwidth shared across all ports, and all traffic visible to every attached host.
- Switches forward by destination MAC, giving each port its own collision domain and full duplex — which is why hubs are obsolete.
🧪 Practice
- Eight hosts share a 100 Mb/s hub. What is the theoretical average bandwidth per host, and why is the real figure lower?
- Explain why a hub cannot support full-duplex operation, referring to what a station must do to detect a collision.
- Interview-style: Why can an analog amplifier not replace a digital repeater on a long link? (Hint: state what each device does with the noise riding on the incoming signal.)
Media Converters and Transceivers
Theory
Networks are rarely homogeneous. A run may need to start as copper at a desk, cross a campus as fibre, and end as copper in a server room. A media converter performs this translation at layer 1: it receives signals on one medium and regenerates them on another, without inspecting or modifying the data.
The most common conversion is copper to fibre, used when a link must exceed copper's 100 m limit, cross between buildings where electrical isolation matters, or pass through an electrically noisy environment such as a factory floor. Because the conversion is purely physical, the devices at each end are unaware it happened — a switch plugged into a copper-to-fibre converter behaves exactly as if it had a long copper cable.
Media converters come in two varieties, and the difference matters for diagnosis:
- Unmanaged (transparent) converters simply translate signals. They are cheap and require no configuration, but they do not pass link-state information: if the fibre side goes down, the copper side may still show link, so the switch believes the path is healthy and keeps forwarding into a black hole.
- Managed converters support link fault pass-through (LFP), deliberately dropping the link on one side when the other side fails, so the switch detects the fault and can reroute. They may also offer DOM readings and SNMP monitoring.
That difference is a recurring operational trap: a transparent converter can turn a simple fibre break into a silent, hard-to-locate outage.
Transceivers were covered for optics earlier; the general principle is the same conversion function, packaged as a pluggable module inside the device rather than as a standalone box. Two further categories complete the picture:
- DAC (Direct Attach Copper) cables have transceivers permanently moulded onto both ends of a twinax cable. For in-rack runs under about 7 m they are cheaper than optics, consume roughly a watt less per port, and add less latency — which is why data centres use them heavily for server-to-top-of-rack connections.
- AOC (Active Optical Cable) does the same with fibre and integrated optics, reaching tens of metres while remaining cheaper than separate optics plus patch cords.
One practical caution: vendor lock checks. Many switch vendors program their optics with a vendor ID and reject third-party modules. Third-party optics are typically identical hardware at a fraction of the price, and most platforms have a command to permit unsupported transceivers — but the support implications are a real consideration.
Examples
A mixed-media link, transparent to both endpoints
[Switch A]--copper--[MC]===fibre 2 km===[MC]--copper--[Switch B]
Cat6, 30 m ^ ^ Cat6, 40 m
media converters
Both switches see "a link". Neither knows fibre is involved.
Why link fault pass-through matters:
WITHOUT LFP: WITH LFP:
fibre cut here -----X fibre cut here -----X
[A]--cu--[MC] X [MC]--cu--[B] [A]--cu--[MC] X [MC]--cu--[B]
link UP link UP link DOWN link DOWN
^ A keeps sending into a ^ A sees the failure immediately
black hole; STP never and can reroute or alarm
reconverges
# Distinguishing a media converter problem from a switch problem.
$ ethtool eth0
# Speed: 1000Mb/s
# Link detected: yes <- copper side is up ... but to WHAT?
$ ping -c 3 10.0.2.1
# 3 packets transmitted, 0 received, 100% packet loss
# Link up + no traffic + a media converter in the path = suspect the far side.
# On a managed converter, check the optical side directly:
$ snmpwalk -v2c -c public 10.0.9.50 1.3.6.1.2.1.2.2.1.8
# IF-MIB::ifOperStatus.1 = INTEGER: up(1) <- copper port
# IF-MIB::ifOperStatus.2 = INTEGER: down(2) <- fibre port: here is the fault
# Choosing an interconnect for a given distance:
# 0 - 7 m DAC twinax cheapest, lowest power, lowest latency
# 7 - 30 m AOC cheaper than optics + patch cords
# 30 m - 400 m SR optics + MMF
# 400 m - 10 km LR optics + SMF
# > 10 km ER/ZR optics + SMF, possibly with amplification
# Why data centres prefer DAC in-rack: power adds up across thousands of ports.
OPTIONS = { # (cost per link, watts per link, typical max metres)
"DAC twinax": (30, 0.1, 7),
"AOC": (90, 1.5, 30),
"SR optics x2": (160, 2.0, 400),
"LR optics x2": (400, 2.6, 10000),
}
def rack_cost(option, n_links, years=5, dollars_per_kwh=0.12, pue=1.5):
cost, watts, _ = OPTIONS[option]
capex = cost * n_links
kwh = watts * n_links * pue * 24 * 365 * years / 1000
return capex, kwh * dollars_per_kwh
for opt in OPTIONS:
capex, opex = rack_cost(opt, n_links=48)
print(f"{opt:<14} 48 links: capex ${capex:>6,.0f} "
f"5-yr power ${opex:>7,.0f} total ${capex+opex:>7,.0f}")
# DAC twinax 48 links: capex $ 1,440 5-yr power $ 38 total $ 1,478
# AOC 48 links: capex $ 4,320 5-yr power $ 568 total $ 4,888
# SR optics x2 48 links: capex $ 7,680 5-yr power $ 757 total $ 8,437
# LR optics x2 48 links: capex $19,200 5-yr power $ 984 total $ 20,184
# Across a data centre with 100,000 ports, this choice is worth millions.
Key takeaways
- Media converters translate signals between media at layer 1, transparently to the devices at each end.
- Transparent converters do not signal faults across the conversion, so a break on one side can leave the other side's link up — creating silent black-hole outages.
- Managed converters support link fault pass-through, propagating the failure so switches detect it and reroute.
- DAC cables (integrated twinax, under ~7 m) are cheaper, cooler, and lower-latency than optics for in-rack links.
- AOC cables integrate optics with fibre for tens of metres at lower cost than modular optics.
- Vendor lock checks may reject third-party optics; most platforms offer an override.
🧪 Practice
- A link between two buildings 400 m apart currently uses copper repeaters. Propose a better design and justify it on at least three grounds.
- Explain how an unmanaged media converter can cause spanning tree to fail to reconverge after a fibre cut.
- Interview-style: A link shows "up" on both switches but passes no traffic, and there is a media converter in the path. What is your diagnostic sequence? (Hint: consider which segment each switch can actually observe, and what a transparent converter hides.)
Patch Panels and Structured Wiring
Theory
A patch panel is a passive array of ports that terminates permanent cabling in one place, so that connections can be made and changed with short patch cords rather than by pulling cable. It contains no electronics, needs no power, and performs no signal processing — it is the physical embodiment of the permanent-link-versus-channel distinction from the structured cabling topic.
The mechanism is worth being precise about, because it is where cheap installations go wrong. Solid-core horizontal cable is terminated on the rear of the panel using insulation displacement contacts (IDC) — punched down with a tool that forces the conductor into a sharp metal slot which cuts through the insulation and makes a gas-tight connection. The front presents standard RJ45 jacks. Nothing is soldered and nothing is crimped.
The payoff is operational. A device's connection is changed by moving a patch cord in the wiring closet — seconds of work, no disruption, no construction. Without patch panels, changing which switch port serves a desk means re-terminating permanent cable, which degrades it a little each time and eventually exhausts the cable's length.
Several rules protect the performance you paid for:
- Untwist as little as possible. No more than 13 mm (half an inch) of pair should be untwisted at the termination. Beyond that, the cancellation that twisting provides is lost exactly where signals are most vulnerable, and NEXT performance collapses. This single mistake is responsible for a large fraction of certification failures.
- Honour the bend radius, both in the cable manager and where cable enters the panel.
- Maintain pair integrity. Wiring pin 3 and pin 6 from different physical pairs — a split pair — passes a continuity test perfectly while destroying crosstalk performance, producing a link that works at 100 Mb/s and fails at 1 Gb/s.
- Label everything per TIA-606, at both ends. An unlabelled panel converts every future change into an exercise in tracing.
- Use the right cable type in the right place: solid core in the walls and on the punch-down side, stranded for patch cords.
Two terms complete the vocabulary. The MDF (Main Distribution Frame) is the building's central cross-connect, usually in the equipment room. An IDF (Intermediate Distribution Frame) is a floor-level or zone-level distribution point, in what TIA-568 calls the telecommunications room. Backbone cable runs MDF to IDF; horizontal cable runs IDF to work areas.
A related pattern is the fibre patch panel or LIU (Lightwave Interconnect Unit), where incoming fibre is spliced to short pigtails terminated in LC or SC adapters, so that fragile spliced fibre is never handled during routine changes. The same principle applies: protect the permanent installation, make changes on the disposable side.
Examples
Patch panel: permanent cable in the back, changes at the front
REAR (punched down once, never touched again)
solid-core Cat6a from the walls
||||||||||||||||||||||||||||
+----------------------------+
| IDC punch-down terminations |
|============================| <- patch panel
| 1 2 3 4 5 6 ... 24 | RJ45 jacks
+--+--+--+--+--+--+-------+--+
| | | | | | |
patch cords (stranded, disposable, changed freely)
| | | | | | |
+--+--+--+--+--+--+-------+--+
| access switch ports |
+----------------------------+
Moving a user from VLAN A to VLAN B = move ONE patch cord. No cable pulled.
The untwist rule, drawn:
GOOD: twisted right up to the IDC BAD: 35 mm of untwisted pair
~~~~~~~~~~~~~~~~~~~|| ~~~~~~~~~~____________||
<= 13 mm untwisted ^IDC a long unbalanced run ^IDC
NEXT stays within spec NEXT fails certification
# Certification outcomes traced to installation mistakes.
FAULTS = {
"excessive untwist": {"wiremap": "PASS", "length": "PASS",
"NEXT": "FAIL", "symptom": "1G unstable, 100M fine"},
"split pair": {"wiremap": "PASS", "length": "PASS",
"NEXT": "FAIL", "symptom": "works at 100M, fails at 1G"},
"reversed pair": {"wiremap": "FAIL", "length": "PASS",
"NEXT": "PASS", "symptom": "no link at all"},
"cable too long": {"wiremap": "PASS", "length": "FAIL",
"NEXT": "PASS", "symptom": "intermittent, worse when warm"},
"kinked cable": {"wiremap": "PASS", "length": "PASS",
"NEXT": "PASS", "symptom": "return loss fails; errors"},
}
print(f"{'fault':<20}{'wiremap':<10}{'length':<9}{'NEXT':<7}symptom")
for fault, r in FAULTS.items():
print(f"{fault:<20}{r['wiremap']:<10}{r['length']:<9}{r['NEXT']:<7}{r['symptom']}")
# fault wiremap length NEXT symptom
# excessive untwist PASS PASS FAIL 1G unstable, 100M fine
# split pair PASS PASS FAIL works at 100M, fails at 1G
# reversed pair FAIL PASS PASS no link at all
# cable too long PASS PASS FAIL intermittent, worse when warm
# kinked cable PASS PASS PASS return loss fails; errors
#
# Note the pattern: the faults that pass a WIREMAP test are the dangerous ones.
# A cheap continuity tester cannot find a split pair — only a certifier can.
Key takeaways
- A patch panel is a passive termination point: permanent solid-core cable is punched down on the rear using IDC contacts, and RJ45 jacks on the front accept patch cords.
- It implements the permanent-link/channel separation, so moves and changes happen by re-patching rather than re-cabling.
- Untwist no more than 13 mm at any termination; exceeding it destroys NEXT performance.
- Split pairs pass continuity tests but fail crosstalk, producing links that work at 100 Mb/s and fail at 1 Gb/s.
- Solid core belongs in walls and punch-downs; stranded belongs in patch cords.
- MDF is the building's main cross-connect; IDF is a floor-level distribution point; backbone runs between them and horizontal runs from IDF to work areas.
- Label to TIA-606 at both ends — the faults that pass a basic wiremap test are the ones that cost the most time.
🧪 Practice
- Explain why patch cords use stranded conductors while permanent cable uses solid core, naming the physical property behind each choice.
- A link passes a continuity test but fails at 1 Gb/s while working at 100 Mb/s. Name the two most likely termination faults and the test that would reveal them.
- Interview-style: Why not simply run cable directly from each switch port to each desk and skip patch panels entirely? (Hint: think about what happens on the tenth move, and what repeated re-termination does to a solid-core cable.)
Collision Domains at the Physical Layer
Theory
A collision domain is a set of devices whose transmissions can interfere with one another — a region of the network where, if two stations transmit simultaneously, the signals overlap on the medium and both are destroyed. It is fundamentally a layer 1 concept, because a collision is a physical event: two electrical signals superimposed on the same conductor.
This existed because early Ethernet was a genuinely shared medium. On 10BASE5 and 10BASE2 coax, every station tapped the same cable; with hubs, every port received every signal. The arbitration protocol was CSMA/CD (Carrier Sense Multiple Access with Collision Detection):
- Carrier sense — listen; if the medium is busy, wait.
- Multiple access — when idle, transmit.
- Collision detection — keep listening while transmitting; if the received signal does not match what was sent, a collision occurred.
- Jam and back off — send a 32-bit jam signal so everyone notices, then wait a random interval chosen by binary exponential backoff (after n collisions, wait a random number of slot times in the range 0 to 2ⁿ−1, capped at 1023) and retry.
The randomised backoff is essential: if both stations waited the same time, they would collide again forever.
This protocol explains a piece of Ethernet trivia that otherwise looks arbitrary: the 64-byte minimum frame size. A station must still be transmitting when a collision from the far end of the maximum-diameter segment reaches it — otherwise it would finish, believe it succeeded, and never retransmit. The worst-case round-trip time across a maximum 10 Mb/s segment corresponds to 512 bit times, which is 64 bytes. Frames shorter than that are padded. A collision detected after the first 64 bytes is a late collision, which is never normal and always indicates a fault — a segment that is too long, or the duplex mismatch described earlier.
The domain boundaries follow directly from what each device does:
| Device | Collision domains | Broadcast domains |
|---|---|---|
| Hub / repeater | Extends the existing one (all ports share) | Extends the existing one |
| Bridge / switch | One per port | Extends the existing one |
| Router | One per interface | One per interface |
| VLAN on a switch | One per port | One per VLAN |
The modern situation is that collision domains have essentially disappeared from wired Ethernet. A switch port connected to a single device operating in full duplex has a dedicated path in each direction, so there is nothing to collide with — CSMA/CD is disabled entirely. The concept survives in three places: legacy hub installations, Wi-Fi (where the medium is genuinely shared and half-duplex, hence CSMA/CA), and troubleshooting, where collision counters on a full-duplex link are proof of a misconfiguration rather than of contention.
Do not confuse this with a broadcast domain, the set of devices reached by a broadcast frame. Switches separate collision domains but not broadcast domains — that requires a router or a VLAN. This distinction is a very common exam question, and Chapter 4 develops it.
Examples
Counting domains in a mixed topology
[ROUTER]
/ \
[SWITCH A] [SWITCH B]
/ | \ | \
PC PC [HUB] PC PC
/ \
PC PC
Collision domains:
- each SWITCH A port with a PC: 2
- SWITCH A port to the HUB + the hub's whole segment: 1 (shared by 2 PCs)
- each SWITCH B port: 2
- router-to-switch links: 2
= 9 collision domains
Broadcast domains:
- everything on SWITCH A's side: 1
- everything on SWITCH B's side: 1
= 2 (the ROUTER is the boundary)
CSMA/CD timeline:
A: |--sense idle--|--transmit------XX jam |--backoff 3 slots--|--retransmit-->
B: |--sense idle--|--transmit--XX jam |--backoff 1 slot--|--transmit-->
^^ collision detected by both
randomised backoff breaks the tie
import random
def binary_exponential_backoff(collision_count, slot_time_us=51.2):
"""802.3 backoff: wait 0..2^n-1 slot times, capped at 1023 (n = 10)."""
n = min(collision_count, 10)
slots = random.randint(0, 2**n - 1)
return slots, slots * slot_time_us
for attempt in range(1, 9):
slots, micros = binary_exponential_backoff(attempt)
print(f"collision #{attempt}: range 0-{2**min(attempt,10)-1:>4} slots, "
f"waited {slots:>4} slots = {micros:>9.1f} us")
# collision #1: range 0- 1 slots, waited 1 slots = 51.2 us
# collision #4: range 0- 15 slots, waited 11 slots = 563.2 us
# collision #8: range 0- 255 slots, waited 187 slots = 9574.4 us
# After 16 attempts the frame is discarded and the error reported upward.
# Why minimum frame size is 64 bytes:
SLOT_TIME_BITS = 512 # worst-case round trip on a max segment
print(f"minimum frame = {SLOT_TIME_BITS} bit times = {SLOT_TIME_BITS//8} bytes")
# minimum frame = 512 bit times = 64 bytes
# A station MUST still be transmitting when the far end's collision reaches it,
# or it would wrongly conclude the frame succeeded.
def domain_count(topology):
"""Collision domains: one per switch/router port, one per hub segment."""
return (topology["switch_ports"] + topology["router_ports"]
+ topology["hub_segments"])
net = {"switch_ports": 6, "router_ports": 2, "hub_segments": 1}
print(f"collision domains: {domain_count(net)}") # collision domains: 9
Key takeaways
- A collision domain is the set of devices whose simultaneous transmissions physically interfere — a layer 1 phenomenon.
- CSMA/CD arbitrates a shared medium: sense carrier, transmit, detect collision, jam, then wait a randomised binary exponential backoff before retrying.
- Ethernet's 64-byte minimum frame exists so a station is still transmitting when a worst-case collision reaches it — 512 bit times across a maximum segment.
- A late collision (after 64 bytes) always indicates a fault: an over-long segment or a duplex mismatch.
- Hubs extend a collision domain; switches create one per port; routers create one per interface.
- Switches do not separate broadcast domains — that requires a router or VLAN.
- Full-duplex switched links have no collision domain at all, and CSMA/CD is disabled.
🧪 Practice
- Count the collision domains and broadcast domains in a network with one router, two 8-port switches (all ports used), and one 4-port hub attached to a switch port.
- Explain why binary exponential backoff uses a random interval rather than a fixed one, and what would happen with a fixed wait.
- Interview-style: You see late collisions on a full-duplex gigabit link. What does this tell you, given that full-duplex links cannot have collisions? (Hint: if collisions are impossible, then one end does not believe the link is full duplex.)
Power over Ethernet
Theory
PoE (Power over Ethernet) delivers electrical power over the same twisted-pair cable that carries data, letting a device operate with a single cable and no nearby mains outlet. The value is not primarily the electricity — it is eliminating the electrician. Mounting a wireless access point in a ceiling, a camera on an exterior wall, or a phone on a desk becomes a single network drop rather than a drop plus an electrical circuit installed by a licensed professional.
Two further benefits follow. Power can be centrally managed: a switch can reboot a frozen access point by cycling power on its port, remotely. And the whole estate can be backed by one UPS in the wiring closet rather than dozens of small ones.
The standards ladder is the main thing to know, and the two power numbers per row matter because cable resistance dissipates some of what is sent:
| Standard | Name | PSE output | Powered device gets | Pairs used |
|---|---|---|---|---|
| 802.3af (2003) | PoE / Type 1 | 15.4 W | 12.95 W | 2 |
| 802.3at (2009) | PoE+ / Type 2 | 30 W | 25.5 W | 2 |
| 802.3bt (2018) | PoE++ / Type 3 | 60 W | 51 W | 4 |
| 802.3bt (2018) | PoE++ / Type 4 | 100 W | 71.3 W | 4 |
The vocabulary: the PSE (Power Sourcing Equipment) supplies power — either a switch (endspan) or an inline midspan injector between switch and device. The PD (Powered Device) consumes it. Power is delivered as roughly 48 V DC (the permitted range is about 44–57 V); a high voltage is chosen deliberately because for a given wattage, higher voltage means lower current and therefore lower I²R loss in the thin conductors.
Delivery uses one of two pin arrangements. Alternative A superimposes power on the data pairs (1/2 and 3/6) using the centre taps of the magnetics, so power and data coexist on the same conductors without interfering. Alternative B uses the spare pairs (4/5 and 7/8), which only works on 10/100 links where those pairs are idle. 802.3bt's Type 3 and 4 energise all four pairs — which is why they need all eight conductors properly terminated, and why a cable wired for 100 Mb/s with only two pairs cannot carry high-power PoE.
The safety mechanism is the elegant part. A PSE never simply energises a port, because that would destroy non-PoE equipment. Instead it performs detection: it applies a low voltage and looks for the PD's signature 25 kΩ resistance. Only if that signature is present does it proceed to classification (determining the power class so the budget can be allocated) and then to full power. Plugging a laptop into a PoE port is therefore harmless — the laptop presents no signature, so no power is applied.
Two operational realities complete the picture. Power budget is a switch-level constraint: a 48-port switch advertising 370 W of PoE cannot deliver 30 W to every port simultaneously, so ports are prioritised and low-priority ports shed first when the budget is exceeded. And heat matters: current through bundled cables raises their temperature, which raises resistance, which reduces the maximum supported length — standards derate cable length in large, tightly packed bundles.
Examples
PoE negotiation before any real power flows
PSE (switch) PD (access point)
|---- detection: apply 2.8-10 V ------>|
|<--- looks for 25 kohm signature -----| no signature -> STOP (safe)
|---- classification: 15.5-20.5 V ---->|
|<--- current draw indicates class ----| class 4 = up to 30 W
|---- allocate 30 W from the budget -->|
|---- apply 48 V DC ------------------>| device powers up
|<--- monitors current continuously ---| device unplugged -> power off
Alternative A (data pairs) Alternative B (spare pairs)
pins 1,2 : data + power (+) pins 4,5 : power (+)
pins 3,6 : data + power (-) pins 7,8 : power (-)
pins 4,5,7,8 : unused pins 1,2,3,6 : data only
802.3bt Type 3/4: ALL FOUR pairs carry power.
STANDARDS = { # (PSE watts, PD watts, pairs)
"802.3af (Type 1)": (15.4, 12.95, 2),
"802.3at (Type 2)": (30.0, 25.50, 2),
"802.3bt (Type 3)": (60.0, 51.00, 4),
"802.3bt (Type 4)": (100.0, 71.30, 4),
}
DEVICES = { # typical draw
"VoIP phone": 6.5, "Wi-Fi 5 AP": 15.4, "Wi-Fi 6E AP": 25.5,
"PTZ camera": 30.0, "Wi-Fi 7 AP": 51.0, "Thin client": 60.0,
}
def required_standard(watts):
for name, (_, pd_watts, _) in STANDARDS.items():
if watts <= pd_watts:
return name
return "exceeds PoE"
for dev, w in DEVICES.items():
print(f"{dev:<14} {w:>5.1f} W -> {required_standard(w)}")
# VoIP phone 6.5 W -> 802.3af (Type 1)
# Wi-Fi 5 AP 15.4 W -> 802.3at (Type 2)
# Wi-Fi 6E AP 25.5 W -> 802.3at (Type 2)
# PTZ camera 30.0 W -> 802.3bt (Type 3)
# Wi-Fi 7 AP 51.0 W -> 802.3bt (Type 3)
# Thin client 60.0 W -> 802.3bt (Type 4)
def plan_budget(switch_budget_w, devices):
"""Switch PoE budgets are shared; oversubscription sheds low-priority ports."""
total = sum(devices.values())
print(f"switch budget {switch_budget_w} W, requested {total:.1f} W "
f"({total/switch_budget_w:.0%})")
if total > switch_budget_w:
print(f" OVERSUBSCRIBED by {total - switch_budget_w:.1f} W "
f"-> lowest-priority ports will be denied power")
return total <= switch_budget_w
plan_budget(370, {f"AP{i}": 25.5 for i in range(12)})
# switch budget 370 W, requested 306.0 W (83%)
plan_budget(370, {f"AP{i}": 25.5 for i in range(20)})
# switch budget 370 W, requested 510.0 W (138%)
# OVERSUBSCRIBED by 140.0 W -> lowest-priority ports will be denied power
# Inspecting PoE allocation on a switch.
$ show power inline
# Available:370.0(w) Used:118.5(w) Remaining:251.5(w)
# Interface Admin Oper Power Device Class Max
# Gi1/0/1 auto on 25.5 AIR-AP3802I 4 30.0
# Gi1/0/2 auto on 15.4 AIR-AP2802I 3 30.0
# Gi1/0/3 auto off 0.0 n/a n/a 30.0
# ^ no PD signature detected: safe, not a fault
# Gi1/0/7 auto power-deny 0.0 IP Phone 8851 2 30.0
# ^ budget exhausted, or this port is low priority
Key takeaways
- PoE carries power and data on one twisted-pair cable, removing the need for separate electrical work near the device.
- Standards: 802.3af 15.4 W, 802.3at (PoE+) 30 W, 802.3bt Type 3 60 W and Type 4 100 W at the source; the powered device receives less due to cable loss.
- PSE supplies power (endspan switch or midspan injector); PD consumes it; delivery is roughly 48 V DC to minimise I²R loss.
- Alternative A uses the data pairs, Alternative B the spare pairs; 802.3bt uses all four pairs, so all eight conductors must be terminated.
- A PSE performs detection (looking for a 25 kΩ signature) and classification before applying power, so non-PoE devices are never damaged.
- Switch power budgets are shared across ports and can be oversubscribed, causing low-priority ports to be denied power.
- Current raises cable temperature and resistance, so dense bundles derate maximum length.
🧪 Practice
- A 48-port switch has a 740 W PoE budget. How many 802.3at access points at 25.5 W can it power simultaneously, and what happens if more are connected?
- Explain why PoE uses 48 V rather than 12 V, referring to current, conductor resistance, and power loss.
- Interview-style: An access point powers up, runs briefly, then reboots in a loop. Give three physical-layer causes. (Hint: consider the switch's budget, the cable's length and gauge, and whether the PD's class matches what the PSE allocated.)
<a id="4-the-data-link-layer"></a>