This document describes how to monitor CPU usage on Catalyst 9800 Wireless LAN Controllers and it covers several configuration recommendations.
Before you delve into CPU load troubleshooting, you must understand the basics of how CPUs are used in Catalyst 9800 Wireless LAN Controllers, and some details on software architecture.
In general, the Catalyst 9800 Best Practices document defines a set of configuration settings that can prevent application-level issues. For example, using location filtering for mDNS or ensuring client exclusion is always enabled. It is advised you apply those recommendations together with the topics exposed here.
Catalyst 9800 controllers were designed as a flexible platform targeting different network loads, and focusing on horizontal scaling. The internal development naming was eWLC with the "e" for elastic, to signify the same software architecture would run from a small single CPU embedded system to multiple CPU/core large-scale appliances.
Each WLC has two distinct sides:
In a simplified view, the controller has communication mechanisms between the control and data plane, punt, sends traffic from the network to the control plane, injection, and pushes frames from the control plane into the network.
As part of a possible high CPU troubleshooting investigation, you must monitor the punt mechanism to evaluate what traffic is reaching the control plane and can lead to a high load.
For the Catalyst 9800 controller, this is running as part of the Cisco Packet Processor (CPP), which is a software framework to develop packet forwarding engines used across multiple products and technologies.
The architecture allows a common feature set across different hardware or software implementations. For example, it allows similar features for 9800CL vs 9800-40 at different throughput scales.
The WLC performs load balancing across CPUs during the CAPWAP AP join process, with the key differentiator being the AP site tag name. The idea is that each AP represents a specific CPU load added, coming from its client activity and the AP itself. There are several mechanisms to perform this balancing:
In general, the default tag can be used on lower load scenarios (for example, less than 40% of AP and client load of the 9800 platform), and for FlexConnect deployment only when fast roaming is not a requirement.
If you have a 9800-40 handling one main office, plus 5 branch offices with different AP counts, the configuration can look like this:
wireless tag site office-main
load 120
wireless tag site branch-1
load 10
wireless tag site branch-2
load 12
wireless tag site branch-3
load 45
wireless tag site branch-4
load 80
wireless tag site branch-5
load 5
In this scenario, you do not want the main office tag to be on the same WNCD as branch-3 and branch-4. There are 6 site tags in total and the platform has 5 WNCDs and there is a chance the highest loaded site tags land on the same CPU. By running the load command, you can create a predictable AP load balancing topology.
The load command is an expected size. It does not need to match the AP count exactly, however, it is normally set to the expected APs that can join.
For hardware platforms, the WNCD count is fixed: 9800-40 has 5, 9800-80 has 8. For 9800CL (virtual), the number of WNCDs depends on the virtual machine template used during the initial deployment.
As a general rule, if you want to find determine how many WNCDs are running in the system, you can run this command across all controller types:
9800-40#show processes cpu platform sorted | count wncd
Number of lines which match regexp = 5
In the case of 9800-CL, you can run the show platform software system all command to collect details on the virtual platform:
9800cl-1#show platform software system all
Controller Details:
=================
VM Template: small
Throughput Profile: low
AP Scale: 1000
Client Scale: 10000
WNCD instances: 1
The AP to WNCD assignment is applied during the AP CAPWAP join process and it is not expected to change during operations, regardless of the balancing method. Unless, there is a network-wide CAPWAP reset event where all APs disconnect and re-join.
Running the CLI show wireless loadbalance tag affinity command can provide an easy way to view the current state of the AP load balance across all WNCD instances:
98001#show wireless loadbalance tag affinity
Tag Tag type No of AP's Joined Load Config Wncd Instance
---------------------------------------------------------------------------------------------
Branch-tag SITE TAG 10 0 0
Main-tag SITE TAG 200 0 1
default-site-tag SITE TAG 1 NA 2
If you want to correlate the AP distribution against client count and CPU load, you can use the WCAE support tool and load a show tech wireless taken during busy times. The tool summarizes the WNCD client count, taken from each AP that is associated with it.
This is an example of a properly balanced controller, during low usage and client count:

Another example is for a more loaded controller, showing normal CPU utilization:

