DNS High Memory Utilization – over 1GB of RAM on Physical Domain Controller

First, to save you reading, let me just say – if you have a lot of CPUs on your Domain Controller this is 100% by design (so long as the amount of RAM is stable, otherwise you may have a memory leak of course). If you only have a couple of CPUs – then this scenario doesn’t relate to you, and you’ve got some other strange problem.

I’ve been tempted to delete this article for a while now, since I’ve received so many “wrong wrong wrong” messages – anyway, I’ve decided to leave it here for the sake of completeness as it may actually be of use to some crazy group of people still running ridiculously large Physical Domain Controllers. I’ll spell it out again:

If you are running your Domain Controller(s) as Virtual Server(s), the scenario discussed in this article does not relate to you or your problem. You have some other issue that has nothing to do with the number of Cores/CPUS on your system – but I can tell you that I don’t think changing your socket pool will help you all that much – perhaps read this blog post.

Around the web, everyone seems to be saying words to the effect of “yeah, that’s because of a security update to protect against DNS Spoofing that increased the number of sockets up to around 5000 for DNS – just change your socket pool down to xxxx sockets”. That’s all well and good – but WHY!?

I tried to find an answer to this question and ended up falling down a rabbit hole of circular commentary. Yes, the patch did cause more sockets to be open, and effectively as a result, more memory was allocated to DNS. I wanted to know why so MUCH and only on some of my systems !?

It turns out that buried within this article at Microsoft, there is a statement regarding the amount of RAM DNS will use on a system. What may not be clear about this is that it all depends on how many “CPUs” are present on your system:

By default, the DNS server opens a pool of 5000 UDP sockets: 2500 for 1Pv4 and 2500 for IPv6. On Windows Server 2008 R2, approximately 2.5 KB of memory is allocated for each socket, plus 7.2 KB of memory per receive buffer. The number of receive buffers is two on a single or dual processor server, and equal to the number of CPUs if more than two are present. This means that the DNS server service uses approximately 2.5 x 5000 = 18 MB of additional memory for sockets plus 2 x 5000 x 7.2 = 72 MB for buffers or a total of 90 MB of additional memory on a single or dual processor server when socket pool is used with default settings. Memory use is half the amount if only IPv4 is enabled. To calculate the number of CPUs, open Task Manager and click the Performance tab. A CPU Usage History graph is displayed for each CPU

To save you some time, what this effectively seems to mean is that the more CPUs you have, the more RAM you’re going to chew up. The figures in the statement above talk about a a single or dual processor. Who runs 2 CPUs these days!? (edit: Granted, if you’re running a virtual environment, you might only use 2 vCPUs – if that is the case, you don’t have this problem [as mentioned in the first paragraph] – this scenario these days really relates to those people who still run at least one or two physical Domain controllers for safety – imagine if your lose your entire virtual environment…! I hope that never happens to you.) Anyway, What if we have 32 CPUs/Cores in our Task Manager?

That’s right:

~(2.5kb x 5000 scokets) + (32 cpus/cores x 5000 sockets x 7.2kb )

= (12500kb) + (1152000kb)

= 1164500kb = ~ 1.1GB

More CPUs = MORE RAM FOR DNS!

I have found that this formula roughly equates to the running size and memory utilization of DNS. I hope this helps someone else wondering why DNS is now taking up so much RAM on their otherwise fine Physical Domain Controllers with many CPUs/Cores.

You can reduce the socket pool size.
This will directly affect your memory usage.
However this will make you (somewhat) less protected for DNS Spoofing attacks.
For instance, use a command prompt and execute:
dnscmd /Config /SocketPoolSize 512
You will have to restart DNS to directly release the memory.