When zones receive frequent DDNS updates (for example from an external DHCP server / kubernetes cluster / etc.), the server’s per-zone change history (_zoneHistory) can grow quickly. During zone persistence the server serializes the entire history and can trigger very large transient memory allocations, potentially resulting in an OutOfMemoryException. This appears as memory leak-like behavior for highly dynamic zones.
This is exaggerated by the default SOA expiry being 1 week.
Context
- I initially noticed the issue when my Technitium DNS container in proxmox was literally stalling the opnsense VM due to I/O stall issues caused by high I/O from the TDNS container.
- I then noticed that the Technitium DNS process was using up all available memory in the container.
- It would start at a few hundred MB, then immediately spiked to over 1GB and keep gradually climbing as it handled requests. Because I have a 2 tier DNS set up in my network (mostly for playing around with DNSSEC), this instance almost exclusively handles IXFR/AXFR/UPDATE requests.
- The OOM was first reached after imposing a systemd cgroup memory limit (
MaxMemory). Without the cgroup limit the process did not immediately crash but memory usage kept increasing as history accumulated (leak-like/unbounded growth).
- Further investigation using copilot to cross reference the stack trace with the codebase resulted in a suggestion that I reduce the SOA expiry.
- Looked at my zone files on disk, the largest zone file was 119MB. Several other less busy zones were using maybe 30-50MB on disk. Compared to my secondary which these zone files were in the KB range.
- I reduced the SOA expiry on busy DHCP-DDNS zones from 1 week to 1 day, this resulted in the zone file on disk shrinking by at least 50% or more.
- Memory usage before: Starting at 1.2GB and kept climbing until it got close to 2GB and got oom-killed due to the capacity of the LXC container it's running in. Enforcing a MaxMemory on it caused it to not get oom-killed, but writing the zone file failed with the exception below.
- Memory usage after: ~500M
- Of note is that the memory usage was several times larger then the zone files on disk, suggesting that the dotnet GC wasn't GC-ing the allocated MemoryStreams fast enough. Might be some opportunity for optimizations here?
- Also out of curiosity, why does the AuthZoneManager buffer zone file writes into memory, then copy it to a temp file, then move the file to the zone file location?
OOM Stack trace:
Aug 21 04:29:20 dns01 dns-server[7845]: [2026-08-20 20:29:20 UTC] System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
Aug 21 04:29:20 dns01 dns-server[7845]: at System.IO.MemoryStream.set_Capacity(Int32 value)
Aug 21 04:29:20 dns01 dns-server[7845]: at System.IO.MemoryStream.EnsureCapacity(Int32 value)
Aug 21 04:29:20 dns01 dns-server[7845]: at System.IO.MemoryStream.Write(ReadOnlySpan`1 buffer)
Aug 21 04:29:20 dns01 dns-server[7845]: at TechnitiumLibrary.Net.Dns.DnsDatagram.SerializeDomainName(ReadOnlySpan`1 domain, Stream s, List`1 domainEntries, Boolean isEmailAddress) in Z:\Technitium\Projects\TechnitiumLibrary\TechnitiumLibrary.Net\Dns\DnsDat>
Aug 21 04:29:20 dns01 dns-server[7845]: at TechnitiumLibrary.Net.Dns.ResourceRecords.DnsResourceRecordData.WriteTo(Stream s, List`1 domainEntries) in Z:\Technitium\Projects\TechnitiumLibrary\TechnitiumLibrary.Net\Dns\ResourceRecords\DnsResourceRecordData.c>
Aug 21 04:29:20 dns01 dns-server[7845]: at DnsServerCore.Dns.Zones.AuthZoneInfo.WriteZoneHistoryTo(IReadOnlyList`1 zoneHistory, BinaryWriter bW) in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\Zones\AuthZoneInfo.cs:line 1023
Aug 21 04:29:20 dns01 dns-server[7845]: at DnsServerCore.Dns.Zones.AuthZoneInfo.WriteTo(BinaryWriter bW) in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\Zones\AuthZoneInfo.cs:line 1215
Aug 21 04:29:20 dns01 dns-server[7845]: at DnsServerCore.Dns.ZoneManagers.AuthZoneManager.WriteZoneTo(String zoneName, Stream s) in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\ZoneManagers\AuthZoneManager.cs:line 586
Aug 21 04:29:20 dns01 dns-server[7845]: at DnsServerCore.Dns.ZoneManagers.AuthZoneManager.SaveZoneFileInternal(String zoneName) in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\ZoneManagers\AuthZoneManager.cs:line 257
Aug 21 04:29:20 dns01 dns-server[7845]: at DnsServerCore.Dns.ZoneManagers.AuthZoneManager.<.ctor>b__23_0(Object state) in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\ZoneManagers\AuthZoneManager.cs:line 97
Just for reference, this is the memory graph of the LXC container over the last day.
And the last week.

When zones receive frequent DDNS updates (for example from an external DHCP server / kubernetes cluster / etc.), the server’s per-zone change history (
_zoneHistory) can grow quickly. During zone persistence the server serializes the entire history and can trigger very large transient memory allocations, potentially resulting in anOutOfMemoryException. This appears as memory leak-like behavior for highly dynamic zones.This is exaggerated by the default SOA expiry being 1 week.
Context
MaxMemory). Without the cgroup limit the process did not immediately crash but memory usage kept increasing as history accumulated (leak-like/unbounded growth).OOM Stack trace:
Just for reference, this is the memory graph of the LXC container over the last day.
And the last week.