In short, you can summarize the different options in:
This 500 AP threshold, is to mark when it is effective to apply the load balancing mechanism, as it groups APs in blocks of 100 units by default.
There are scenarios where you can apply advanced AP balancing, and it is desirable to have granular control on how APs are spread across CPUs. For example, very high-density scenarios where the key load metric is client count versus focusing on the number of APs present in the system.
A good example of this situation is large events where a building can host thousands of clients over several hundred APs, and you need to split the load across as many CPUs as possible, but optimize roaming at the same time. You do not roam across WNCD unless it is needed. You want to prevent situations where multiple APs in different WNCDs/site tags are intermixed in the same physical location.
To help fine tune and provide a visualization of the distribution, you can use the WCAE tool and take advantage of the AP RF View feature:

This allows you to view the AP/WNCD distribution, just set the View Type to WNCD. Each color represents a WNCD/CPU and you can set the RSSI filter to -85 to avoid low signal connections. These are also filtered by the RRM algorithm in the controller.
In the previous example, corresponding to Ciscolive EMEA 24, you can see most adjacent APs are clustered across the same WNCD with very limited cross-overlapping. Site tags allocated to the same WNCD receive the same color.
It is important to remember the concept of Cisco IOS XE architecture and keep in mind there are two main views of CPU usage. One comes from historical Cisco IOS support, and the main one with a holistic view of the CPU across all processes and cores.
In general, you can run the command show processes cpu platform sorted to collect detailed information for all processes across Cisco IOS XE:
9800cl-1#show processes cpu platform sorted
CPU utilization for five seconds: 8%, one minute: 14%, five minutes: 11%
Core 0: CPU utilization for five seconds: 6%, one minute: 11%, five minutes: 5%
Core 1: CPU utilization for five seconds: 2%, one minute: 8%, five minutes: 5%
Core 2: CPU utilization for five seconds: 4%, one minute: 12%, five minutes: 12%
Core 3: CPU utilization for five seconds: 19%, one minute: 23%, five minutes: 24%
Pid PPid 5Sec 1Min 5Min Status Size Name
--------------------------------------------------------------------------------
19953 19514 44% 44% 44% S 190880 ucode_pkt_PPE0
28947 8857 3% 10% 4% S 1268696 linux_iosd-imag
19503 19034 3% 3% 3% S 247332 fman_fp_image
30839 2 0% 0% 0% I 0 kworker/0:0
30330 30319 0% 0% 0% S 5660 nginx
30329 30319 0% 1% 0% S 20136 nginx
30319 30224 0% 0% 0% S 12480 nginx
30263 1 0% 0% 0% S 4024 rotee
30224 8413 0% 0% 0% S 4600 pman
30106 2 0% 0% 0% I 0 kworker/u11:0
30002 2 0% 0% 0% S 0 SarIosdMond
29918 29917 0% 0% 0% S 1648 inet_gethost
There are several key points to highlight:
Pid PPid 5Sec 1Min 5Min Status Size Name
--------------------------------------------------------------------------------
19371 19355 62% 83% 20% R 128120 smand
27624 27617 53% 59% 59% S 1120656 pubd
4192 4123 11% 5% 4% S 1485604 linux_iosd-imag
Pid PPid 5Sec 1Min 5Min Status Size Name
--------------------------------------------------------------------------------
21094 21086 25% 25% 25% S 978116 wncd_0
21757 21743 21% 20% 20% R 1146384 wncd_4
22480 22465 18% 18% 18% S 1152496 wncd_7
22015 21998 18% 17% 17% S 840720 wncd_5
21209 21201 16% 18% 18% S 779292 wncd_1
21528 21520 14% 15% 14% S 926528 wncd_3
9800cl-1#show processes cpu sorted
CPU utilization for five seconds: 2%/0%; one minute: 3%; five minutes: 3%
PID Runtime(ms) Invoked uSecs 5Sec 1Min 5Min TTY Process
215 81 88 920 1.51% 0.12% 0.02% 1 SSH Process
673 164441 7262624 22 0.07% 0.00% 0.00% 0 SBC main process
137 2264141 225095413 10 0.07% 0.04% 0.05% 0 L2 LISP Punt Pro
133 534184 21515771 24 0.07% 0.04% 0.04% 0 IOSXE-RP Punt Se
474 1184139 56733445 20 0.07% 0.03% 0.00% 0 MMA DB TIMER
5 0 1 0 0.00% 0.00% 0.00% 0 CTS SGACL db cor
6 0 1 0 0.00% 0.00% 0.00% 0 Retransmission o
2 198433 726367 273 0.00% 0.00% 0.00% 0 Load Meter
7 0 1 0 0.00% 0.00% 0.00% 0 IPC ISSU Dispatc
10 3254791 586076 5553 0.00% 0.11% 0.07% 0 Check heaps
4 57 15 3800 0.00% 0.00% 0.00% 0 RF Slave Main Th
8 0 1 0 0.00% 0.00% 0.00% 0 EDDRI_MAIN

