Loading content...
Networks are dynamic. Devices power off, laptops move to different desks, virtual machines migrate between hosts, and cables get unplugged. If a bridge's forwarding database never forgot anything, these changes would cause serious problems.
Imagine this scenario:
AA:11:22:33:44:55) is connected to Port 1AA:11:22:33:44:55 → Port 1Without a mechanism to remove stale entries, moved devices would experience prolonged outages, unplugged devices would consume table space indefinitely, and the forwarding database would eventually fill with garbage.
The solution is entry aging—a timer-based mechanism that automatically removes entries that haven't been refreshed by recent traffic.
By the end of this page, you will understand the aging mechanism in detail—including timer operation, default values and configuration, the relationship between aging and topology changes, how aging interacts with STP, and best practices for tuning aging timers in various network environments.
Every dynamic entry in the forwarding database has an associated age—either a timestamp of last update or a countdown timer. The bridge uses this age to determine when entries should be removed.
How Aging Works
1. Entry Creation
When a new MAC address is learned, a timer is initialized. This can be implemented as:
2. Entry Refresh on Traffic
Every time a frame is received with this MAC as the source address:
This keeps active entries alive indefinitely.
3. Periodic Aging Check
The bridge periodically examines all entries:
4. Entry Removal (Aging Out)
When an entry ages out:
Default Aging Time
The IEEE 802.1D standard specifies a default aging time of 300 seconds (5 minutes). This value represents a balance between:
Most network equipment uses 300 seconds as the default, but this is configurable.
Why 300 Seconds?
The 5-minute default was chosen based on typical network behavior patterns:
This value made sense for networks of the 1990s. Modern networks may benefit from adjustment.
It's critical to understand that aging only applies to dynamic entries (those learned automatically). Static entries configured by administrators never age out—they remain in the table until manually removed. This is by design: static entries are for critical addresses that must always be known.
Aging time is a tunable parameter on virtually all managed switches. Understanding when and how to adjust it is an important network administration skill.
Configuration Commands
Cisco IOS:
! Global configuration
switch(config)# mac address-table aging-time 120
! Per-VLAN configuration (some platforms)
switch(config)# mac address-table aging-time 120 vlan 10
! Verify configuration
switch# show mac address-table aging-time
Global Aging Time: 120
Vlan Aging Time
---- ----------
10 120
20 300
Juniper Junos:
[edit ethernet-switching-options]
set mac-table-aging-time 120
HP/Aruba:
switch(config)# mac-age-time 120
Linux Bridge:
# Set aging time to 120 seconds
ip link set br0 type bridge ageing_time 12000
# Note: Linux uses centiseconds (12000 = 120 seconds)
| Environment | Suggested Aging Time | Rationale |
|---|---|---|
| Stable data center | 300-600 seconds | Devices rarely move; fewer timeouts, less flooding |
| Office with mobile users | 120-300 seconds | Laptops move between ports; faster adaptation |
| High-change VM environment | 60-120 seconds | VMs migrate frequently; need quick path updates |
| Industrial control network | 600-1200 seconds | Devices extremely stable; minimize any disruption |
| Public WiFi/guest network | 60-120 seconds | Clients come and go; table space matters |
| After STP topology change | 15-30 seconds (temporary) | Accelerated flush to quickly relearn correct paths |
Trade-offs When Adjusting Aging Time
Shorter Aging Time (< 300 seconds)
Pros:
Cons:
Longer Aging Time (> 300 seconds)
Pros:
Cons:
Setting aging time to 0 disables aging—entries never expire. This is rarely appropriate because moved devices will be permanently black-holed until they transmit. However, it might be used in extremely static networks (embedded systems, industrial control) where no device ever moves and table space is ample.
The interaction between MAC aging and Spanning Tree Protocol (STP) is critical for understanding network convergence behavior.
The Problem: Topology Changes
When STP reconverges due to a link failure or addition:
If we wait for normal aging (5 minutes), traffic will be misdirected for up to 5 minutes—unacceptable for modern networks.
The Solution: Accelerated Aging on TCN
When STP detects a Topology Change, bridges take special action:
Parameters Involved
Several STP parameters affect aging behavior during topology changes:
Forward Delay (default: 15 seconds)
Max Age (default: 20 seconds)
Topology Change Time = max_age + forward_delay = 35 seconds
Rapid Spanning Tree (RSTP) Improvements
RSTP (802.1w) improves on classic STP:
Frequent topology changes cause repeated table flushes, leading to constant flooding and poor network performance. Common causes include: flapping links (intermittent physical issues), misconfigured port fast settings, and aggressive STP parameters. Monitor for excessive Topology Change Notifications in switch logs.
Understanding how aging is actually implemented helps explain some edge cases and performance characteristics.
Timestamp-Based Aging
The most common implementation:
Entry Structure:
{
mac_address: 48 bits,
port: port_id,
last_seen: 32-bit timestamp (seconds since epoch),
type: static | dynamic
}
Aging Process (runs periodically, e.g., every second):
current_time = get_current_time()
for each entry in fdb:
if entry.type == dynamic:
if (current_time - entry.last_seen) > aging_time:
remove(entry)
Pros:
Cons:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
from dataclasses import dataclassfrom time import timefrom typing import Dict, Optional @dataclassclass FDBEntry: """Forwarding Database Entry with aging support""" mac_address: str port: int last_seen: float entry_type: str = "dynamic" # "dynamic" or "static" def age(self, current_time: float) -> float: """Return age in seconds""" return current_time - self.last_seen def is_expired(self, current_time: float, aging_time: float) -> bool: """Check if entry has exceeded aging time""" if self.entry_type == "static": return False # Static entries never expire return self.age(current_time) > aging_time class ForwardingDatabase: """Simulates bridge forwarding database with aging""" def __init__(self, aging_time: float = 300.0): self.entries: Dict[str, FDBEntry] = {} self.aging_time = aging_time def learn(self, mac: str, port: int) -> None: """Learn or update a MAC address""" current_time = time() if mac in self.entries: entry = self.entries[mac] if entry.entry_type == "static": return # Don't overwrite static entries if entry.port != port: print(f"MAC move: {mac} moved from port {entry.port} to {port}") entry.port = port entry.last_seen = current_time else: self.entries[mac] = FDBEntry( mac_address=mac, port=port, last_seen=current_time, entry_type="dynamic" ) print(f"Learned: {mac} on port {port}") def lookup(self, mac: str) -> Optional[int]: """Look up destination port for a MAC address""" if mac not in self.entries: return None # Unknown - must flood entry = self.entries[mac] return entry.port def run_aging(self) -> int: """Remove expired entries, return count of removed entries""" current_time = time() expired = [] for mac, entry in self.entries.items(): if entry.is_expired(current_time, self.aging_time): expired.append(mac) for mac in expired: print(f"Aged out: {mac} (age: {self.entries[mac].age(current_time):.0f}s)") del self.entries[mac] return len(expired) def set_aging_time(self, seconds: float) -> None: """Adjust aging time (e.g., during STP topology change)""" self.aging_time = seconds print(f"Aging time set to {seconds} seconds") # Example usage demonstrating agingif __name__ == "__main__": fdb = ForwardingDatabase(aging_time=10) # Short aging for demo # Simulate learning fdb.learn("AA:BB:CC:11:22:33", 1) fdb.learn("DD:EE:FF:44:55:66", 2) # Wait and run aging (in real code, this runs periodically) import time as t t.sleep(12) removed = fdb.run_aging() print(f"Removed {removed} aged entries")Hardware Accelerated Aging
In high-performance switches, aging may be implemented in hardware:
Aging Granularity
Most implementations have aging granularity of 1 second—entries may persist up to 1 second longer than the configured aging time. This is the resolution at which the aging process runs and is generally acceptable.
Some implementations have coarser granularity (5-10 seconds) to reduce CPU overhead. This is transparent to administrators but may cause slight timing variations.
While aging handles routine maintenance automatically, administrators sometimes need to manually intervene with forwarding database entries.
Clearing the Entire FDB
For troubleshooting or recovery, you may need to flush all learned entries:
Cisco IOS:
! Clear all dynamic entries
switch# clear mac address-table dynamic
! Clear entries for specific interface
switch# clear mac address-table dynamic interface gigabitethernet0/1
! Clear entries for specific VLAN
switch# clear mac address-table dynamic vlan 10
! Clear specific MAC address
switch# clear mac address-table dynamic address aaaa.bbbb.cccc
When to Manually Clear
Impact of Manual Clear
Clearing the FDB causes immediate flooding:
Viewing FDB and Entry Ages
To understand what's happening with aging:
! View table with ages
switch# show mac address-table
! View specific entry detail
switch# show mac address-table address aaaa.bbbb.cccc
! View table statistics
switch# show mac address-table count
Some platforms show the exact age of each entry; others only show whether entries are dynamic or static. For detailed age tracking, check platform-specific documentation.
Clearing the FDB on a core or distribution switch affects all traffic passing through that switch. The resulting flood can overwhelm links and trigger congestion on connected switches. In production, clear selectively (by VLAN, port, or MAC) rather than clearing everything if possible.
Several situations reveal interesting aspects of aging behavior that are important for advanced troubleshooting.
Edge Case 1: Receive-Only Devices
Some devices only receive traffic and never transmit (or transmit very rarely):
For these devices:
Solution: Create static entries for receive-only devices if bandwidth is a concern.
Edge Case 2: Infrequent Transmitters
Devices that transmit less often than the aging time:
These devices may age out between transmissions, causing their traffic to be flooded.
Solutions:
| Device Type | Traffic Pattern | Aging Risk | Recommendation |
|---|---|---|---|
| Desktop PC | Regular, bidirectional | Low—constant traffic refreshes | Default aging works well |
| Laptop (wired) | Variable, may move | Medium—mobility, idle periods | Shorter aging if many mobile |
| Server | Heavy, constant | Very low—always active | Default or longer aging |
| Network printer | Bursty, long idle periods | High—may age out frequently | Static entry or longer aging |
| IoT sensor | Periodic, one-way | Very high—may never be learned | Static entry typically required |
| Virtual machine | Variable, may migrate | Variable—depends on migration | Shorter aging for VMware/etc. |
Edge Case 3: Link Down Events
When a port goes down, what happens to entries learned on that port?
Most implementations: Entries are immediately flushed when the port link status changes to down. This is proactive—we know those paths are invalid, so why wait for aging?
Some implementations: Entries persist and age normally. This can cause delays in reconvergence.
Check your switch vendor's behavior:
switch# show mac address-table interface gigabitethernet0/1
! Unplug the cable
! Wait a moment
switch# show mac address-table interface gigabitethernet0/1
! If empty, entries were flushed on link-down
Edge Case 4: VLAN Changes
When a port's VLAN assignment changes:
Always verify that VLAN changes properly update the FDB—stale cross-VLAN entries can cause subtle connectivity issues.
Some switches allow configuring aging time per-VLAN, while others only support a global setting. Per-VLAN aging is useful when you have VLANs with different mobility characteristics—e.g., a static server VLAN might use longer aging than a mobile user VLAN.
Effective monitoring of aging behavior helps identify network issues before they impact users.
Key Metrics to Monitor
1. Table Size Over Time
Track how many entries are in the FDB:
2. Aging Events Rate
How often entries age out:
3. Unknown Unicast Flood Rate
How often flooding occurs:
| Symptom | Possible Cause | Investigation Steps |
|---|---|---|
| Traffic black-holed to specific destination | Stale FDB entry pointing wrong port | Check FDB for destination MAC; verify port; clear if wrong |
| Excessive flooding in network | Table overflow, aggressive aging, or attack | Check table utilization; verify aging config; look for flood source |
| MAC keeps appearing on different ports | MAC flapping due to loop or attack | Check STP status; investigate loop; enable storm control |
| Device works intermittently | Ages out between transmissions | Check aging time; add static entry if needed |
| New device can't communicate | Not learned yet, depends on flooding | Wait for transmission; check port config |
| Post-topology-change flooding | Normal STP TC behavior | If prolonged, check for STP issues |
Useful Commands for Troubleshooting
View complete FDB state:
switch# show mac address-table
switch# show mac address-table count
switch# show mac address-table aging-time
Track specific MAC:
switch# show mac address-table address aaaa.bbbb.cccc
Debug learning/aging (use carefully):
switch# debug mac-address-table
! Warning: Can generate massive output in busy networks
SNMP Monitoring:
Standard MIBs provide FDB access:
dot1dTpFdbTable (802.1D bridge MIB)dot1qTpFdbTable (802.1Q VLAN MIB)These can be polled to track:
Establish a baseline of normal FDB behavior: typical table size, typical churn rate, expected entries per VLAN. When problems occur, comparing current state to the baseline makes anomalies obvious. Many network monitoring systems can graph these metrics over time.
We've thoroughly examined how bridges manage the lifecycle of forwarding database entries. Let's consolidate the essential concepts:
What's Next: The Loop Problem
We've now covered learning, forwarding, filtering, and aging—the complete lifecycle of FDB entries. But there's a critical vulnerability in all of this: what happens when there are loops in the network topology? Without special handling, loops cause catastrophic failures. The next page explores the loop problem—why it occurs, its devastating effects, and how it's detected.
You now understand the aging mechanism—how it works, why it exists, how to configure it, and how it interacts with STP. This knowledge completes your understanding of FDB lifecycle management and prepares you for understanding why loop prevention (covered next) is absolutely critical.