---
title: 'Repeater, Hub, and Switch'
source: 'https://academia.sh/en/courses/switching-and-routing/repeater-hub-and-switch'
course: 'Switching and Routing'
language: en
updated: '2026-08-17T18:07:17+00:00'
license: 'CC BY-SA 4.0'
---

# Repeater, Hub, and Switch

Three device classes are measured on the same forty frames: the repeater and the hub set up a single collision domain and produce 280 deliveries and 34 collisions, a table-less switch zeroes the collisions but keeps 240 unnecessary copies, and a switch with a table brings deliveries down to 40.

The previous course counted what an intermediary can read **from a message**.
There, the decision was made by looking at what was written in the message:
the method field said something, the status code said something, and the
intermediary ran purely by reading these. When the message closed, the
intermediary went blind.

A switch's decision is not made this way. The device receiving the frame
passes it to an output by looking at **its own table**; the destination
address written in the frame is only the question asked of the table, not
the answer itself. The answer is in the device's memory. And what is in
that memory is a **copy** of a shared reality — the copy can go stale, can
be incomplete, can contradict its neighbor's. This is the course's one
subject. This lesson's question comes before that: how do a
decision-making device and a non-deciding device diverge on the same
traffic?

## Where the Decision Is Read From

What is measured throughout the course is a single mechanism. There is a
**table**; the table maps a destination to an output. The device takes the
incoming frame or packet, looks up its destination in the table, and
passes it to the output it finds. The table itself is not the device's
invention: it derives from the network's real shape, but it is kept as a
**local copy** of that reality.

To measure whether the copy agrees with reality, the reality has to be
written down separately. Throughout the course, this is called the
**oracle**: because we build the topology ourselves, where every
destination is is known. The oracle is not information in a device's
hands; it is the ruler in the measurement's hands.

When the copy does not agree with reality, one of three things happens to
the packet, and the course uses these three names to the end. **Reached:**
the packet arrived at its destination. **Loop:** the packet crossed the
same link a second time, or burned through the hop limit; it did not die,
it is circling. **Black hole:** the output is not in the table, or is no
longer a real output; the packet ended there. The only fate measured in
this lesson is **reached**, because a single device's table cannot set up
a loop by itself. A loop is a disagreement between at least two tables,
and two tables show up in this topic's later lessons.

## Three Device Classes

Three device classes standing on the same local network read the decision
from three separate places.

A **repeater** reads from nowhere. It joins two segments and refreshes the
signal coming from one side, pushing it out the other. It does not decode
the frame, does not look at an address, keeps no table. What it does is
undo the signal's weakening; it buys distance, not decision.

A **hub** is a repeater with many ports. It pushes the signal coming in on
one port out to all the remaining ports. The port count is greater than
two, but the decision mechanism is the same: nonexistent.

A **switch** reads the decision from a table. The table maps a hardware
address to a port; if the frame's destination address is in the table, the
frame goes out only that port. How it fills the table — writing an
incoming frame's source address together with the port it arrived on, and
**flooding** a frame whose destination is unknown — was established in the
Ethernet and MAC Addresses lesson of the Network Models and Protocols
course and is not repeated here. Here the table is taken as given; what is
measured is what the table's **existence** buys.

The distinction is a layer distinction. The repeater and the hub work at
the signal level: what they carry is a bit stream, not a frame. The switch
works at the link layer: it recognizes the frame as a unit, reads its
address fields, and makes a decision. Which layer a device stands at says
not how fast it is, but **what it can look at**.

## Forwarding Modes

A switch's decision is made at one point in time, and the choice of that
point gives rise to two modes.

In **store-and-forward** mode, the switch takes in the whole frame,
verifies the check sequence, and only then passes it to a port. A
corrupted frame never gets placed on an output; its cost is a wait
proportional to the frame's length.