This is available on the Monitoring/System/CPU Utilization tab.
The process list varies depending on the controller model and the Cisco IOS XE version. This is a list of some key processes and it is not intended to cover all possible entries.
| Process Name |
What Does It Do |
Evaluation |
| wncd_x |
Handles most wireless operations. Depending on the 9800 model, you can have between 1 to 8 instances. |
You can see peaks of high utilization during busy hours. Report if the utilization is stuck for 95% or more for several minutes. |
| linux_iosd-imag |
Cisco IOS Process |
Expect to see high utilization if collecting large CLI output (show tech). Large or too frequent SNMP operations can lead to high CPU. |
| nginx |
Web Server |
This process can show peaks and can only be reported on a sustained high load. |
| ucode_pkt_PPE0 |
Data Plane in 9800CL/9800L |
Run the command show platform hardware chassis active qfp datapath utilization to monitor this component. |
| ezman |
Chipset Manager for Interfaces |
A sustained high CPU can indicate either a HW issue or a possible kernel software problem (it can be reported.) |
| dbm |
Database Manager |
A sustained high CPU here can be reported. |
| odm_X |
Operation Data Manager handles consolidated DB across processes |
High CPU expected on loaded systems. |
| rogued |
Handles Rogue Functionality |
A sustained high CPU here can be reported. |
| smand |
Shell Manager takes care of CLI parsing, and interaction across different processes. |
High CPU expected when handling large CLI output. Sustained high CPU in the absence of load can be reported. |
| emd |
Shell Manager - Handles CLI parsing, and interactions across different processes |
High CPU expected when handling large CLI output. Sustained high CPU on the absence of load can be reported. |
| pubd |
Part of Telemetry handling |
High CPU expected for large telemetry subscriptions. Sustained high CPU on the absence of load can be reported. |
Catalyst 9800 Wireless LAN Controllers have extensive protection mechanisms around network or wireless client activity to prevent high CPU due to accidental or intentional scenarios. There are several key features designed to help contain problematic devices:
This is enabled by default, and is part of Wireless Protection Policies, and it can be enabled or disabled per Policy Profile. This can detect several different behavior issues, remove the client from the network, and set it into a temporary exclusion list. While the client is on this excluded state, the APs do not talk to them, preventing any further actions.
After the exclusion timer has passed (60 seconds by default), the client is allowed to associate again.
There are several triggers for client exclusion:
Client exclusion protects your controller, AP, and AAA infrastructure (Radius) from several high activity types that can lead to high CPU. It is not advisable to disable any exclusion methods unless required for a troubleshooting exercise or compatibility requirement.
The default settings operate for almost all cases and only on some exceptional scenarios are required to increase the exclusion time or disable some specific trigger(s). For example, some legacy or specialized clients (IOT/Medical) must have the association failure trigger to be disabled, due to client-side defects that cannot be easily patched
You can customize the triggers in the UI: Configuration/Wireless Protection/Client Exclusion Policies:

