Redundant links are a loop waiting to happen — so spanning tree blocks one, and half your bandwidth sleeps. Understand the election, choose your root bridge on purpose, switch to Rapid PVST+, and then bundle those redundant links into an EtherChannel that uses them all.
Plug two switches together twice — for redundancy — and without protection you've built a bridging loop: ethernet frames have no TTL, so one broadcast circulates forever, multiplying until both switches melt at 100% CPU. That's a broadcast storm, and it takes down networks in seconds. Spanning tree (STP) is the immune system: the switches elect a root bridge, compute the shortest loop-free tree, and deliberately block every redundant path. Loops prevented — but blocked links carry nothing.
That's the trade this post resolves. First, understand and control STP: if you don't pick the root bridge, the network picks for you — usually the oldest, slowest switch in the building. Then reclaim the wasted bandwidth: EtherChannel bundles parallel links into one logical interface that STP treats as a single path, so all members forward at once. Redundancy and throughput — this is how switch uplinks should be built.
01
Everything in spanning tree flows from one choice: the root bridge. Every switch measures its distance to the root, keeps its best path, and blocks the rest. The election is won by the lowest bridge ID — priority first, then MAC address.
SW1# show spanning-tree vlan 10 VLAN0010 Spanning tree enabled protocol rstp Root ID Priority 24586 Address 0cd0.f894.1a00 Cost 4 Port 24 (GigabitEthernet0/24) ← my way toward the root Bridge ID Priority 32778 (priority 32768 sys-id-ext 10) Address 70b3.d5aa.2c00 ← this switch's own ID Interface Role Sts Cost Prio.Nbr Type Gi0/1 Desg FWD 4 128.1 P2p Edge Gi0/23 Altn BLK 4 128.23 P2p ← the blocked redundancy Gi0/24 Root FWD 4 128.24 P2p
Read it top-down: the Root ID block names the elected root and my cost to reach it; the Bridge ID block is me. If the two blocks show the same address, this switch is the root. Below, each port has a role: Root (my best path toward the root), Desg (designated — forwarding for its segment), Altn BLK (the loop-breaker, parked in blocking). One blocked port per redundant loop is spanning tree working exactly as designed.
Every switch defaults to priority 32768, so the election tie-breaks on the lowest MAC address — which usually belongs to the oldest switch in the building. Result: a ten-year-old access switch under a desk becomes the root, and all inter-VLAN traffic hairpins through it. If you've never set a priority, this is your topology right now. Check with show spanning-tree root — if the root isn't your core, fix it in section 02.
02
The root bridge should be your core switch — the box in the middle of the traffic patterns. One command per VLAN pins it, and a second names the backup.
# The readable way: "primary" sets priority low enough to win (24576 or lower) CORE(config)# spanning-tree vlan 10,20,99 root primary # On the second-best switch — the designated backup root: DIST(config)# spanning-tree vlan 10,20,99 root secondary # Or set the number explicitly (must be a multiple of 4096): CORE(config)# spanning-tree vlan 10 priority 24576 # Verify the core now wins: CORE# show spanning-tree vlan 10 | include This bridge is the root This bridge is the root
Cisco runs one spanning-tree instance per VLAN (PVST+/Rapid PVST+), which is why every command takes a VLAN list — and why a priority shows as 32778 for VLAN 10: the VLAN ID is added to the base priority (32768 + 10) as the "sys-id-ext". Per-VLAN trees also mean you can make one switch root for VLANs 10–20 and another for 30–40, splitting load across two uplinks that would otherwise sit half-blocked. That's a free optimization on any dual-core design.
03
Classic STP takes 30–50 seconds to converge after a failure. Rapid PVST+ does it in about a second, with the same commands you already know. On modern Catalysts it's usually the default — but verify, don't assume.
# One global command, on EVERY switch: SW1(config)# spanning-tree mode rapid-pvst SW1(config)# end # Confirm — "protocol rstp" in the header means rapid is active: SW1# show spanning-tree summary | include mode Switch is in rapid-pvst mode # And the PortFast/BPDU-guard defaults from the Switch Security post: SW1(config)# spanning-tree portfast bpduguard default
Rapid PVST+ interoperates with old STP — a legacy switch on the network quietly drags that segment back to slow timers. Migrate everything, then verify per switch. And the PortFast + BPDU guard pairing from the Switch Security post now makes full sense: PortFast tells STP "this is a host port, skip the listening/learning wait," and BPDU guard enforces that promise by killing the port if a switch ever appears there.
04
Two or four parallel links between the same pair of switches, one logical interface. STP sees a single link so nothing blocks; traffic hashes across all members; one member dying is invisible to the topology.
# Pick the member ports — they must be IDENTICAL (speed, duplex, mode, VLANs) SW-A(config)# interface range GigabitEthernet0/23 - 24 SW-A(config-if-range)# channel-group 1 mode active # active = initiate LACP Creating a port-channel interface Port-channel 1 SW-A(config-if-range)# exit # Configure the BUNDLE, not the members — trunk settings go here: SW-A(config)# interface Port-channel1 SW-A(config-if)# switchport mode trunk SW-A(config-if)# switchport trunk native vlan 99 SW-A(config-if)# switchport trunk allowed vlan 10,20,99 SW-A(config-if)# end # SW-B: the exact same block. "active" on both sides is the clean pattern. # (mode on = static bundle, no protocol — only if a device can't speak LACP.) SW-A# show etherchannel summary Flags: P - bundled in port-channel S - Layer2 U - in use Group Port-channel Protocol Ports ------+-------------+-----------+---------------------------- 1 Po1(SU) LACP Gi0/23(P) Gi0/24(P) # (SU) and every member (P) = healthy. (SD) or (s) members = see the gotcha.
Every member port must match exactly — speed, duplex, switchport mode, allowed VLANs, native VLAN. One mismatch and that member shows (s) suspended in show etherchannel summary while the rest carry on: you silently paid for four links and run on three. Worse: mode on (static) on one side with LACP on the other creates a bundle that looks up but can loop or blackhole, because one side isn't checking anything. Rule: active/active with LACP, configure through the Port-channel interface, and read the flags after every change.
EtherChannel load-balances by hashing (src/dst MAC or IP), so each flow sticks to one member link. A 4×1G bundle gives you 4 Gbps of aggregate capacity, not a 4 Gbps pipe for a single backup job — one flow still tops out at 1G. That's the right trade for switch uplinks carrying many users' traffic, but if a single server-to-server transfer needs more than a member link, you need a faster link, not a wider bundle. Check the hash with show etherchannel load-balance; src-dst-ip spreads best in most networks.
05
The recurring questions: who is root, why is this port blocking, why did the topology just change, and is the bundle healthy.
| Command | Answers |
|---|---|
| show spanning-tree root | Root bridge, its priority, and my cost/port toward it — per VLAN. |
| show spanning-tree vlan 10 | The full tree for one VLAN: roles, states, who blocks. |
| show spanning-tree summary | Mode (rapid?), PortFast/BPDU-guard defaults, blocked-port counts. |
| show spanning-tree detail | include ieee|occurr | When and where the last topology change came from — the flapping-port finder. |
| show etherchannel summary | Bundle health at a glance — (SU) good, (SD)/(s) broken. |
| show etherchannel load-balance | The hashing method in use. |
| show lacp neighbor | Confirms the other side actually speaks LACP. |
# Users report random 1-second freezes. Suspect STP topology changes: CORE# show spanning-tree vlan 10 detail | include occurr Number of topology changes 4817 last change occurred 00:00:41 ago from GigabitEthernet0/14 # 4817 changes and counting, all from Gi0/14 — a flapping link or a host # port without PortFast bouncing. Fix: portfast on host ports (edge ports # don't generate topology changes), and investigate Gi0/14's cabling.
06
RouterOS bridges run (R)STP too, and bonding is its EtherChannel. The concepts carry straight over.
| MikroTik / RouterOS | Cisco IOS |
|---|---|
| bridge protocol-mode=rstp | spanning-tree mode rapid-pvst |
| bridge priority=0x6000 | spanning-tree vlan X priority 24576 |
| One tree per bridge | One tree per VLAN (PVST+) — finer control, more to check |
| bridge port edge=yes | spanning-tree portfast |
| bridge port bpdu-guard=yes | spanning-tree bpduguard enable |
| /interface bonding mode=802.3ad | EtherChannel channel-group N mode active (LACP) |
| transmit-hash-policy=layer-2-and-3 | port-channel load-balance src-dst-ip |
Takeaways
show spanning-tree is a feature.spanning-tree vlan X root primary on the core, secondary on its backup, verify with show spanning-tree root.active on both sides, always.show etherchannel summary flags after every change.The root bridge should be a decision, not whatever STP happened to elect. I design switch topologies where that's chosen deliberately, uplinks are properly bundled, and failover gets tested by pulling a cable — not assumed from a diagram.
Book a Discovery Call →