Optimizing WiFi RTS Threshold and Fragmentation for High-Density, Noisy Environments: A Programmer’s Guide


2 views

html

The values 2346/2347 originate from the 802.11 protocol's maximum MSDU (MAC Service Data Unit) size of 2304 bytes plus overhead. Here's the breakdown:

// Typical WiFi frame structure calculation
#define IEEE80211_MAX_MSDU_SIZE   2304
#define LLC_SNAP_HEADER_LEN       8
#define WLAN_HEADER_LEN           24
#define WLAN_CRC_LEN              4
#define MAX_FRAME_LEN            (IEEE80211_MAX_MSDU_SIZE + LLC_SNAP_HEADER_LEN + WLAN_HEADER_LEN + WLAN_CRC_LEN)
// Result: 2304 + 8 + 24 + 4 = 2340
// Vendors typically round up to nearest even number (2346)

These settings control collision handling differently:

  • RTS Threshold: Triggers Request-to-Send/Clear-to-Send (RTS/CTS) handshake for frames larger than threshold
  • Fragmentation Threshold: Splits frames larger than threshold into smaller fragments

They're often set similarly because:

// Typical enterprise AP configuration logic
if (frame_size > fragmentation_threshold) {
    fragment_frame();
} else if (frame_size > rts_threshold) {
    initiate_rts_cts();
}

For your 50-75 user environment with roaming issues:

// Recommended starting values (Linux hostapd example)
rts_threshold=1492
fragm_threshold=1492
dtim_period=2
beacon_int=100

Testing methodology:

# Continuous ping test while roaming
ping -f -l 1472 google.com | tee ping_test.log

# Monitor retries and collisions
iw dev wlan0 station dump | grep -E "retries|tx retries"

For environments with persistent interference:

// Enable WMM (WiFi Multimedia) QoS
wmm_enabled=1

// Adjust contention window values
cwmin=15
cwmax=1023
aifsn=3

// Python script to monitor optimal settings
import subprocess
import matplotlib.pyplot as plt

def monitor_rssi(interface):
    cmd = f"iw dev {interface} link"
    # ... (implementation for signal quality tracking)

To improve AP handoffs:

  • Set 802.11k/v/r (Fast Transition) support if available
  • Ensure 20% RSSI overlap between APs (-67dBm to -70dBm recommended)
  • Match beacon intervals across all APs
// Example for OpenWRT roaming optimization
config wifi-device 'radio0'
    option roam_threshold '-70'
    option roam_delta '5'
    option rate_adaptive '1'

That magic number 2346 isn't arbitrary - it's derived from the maximum MSDU (MAC Service Data Unit) size in 802.11 standards minus 1 byte for the frame control field. Here's the technical breakdown:


// Typical WiFi frame structure components
#define WIFI_HEADER_SIZE        24    // Typical MAC header size
#define FCS_SIZE                4     // Frame Check Sequence
#define MAX_MSDU_SIZE           2304  // 802.11 standard maximum
#define DEFAULT_FRAG_THRESHOLD  (MAX_MSDU_SIZE + WIFI_HEADER_SIZE + FCS_SIZE - 2)
// Result: 2304 + 24 + 4 - 2 = 2330 (varies slightly by implementation)

While both mechanisms deal with frame transmission, they serve different purposes:

  • RTS Threshold: Controls when Request-to-Send/Clear-to-Send handshake occurs (collision avoidance)
  • Fragmentation Threshold: Determines packet splitting size (error recovery)

Their similar values aren't coincidence - they're both tied to maximum frame sizes, but should be configured differently based on your environment.

For your 50-75 user scenario with roaming issues:


// Suggested starting values for enterprise APs in noisy environments
#define OPTIMAL_RTS_THRESHOLD      1500  // Start with Ethernet MTU equivalent
#define OPTIMAL_FRAG_THRESHOLD     1300  // Slightly below to accommodate headers

// Linux hostapd configuration example
rts_threshold=1500
fragm_threshold=1300

When modifying these thresholds:

  1. Always test changes incrementally - drop by 200-300 bytes each step
  2. Monitor both throughput and stability - not just ping drops
  3. Different clients may react differently - test multiple device types

For monitoring, consider this Python snippet to test settings:


import subprocess
import statistics

def test_wifi_settings(rts, frag, samples=100):
    # Configure AP (vendor specific commands here)
    subprocess.run(f"configure_ap --rts {rts} --frag {frag}", shell=True)
    
    # Test latency
    latencies = []
    for _ in range(samples):
        ping = subprocess.run("ping -c 1 8.8.8.8", capture_output=True, text=True)
        if "time=" in ping.stdout:
            latency = float(ping.stdout.split("time=")[1].split(" ")[0])
            latencies.append(latency)
    
    return {
        'packet_loss': (samples - len(latencies)) / samples,
        'avg_latency': statistics.mean(latencies) if latencies else None,
        'jitter': statistics.stdev(latencies) if len(latencies) > 1 else 0
    }

Beyond basic threshold adjustments:

  • Enable WMM (WiFi Multimedia) for better QoS handling
  • Adjust DTIM period from default 3 to 1 for better roaming
  • Set basic rates to ensure stable fallback speeds

Example enterprise AP configuration:


# Sample enterprise WiFi configuration snippet
wmm_enabled=1
dtim_period=1
basic_rates=12 18 24
supported_rates=6 9 12 18 24 36 48 54
rts_threshold=1400
fragm_threshold=1200