Recently, I helped with a project to replace some older domain controllers (2012) with newer ones (2022).
We began experiencing issues with DNS shortly after said migration, which later turned out to be related to a network issue; however we spent the first few hours health checking and examining the new DCs.
One thing that was immediately noticed was that the DNS server was taking up what appeared to be a very large amount of RAM, even on DCs that were not actively referenced for DNS by client devices or servers.
Compared to the previous generation which was only using about 450mb of RAM, the new DCs were using 1.2gb of RAM for the “dns.exe” service.
We began to search for reasons why this would be taking place, and unfortunately set us back awhile as we couldn’t rule out the new DCs as the source of the DNS issue being experienced.
Most of the articles that I discovered talked about how the Socket Pool Size (like this one) could influence RAM usage, but they were from a timeframe from a decade ago and mostly related to Server 2008.
I did play with the socket pool size setting in the registry which came out as part of a 2008 security update intended to randomize the UDP source port in order to preventing DNS spoofing; while it did bring RAM usage down, I still felt it was strange that I was seeing 2.5x higher usage from old to new.
Short history lesson / side note: back in the day, it was extremely common for all UDP protocols to use the same source and destination port instead of having the source port be a random ephemeral port. Since UDP is session-less there was no need to create a unique socket for every outgoing connection because there was no session… UDP packets in and out. Thus if you looked in the Firewall logs, you would see a DNS query has source and destination port as UDP-53. This made it easy to spoof because you could just start sending UDP responses to a firewall on that port for common web addresses and it would cause those DNS servers to accept the result they got back. It would only be successful for a query that happened to be already triggered first, but if you spoof DNS responses long enough you’re bound to be able to poison a query for a common site like microsoft.com or google.com. Thus, an improvement was made to force UDP to act like TCP with respect to DNS, where the connection would come from a random source port, so bad actors had to guess between several thousand ports which ones were active and then spoof all of them. Additionally, firewalls have also gotten better at detecting outbound UDP “sessions” and only allowing the response traffic if a request was made from the internal first. Anyhow, the setting that controls the number of source ports is this SocketPoolSize query. You can’t define the range that they squat on, as it is reserved during bootup time from whatever is available, but it does come out of the ephemeral port range that is defined on your servers (since 2008, the default range is 49152-65535).
Back to the topic at hand… I played with the socket pool size but was still unable to get my DNS server down to a reasonable RAM usage size. Mind you these DCs had the physical hardware capability to run a 1.2gb DNS server in memory, but it bothered me it was so high. Plus, the previous domain controllers were the same make and model servers and I never had to tweak that setting. Or wait? Were they?
Recall the old usage was around 450-500mb and new usage is 1.1-1.2gb. I lined up everything – drivers, firmware, whatever came to mind in order to find a hardware difference. Same amount of RAM, HDD, but wait! CPU was different – I had forgotten to check that earlier.
I saw that the new DCs had 40 logical processors and the old had 16. Something went off in my brain and I noticed the numbers aligning. So I pulled out the calculator and did some math:
500mb/1200mb = .40 = 40%
16 processors / 40 processors = .40 = 40%
The amount of CPU had to be proportional to the DNS server usage.
I tried proving this by setting a processor affinity on the DNS.exe service, but when I rebooted the settings didn’t stick. I decided rather than playing with that to just set up a Windows DNS service on a test VM I had. I played with the assigned RAM in VMware. Every amount of RAM I allotted influenced the memory usage of the DNS.exe service.
I also went back to playing with the SocketPoolSize registry setting and observed that dropping the amount of sockets by 50% cut the RAM usage exactly 50%.
So now knowing that two factors define memory usage on a Windows DC’s DNS service – SocketPoolSize and RAM.
Here is the formula that I arrived at:
RAM usage for a Windows AD/DNS’s dns.exe service = SocketPoolSize Value * Processor Count * 12.5kb
To simplify this, let us define some variables and a constant:
R = variable: RAM usage of DNS.exe
S = variable: SocketPoolSize value (default: 2500)
P = variable: Logical Processor Count*
C = constant: represents the amount of RAM that a single socket and a single processor consumes
R = S*P*C
*you can find it from running in PowerShell: “(gwmi win32_processor).numberoflogicalprocessors”
So in the end, the amount of RAM being unused did not turn out to be problematic; it was just shocking because I had never seen that much usage before on a DNS process (even in a large environment with caching). There is a lot of bad and subjective advice on this topic online, so tread carefully there. I wrote this article to help the next guy (or gal) so they don’t get stuck for several hours trying to investigate something that is perfectly normal.
Important note: I used the value of Logical Processors for my formula, but I did not test the impact of hyperthreading on the RAM usage. So if your Logical Processor Count is double the count of Total Number of Cores, your results may vary. If I have some time, I will try experimenting with hyperthreading to see if doubling the the number of logical processors (which is what hyperthreading does when the system permits it) also doubles the amount of RAM that DNS.exe uses. I would guess that it does, but I cannot say for sure without testing.
#dns #dns.exe #windowsdns #windowsactivedirectory #activedirectorydns #addns #highramusage #dnstakesupalot ofram #highdnsmemory