The ARP Exclusion trigger was designed to be permanently enabled at a global level, however, it can be customized on each policy profile. You can check the status by running the sh wireless profile policy all command and look for this specific output:
ARP Activity Limit
Exclusion : ENABLED
PPS : 100
Burst Interval : 5
This is an advanced mechanism in the Data Plane to ensure traffic sent to the Control Plane does not exceed a predefined set of thresholds. This feature is called Punt Policers and in almost all scenarios, it is not necessary to touch them, and even then, only must be used when working with Cisco Support.
The advantage of this protection is it provides detailed insight into the network, and if there is any specific activity that has an increased rate, or unexpected high packets per second.
This is only exposed through CLI, as they are normally part of advanced functionality that rarely needs modification.
To receive a view of all punt policies:
9800-l#show platform software punt-policer
Per Punt-Cause Policer Configuration and Packet Counters
Punt Config Rate(pps) Conform Packets Dropped Packets Config Burst(pkts) Config Alert
Cause Description Normal High Normal High Normal High Normal High Normal High
-------------------------------------------------------------------------------------------------------------------------------------------------------------
2 IPv4 Options 874 655 0 0 0 0 874 655 Off Off
3 Layer2 control and legacy 8738 2185 33 0 0 0 8738 2185 Off Off
4 PPP Control 437 1000 0 0 0 0 437 1000 Off Off
5 CLNS IS-IS Control 8738 2185 0 0 0 0 8738 2185 Off Off
6 HDLC keepalives 437 1000 0 0 0 0 437 1000 Off Off
7 ARP request or response 437 1000 0 330176 0 0 437 1000 Off Off
8 Reverse ARP request or repso 437 1000 0 24 0 0 437 1000 Off Off
9 Frame-relay LMI Control 437 1000 0 0 0 0 437 1000 Off Off
10 Incomplete adjacency 437 1000 0 0 0 0 437 1000 Off Off
11 For-us data 40000 5000 442919246 203771 0 0 40000 5000 Off Off
12 Mcast Directly Connected Sou 437 1000 0 0 0 0 437 1000 Off Off
This can be a large list with more than 160 entries, depending on the software version. On the table output, check the dropped packet column along with any entry that has a non-zero value on the high drop count. To simplify the data collection, you can run the show platform software punt-policer drop-only command to filter for only policer entries with drops.
This feature can be useful to identify if there are ARP storms or 802.11 probe floods (they use queue 802.11 Packets to LFTS and LFTS stands for Linux Forwarding Transport Service.)
In all recent maintenance releases, the controller has an activity monitor to dynamically react to high CPU, and ensure AP CAPWAP tunnels remain active in the face of unsustainable pressure. This feature checks on the WNCD load and starts throttling new client activity to ensure enough resources remain available to handle existing connections and to protect CAPWAP stability. This is enabled by default and it does not have configuration options.
There are three levels of protection defined, L1 at 80% load, L2 at 85% load, and L3 at 89%. Each one triggering different incoming protocol drops as protection mechanisms. The protection is automatically removed as soon as the load decreases.
In a healthy network, you cannot see L2 or L3 load events and if they happen frequently, it can be investigated.
To monitor, run the command wireless stats cac:
9800-l# show wireless stats cac
WIRESLESS CAC STATISTICS
---------------------------------------------
L1 CPU Threshold: 80 L2 CPU Threshold: 85 L3 CPU Threshold: 89
Total Number of CAC throttle due to IP Learn: 0
Total Number of CAC throttle due to AAA: 0
Total Number of CAC throttle due to Mobility Discovery: 0
Total Number of CAC throttle due to IPC: 0
CPU Throttle Stats
L1-Assoc-Drop: 0 L2-Assoc-Drop: 0 L3-Assoc-Drop: 0
L1-Reassoc-Drop: 0 L2-Reassoc-Drop: 0 L3-Reassoc-Drop: 0
L1-Probe-Drop: 12231 L2-Probe-Drop: 11608 L3-Probe-Drop: 93240
L1-RFID-Drop: 0 L2-RFID-Drop: 0 L3-RFID-Drop: 0
L1-MDNS-Drop: 0 L2-MDNS-Drop: 0 L3-MDNS-Drop: 0
mDNS as a protocol allows a zero-touch approach to discover services across devices, but at the same time, it can be very active, and drive load significantly if not configured properly.
mDNS, without any filtering, can easily increase WNCD CPU utilization, coming from several factors:
You can check mDNS list size per service by running this command:
9800-l# show mdns-sd service statistics
Service Name Service Count
-----------------------------------------------------------------------------
_ipp._tcp.local 84
_ipps._tcp.local 52
_raop._tcp.local 950
_airplay._tcp.local 988
_printer._tcp.local 13
_googlerpc._tcp.local 12
_googlecast._tcp.local 70
_googlezone._tcp.local 37
_home-sharing._tcp.local 7
_cups._sub._ipp._tcp.local 26
This can provide an idea of how large any given query can get. It does not denote a problem by itself, just a way to monitor what is tracked. There are some important mDNS configuration recommendations:
9800-1(config)# mdns-sd gateway
9800-1(config-mdns-sd)# transport ipv4
By default, it uses IPv4 transport and for performance, it is advisable to use either IPv6 or IPv4, but not both.
If you see high CPU load and none of the previous steps help, contact Customer Experience (CX) through a case and add this data as starting point:
show tech-support wireless
request platform software trace archive last <days> to-file bootflash:<archive file>
| Revision | Publish Date | Comments |
|---|---|---|
3.0 |
03-Aug-2026
|
Updated Introduction, spelling, grammar, inserted horizontal lines to separate sections/readability, fixed CCW errors. |
2.0 |
06-Jun-2025
|
Updated Alt Text, Style Requirements, Machine Translation, Branding Requirements, and Formatting to Comply with Cisco's Guidelines for Externalization |
1.0 |
09-May-2024
|
Initial Release |