How to monitor LDAP,NTLM,Kerberos to your domain controllers ?

Troubleshooting high LSASS CPU ?

DC fails logons or experiences LDAP timeouts:

Tips and tricks:

  • Identify missing subnets and add them on dssite.msc
  • Add more CPU and RAM on domain controllers
  • Move to 2012 R2 domain controllers
  • Disable Netbios on the DC but this may not be an option for everyone, so the site subnet mapping or DNS name resolution should also fix this kind of an issue.
  • Educate developers to perform the right LDAP queries
  • Configure client applications properly (ldap filters)
  • We have seen the LDAP ATQ threads get depleted at a customer due to high volume of LDAP clients using NTLM for authentication. These were overloading the Netlogon service, ran into MaxConcurrentApi bottleneck.
  • By default there are 4 threads per processor allocated to the LDAP thread pool, we can change that via LDAP policies, specifically MaxPoolThreads: MaxPoolThreads = Maximum number of threads created by the domain controller for query execution (4 per processor). Set to 8 per proc.

Enable LDAP query logging using NTDS diagnostic values:

with PowerShell script:

Basically, you want to set the following registry values:

Path: HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics\15 Field Engineering
Value: 5

Path: HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters\Expensive Search Results Threshold
Value: 10000  (decimal – default value)

Path: HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters\Inefficient Search Results Threshold
Value: 1000  (decimal – default value)

Path: HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters\Search Time Threshold
Value: 30000  (decimal – defaut value in milliseconds)


Expensive LDAP calls are the searches those visit large number of entries. Default threshold for expensive search is 10,000 which means if an LDAP call visit 10,000 or more entries then it will be consider as an expensive call. Once you find such call in logs, you can figure out possible solutions to optimize it. For example a query (displayName=*John*) on root domain container will visit all objects in the domain those have any value available in displayName attribute and it will be consider an expensive call if there are 10,000 or plus such objects those have displayName attribute populated.

Inefficient LDAP calls are the searches those return less than 10% of visited entries. For example, if a query visit 10,000 entries in active directory but only return 100 entries then it will be consider inefficient query as return entries are less than 10% of total visited entries. Default visited entries threshold limit for inefficient query is 1,000 which means if a query visit less than 1000 entries then it will not be consider inefficient query even though if it return no entry.

Search Time Threshold, is available only if 2012 R2 DC or after you install the KB 2800945 installed on Server 2012, Server 2008 R2 or Server 2008 domain controllers. By default the value is 30000 milliseconds = 30 seconds ! too long and I recommend to set up to 5000 (5 secs)

These registry changes do not require a reboot but are set per server, so implementing for an entire forest/domain would best be done via Group Policy Preferences. Once set you will find the resulting logs in the Directory Service event log on the DC. They are not exactly parse-friendly but can be wrangled with some regex. The best part is it requires no external utilities/code. Because it is very verbose, don’t forget to remove those values after audit phase.

Which Tools to help?

Creating More Efficient Active Directory-Enabled Applications:

Web Resources: : Debugging And Performance Tuning With ETW : creating Data Collector Sets