STP

Per-VLAN Spanning Tree (PVST+ and Rapid-PVST+) Explained

Per-VLAN Spanning Tree explained: PVST+ vs Rapid-PVST+, the sys-id-ext Bridge ID trick, per-VLAN root placement for uplink load balancing, and when to move to MSTP.
Per-VLAN Spanning Tree PVST feature image, PingLabz
Table of Contents
In: STP, VLAN, Fundamentals

Per-VLAN Spanning Tree is the reason a Cisco switch with 50 VLANs is running 50 spanning trees. It is also the reason you can load-balance traffic across redundant uplinks instead of letting half your links sit idle in blocking. PVST+ and Rapid-PVST+ are Cisco's per-VLAN take on spanning tree, and understanding them is the difference between accepting whatever topology STP hands you and engineering the one you want. This post explains how per-VLAN spanning tree works, why Cisco built it, and how to use it to load-balance.

For the cluster overview, see the Spanning Tree Protocol pillar. For the L2 fundamentals underneath, see the VLAN and L2 switching pillar.

The problem with one spanning tree

The original IEEE 802.1D ran a single spanning tree for the entire switched network, regardless of how many VLANs you had. One tree means one root bridge, one set of blocked ports, one topology.

Picture two distribution switches and two uplinks from an access switch. With a single spanning tree, one uplink forwards and the other blocks - for everything. Every VLAN's traffic crosses the same uplink. The second uplink, which you paid for, carries nothing until the first one fails.

That is wasteful, and it is the problem per-VLAN spanning tree solves.

The per-VLAN idea

Per-VLAN spanning tree runs a separate, independent spanning tree instance for every VLAN. Each VLAN can have its own root bridge, its own port roles, its own blocked ports.

Now take the same two-uplink example. You make distribution switch A the root for VLANs 10, 20, 30, and distribution switch B the root for VLANs 40, 50, 60. VLAN 10's spanning tree forwards on the uplink toward switch A and blocks the other. VLAN 40's spanning tree does the opposite. Both uplinks now carry traffic - half the VLANs on each. You have load-balanced across redundant links using nothing but root-bridge placement.

The Cisco PVST family

NameWhat it isStatus
PVSTOriginal per-VLAN STP. Required Cisco ISL trunking.Obsolete (ISL is dead)
PVST+Per-VLAN STP over 802.1Q trunks. Per-VLAN instances, but each runs the slow legacy 802.1D state machine.Legacy, still seen
Rapid-PVST+Per-VLAN STP where each instance runs the fast 802.1w (RSTP) state machine.Current Cisco default

On any modern Catalyst the default is Rapid-PVST+: one instance per VLAN, each instance converging in sub-second time thanks to RSTP. PVST+ (the slow-converging version) still turns up on older gear. The configuration command makes the choice explicit:

spanning-tree mode rapid-pvst

The Bridge ID and the sys-id-ext trick

Per-VLAN spanning tree needs a separate Bridge ID per VLAN, but a switch has one MAC address. Cisco solved this by splitting the Bridge ID priority field.

The 16-bit Bridge ID priority became: a 4-bit configurable priority + a 12-bit "system ID extension" that holds the VLAN number. So a switch running spanning tree for VLAN 10 with priority 32768 actually advertises a Bridge ID priority of 32768 + 10 = 32778. For VLAN 20 it is 32768 + 20 = 32788.

This is why show spanning-tree reports lines like priority 32778 (priority 32768 sys-id-ext 10). The base priority is 32768; the 10 is the VLAN. It also explains why switch priority must be set in multiples of 4096 - only the top 4 bits are yours; the bottom 12 belong to the VLAN ID.

Setting the root: the load-balancing config

You steer each VLAN's tree by setting the root bridge per VLAN. Two ways:

! Explicit priority - multiples of 4096
spanning-tree vlan 10,20,30 priority 24576
spanning-tree vlan 40,50,60 priority 28672

Or the macro that picks a low priority for you:

spanning-tree vlan 10,20,30 root primary
spanning-tree vlan 40,50,60 root secondary

On distribution switch A you make VLANs 10-30 primary and 40-60 secondary. On distribution switch B you do the mirror image. The result: VLANs 10-30 root on A, VLANs 40-60 root on B, and the access switch's two uplinks both forward - each carrying the VLANs whose root they point toward.

Reading the per-VLAN topology

SW-ACCESS# show spanning-tree vlan 10

VLAN0010
  Spanning tree enabled protocol rstp
  Root ID    Priority    24586
             Address     0050.7989.aaaa
             Cost        4
             Port        25 (TenGigabitEthernet1/1/1)

  Bridge ID  Priority    32778  (priority 32768 sys-id-ext 10)
             Address     0050.7989.cccc

Interface           Role Sts Cost      Prio.Nbr Type
------------------- ---- --- --------- -------- ----------------
Te1/1/1             Root FWD 4         128.25   P2p
Te1/1/2             Altn BLK 4         128.26   P2p

For VLAN 10, the access switch's uplink Te1/1/1 is the Root port and forwards; Te1/1/2 is Alternate and blocks. Run show spanning-tree vlan 40 and you should see the roles swapped - Te1/1/2 forwarding, Te1/1/1 blocking - because VLAN 40 roots on the other distribution switch. That swap is the proof your load balancing is working.

The summary view across all VLANs:

SW-ACCESS# show spanning-tree summary
Switch is in rapid-pvst mode
Name                   Blocking Listening Learning Forwarding STP Active
---------------------- -------- --------- -------- ---------- ----------
VLAN0010                      1         0        0          1          2
VLAN0040                      1         0        0          1          2

The cost of per-VLAN: scale

Per-VLAN spanning tree's strength - an independent tree per VLAN - is also its limit. Every VLAN is a full state machine, a set of BPDUs sent every 2 seconds on every trunk, and CPU to maintain. With 20 or 50 VLANs this is a non-issue. With 500 VLANs across a large campus it becomes real overhead, and the BPDU volume on trunks adds up.

That is the point where MSTP takes over: it keeps the load-balancing benefit by letting you map many VLANs onto a few instances, instead of one instance per VLAN. The rule of thumb: Rapid-PVST+ up to roughly 50-75 VLANs, MSTP beyond that.

Common gotchas

SymptomCause
"Priority must be a multiple of 4096" rejected your valueOnly the top 4 bits of the priority field are yours; the rest is the VLAN sys-id-ext. Use 0, 4096, 8192, ... 61440.
Both uplinks forward for every VLAN - no blocking anywhereThe two links are an EtherChannel (correct) - or a real loop with STP disabled (dangerous). Confirm which.
One uplink carries all VLANs; the other blocks for allAll VLANs share one root bridge. Split the root placement per VLAN range to load-balance.
BPDU load high on a big campus switchToo many per-VLAN instances. Migrate to MSTP.
Native VLAN inconsistency warningsTrunk native VLAN mismatch - unrelated to PVST roles but flagged in the same logs.

Key takeaways

Per-VLAN spanning tree runs an independent spanning tree per VLAN, which lets you place a different root bridge per VLAN and load-balance traffic across redundant uplinks instead of leaving half of them blocked. Cisco's current default is Rapid-PVST+ - per-VLAN instances each running the fast RSTP state machine. The VLAN number lives in the Bridge ID's sys-id-ext field, which is why switch priority must be a multiple of 4096. The model is excellent up to ~50-75 VLANs; beyond that, MSTP keeps the load-balancing benefit without the per-VLAN overhead.

For the STP cluster, see the Spanning Tree Protocol pillar.

Written by
More from Ping Labz
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Ping Labz.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.