In **cut-through** mode, the switch picks the output the moment it reads
the destination address and passes the remaining bytes through as they
stream in. The wait is only as long as the address field, independent of
the frame's length. Its cost is this: the check sequence is at the end of
the frame, meaning it has not yet been seen when the decision is made. A
corrupted frame gets forwarded too, and only the receiver finds the error.

The choice is not a right-versus-wrong choice, but a trade-off that
depends on what is being counted: latency on one side, wasted transmission
on the other. This lesson's measurement is independent of the mode and the
same in both, because what is counted is not **when** the decision is made
but whether it is made at all.

## Two Domains

Two scopes are distinguished, and this distinction is the first measure
that separates the three devices from each other.

A **collision domain** is the set of devices whose signals can clash if
transmission happens at the same time. The repeater and the hub set up a
single shared medium: eight stations are in a single collision domain.
Every port of the switch is a separate collision domain; a transmission on
one port does not clash with a transmission on another.

A **broadcast domain** is the set of devices a broadcast frame reaches.
None of the three devices splits the broadcast domain. Nor does the
switch: a frame whose destination is a group address goes out every port.
The mechanism that splits the broadcast domain is the subject of this
topic's later lessons.

## Full-Duplex Ports and Buffers

Every port of the switch being a separate collision domain means collision
**can** happen in that domain. If a port has a single station on it and
the port runs full-duplex, sending and receiving travel on separate paths,
and two transmissions that would clash never arise at all. The switch's
zeroing of collisions comes from this structure: the collision domain was
not shrunk, it was **emptied out.**

This has a cost, and the queue column in the measurement counts it. Two
transmissions cannot happen at the same time on a shared medium; they can
on a switch, because the input ports are independent of each other. When
two inputs want the same output, the switch has to hold one of them, and
where it holds it is a **buffer.** If the buffer fills, the frame is
dropped — the site of the loss has moved from the medium to the device.

The same reasoning works when port speeds are not equal too. A frame
coming in on a fast port and going out on a slow one waits out the
difference in the buffer. On a shared medium, such a difference was
undefined: everyone spoke at the same speed, because everyone was on the
same wire.

The measurement's setup is this: eight stations are connected to a single
device through eight ports. Forty frames are sent; every frame has a
source, a destination, and a time slot. The device's table is read as in
the transcript below.

```text
# taught transcript, not run

MAC address table (switch)
  address   port
  a         1
  b         2
  ...
  h         8

trace of one frame
  source a, destination e
    hub        -> 2,3,4,5,6,7,8   (seven copies, six unnecessary)
    switch     -> 5               (one copy)
  when destination is not in the table
    switch     -> 2,3,4,5,6,7,8   (flooding; same as hub)
```

## The Measurement's Assumptions

- **ND1** — Eight stations are connected to a single device through eight
  ports, and every station is on exactly one port. The oracle is known
  because we built this layout ourselves: the measurement knows which
  address is on which port, the device may not.
- **ND2** — Forty frames are generated. Source and destination are drawn
  from one generator, the time slot from a separate generator; each
  generator is called with a single modulus. A draw where source and
  destination are the same is discarded.
- **ND3** — The number of time slots is twenty. Forty frames spread over
  twenty slots means a loaded medium; what is measured is not the
  absolute collision count, but what the same load becomes across the
  three devices.
- **ND4** — On a shared medium, if a slot has more than one sender, every
  frame in that slot is counted as **collided**. There is no collision on
  separate ports; every extra frame in the same slot wanting the same
  output port is written to the **queue**.
- **ND5** — Four regimes are compared: repeater, hub, a switch with an
  empty table, and a switch with a full table. The switch with an empty
  table is a setup that does not learn; its purpose is to separate the
  gain of port isolation from the gain of the table.
- **ND6** — The load axis is built with the slot count: the same forty
  frames are fit into forty, twenty, and ten slots. When the slot count
  changes, the draws are redone from scratch, so the load rows are not
  subsets of each other; what is compared is not the same frame
  sequence, but the same density rule.
- **ND7** — The set's resolution is forty frames; the smallest measurable
  difference is $1/40 = 0{,}025$. A difference smaller than this cannot be
  defended with this set.

## The Measurement

```python
"""Three device classes on the same traffic: domain counts and delivered frames.

Source and destination are drawn from one generator, the time slot from a
separate generator; each generator is called with a single modulus.
"""
SEED = 20260810
STATIONS = ["a", "b", "c", "d", "e", "f", "g", "h"]
SLOTS = 20


def generator(seed):
    d = seed % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def frames(count=40, slots=SLOTS):
    r, z, result = generator(SEED), generator(SEED + 1), []
    while len(result) < count:
        x, y = STATIONS[r(8)], STATIONS[r(8)]
        if x != y:
            result.append({"source": x, "destination": y, "slot": z(slots)})
    return result


def oracle():
    """Reality: which station stands on which port."""
    return {a: i + 1 for i, a in enumerate(STATIONS)}


def measure(C, table, shared_medium):
    location, filled, sent = oracle(), {}, {}
    delivered = unnecessary = collided = 0
    for c in C:
        filled[c["slot"]] = filled.get(c["slot"], 0) + 1
    for c in C:
        port = table.get(c["destination"])
        outputs = ([port] if port is not None
                   else [p for p in location.values() if p != location[c["source"]]])
        delivered += len(outputs)
        unnecessary += sum(1 for p in outputs if p != location[c["destination"]])
        if shared_medium:
            collided += 1 if filled[c["slot"]] > 1 else 0
        else:
            for p in outputs:
                sent[(c["slot"], p)] = sent.get((c["slot"], p), 0) + 1
    queue = sum(n - 1 for n in sent.values() if n > 1)
    return delivered, unnecessary, collided, queue


C, FULL = frames(), oracle()
print(f"frames {len(C)} | stations {len(STATIONS)} | time slots {SLOTS}")
print()
print(f"{'device':<20s} {'ports':>5s} {'collision':>9s} {'broadcast':>9s} "
      f"{'delivered':>9s} {'unnecessary':>11s} {'collided':>8s} {'queue':>6s}")
for name, ports, table, shared in (("repeater", 2, {}, True),
                                    ("hub", 8, {}, True),
                                    ("switch, no table", 8, {}, False),
                                    ("switch, full table", 8, FULL, False)):
    d, u, co, q = measure(C, table, shared)
    print(f"{name:<20s} {ports:5d} {1 if shared else ports:9d} {1:9d} "
          f"{d:9d} {u:11d} {co:8d} {q:6d}")
print()
print(f"{'slots':>5s} {'hub collided':>12s} {'no-table queue':>14s} "
      f"{'full-table queue':>17s}")
for d in (40, 20, 10):
    Cd = frames(40, d)
    _, _, co, _ = measure(Cd, {}, True)
    _, _, _, q0 = measure(Cd, {}, False)
    _, _, _, q1 = measure(Cd, FULL, False)
    print(f"{d:5d} {co:12d} {q0:14d} {q1:17d}")
```

```
frames 40 | stations 8 | time slots 20

device               ports collision broadcast delivered unnecessary collided  queue
repeater                 2         1         1       280         240       34      0
hub                      8         1         1       280         240       34      0
switch, no table         8         8         1       280         240        0    151
switch, full table       8         8         1        40           0        0      6

slots hub collided no-table queue  full-table queue
   40           27            102                 3
   20           34            151                 6
   10           38            202                10
```

## Two Separate Gains

The first two rows are **identical to each other**, and this is not a
shortcoming but the lesson's first finding. The repeater has two ports,
the hub has eight; the domain counts they produce, the copy counts they
deliver, and the collided-frame counts all come out the same. Adding
ports buys no decision. Because neither reads the decision from anywhere,
they are the same device.

The third row measures port isolation alone. The switch with an empty
table still floods: **280** deliveries, **240** unnecessary copies — the
same as the hub's. The only thing that changes is collision: it drops
from **34** to **0**. Because the ports are separate collision domains,
two transmissions no longer corrupt each other. Transmissions that are
not corrupted do not vanish, they go into the **queue**: **151** extra
copies wanting to go out the same port in the same slot wait in line.
Collision did not disappear, it **turned into queuing.**

The fourth row adds the table's gain. Delivered drops from **280** to
**40**, unnecessary copies from **240** to **0**: every one of the forty
frames goes out exactly one port. The queue also drops from **151** to
**6**, because now only the frames that genuinely need to go there want a
given port.

The distinction is this: **port isolation removes collision, the table
removes unnecessary copies.** They are two separate mechanisms, and they
are measured separately. A table-less switch is better than a hub in
wiring, and no different from it in workload.

The differences counted are within the measurement's band. In a set of
forty frames, the smallest measurable difference is $1/40 = 0{,}025$; the
differences here are not at the level of one frame but tens of frames.
The **34**-frame drop in collision is **0.850** of the set, and the
**240**-unit drop in unnecessary copies is six copies per frame. A
difference at this scale does not depend on the fiction's detail.

## When Load Rises

The table below sends the same forty frames at three separate densities:
light load when spread over forty slots, heavy when packed into ten.

On the shared medium, collided frames climb from **27** to **34**, then
to **38**. The rise slows because there is a known ceiling: all forty of
the forty frames can collide, and there is nothing past that. This is the
shared medium's behavior under load — degradation is measured **by
frames lost**, and it saturates.

On the switch, the same load shows up as a queue. On the switch with a
table, the queue climbs to **3**, **6**, **10** entries; on the
table-less switch, to **102**, **151**, **202**. Two observations follow.
First, on a switch, load produces not **loss** but **waiting**: the frame
does not disappear, it waits its turn. Second, flooding raises the queue
roughly twentyfold — because every frame wants not one port but seven.
The table's gain grows as load rises: the gap is **99** entries under
light load, **192** under heavy load.

One more warning is read from the table above. The broadcast domain
column is **1** in all four rows. No matter how well the switch decides
with its table, it has to give a frame whose destination is a group
address to every port — because that frame's destination never lands on
a single port in the table. In an eight-station domain, a single
broadcast frame produces seven deliveries; as the domain grows, this
number grows with it.

## Summary

- In this course, the decision is not read from what is written in the
  message; it is read from the device's **table**, and the table is a
  local copy of a shared reality.
- A packet has three fates — **reached**, **loop**, **black hole**; a
  single device's table cannot set up a loop by itself, a loop is a
  disagreement between at least two tables.
- The repeater and the hub are the same device: on forty frames, both
  give **1** collision domain, **280** deliveries, **240** unnecessary
  copies, and **34** collided frames.
- Port isolation brings collision down from **34** to **0** but does not
  touch unnecessary copies; collision does not disappear, it turns into
  **151** queue entries. The table brings delivered down from **280** to
  **40**, unnecessary copies from **240** to **0**, the queue from
  **151** to **6**.
- As load rises, collision on the shared medium saturates toward forty
  with **27**, **34**, **38**; the same load on the switch becomes **3**,
  **6**, **10** queue entries — waiting, not loss.
- None of the three devices splits the broadcast domain; the broadcast
  domain count stays **1** across all four regimes.

## Next Step

In this measurement, the switch's table was taken as given: all eight of
the eight addresses were mapped to the right port. In reality, a table
does not start that way and does not stay that way. When a switch powers
on, its table is empty; if a station goes quiet, its entry gets deleted
after a while; if a station moves to another port, its entry stays wrong
for a while. The next lesson measures the table's **age**: how many
frames an unlearned and an aged entry make get flooded, and which domain
that flooding grows.
