From 6c2b3663c0a53a72c407b047dfe7aa76e444d5cc Mon Sep 17 00:00:00 2001 From: Danny Canter Date: Thu, 9 Apr 2026 22:17:00 -0700 Subject: [PATCH] vminitd: Lower nio event loop group threads to 1 The event loop group threads afaict are for ingesting the requests, and then they're fanned out to the Swift concurrency threads. vminitd is at it's heart not very request heavy. It typically does sequential rpcs until the container is up and running, and then all IO happens on vsock ports out of band of grpc entirely. We do not need {core count of guest} threads servicing requests as far as I can see. The real killer is that each thread seems to consume 3MiB of RSS, which causes the overhead of RAM we give to the guest to account for vminitd to be out of whack. It also caused vminitds memory usage to scale with the core count of the guest, which is similarly insane. This change: - Uses 1 thread to service the grpc server - Moves the blocking thread pool which today is used for copy operations down to 2. This does mean you can only do 2 copy operations in parallel, but this does not worry me. - Bumps vminitds overhead to 75. Now, at idle vminitd hovers around 45-50MiB, which still feels a tad high, but much better after {-3*coreCount}MiB which would cause 8 core guests to be in the 70s. Keep our cgroup high memory accounting for vminitd at 75MiB, so now it matches the actual overhead RAM we give. --- Sources/Containerization/LinuxContainer.swift | 6 +++--- vminitd/Sources/vminitd/AgentCommand.swift | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/Containerization/LinuxContainer.swift b/Sources/Containerization/LinuxContainer.swift index 8fa95a45..5ab42583 100644 --- a/Sources/Containerization/LinuxContainer.swift +++ b/Sources/Containerization/LinuxContainer.swift @@ -524,9 +524,9 @@ extension LinuxContainer { // Calculate VM memory with overhead for the guest agent. // The container cgroup limit stays at the requested memory, but the VM - // gets an additional 50MB for the guest agent (could be higher, could be lower - // but this is a decent baseline for now). - let guestAgentOverhead: UInt64 = 50.mib() + // gets an additional 75MiB for the guest agent (could be higher, could + // be lower but this is a decent baseline for now). + let guestAgentOverhead: UInt64 = 75.mib() let mib: UInt64 = 1.mib() let vmMemory = (self.memoryInBytes + guestAgentOverhead + mib - 1) & ~(mib - 1) diff --git a/vminitd/Sources/vminitd/AgentCommand.swift b/vminitd/Sources/vminitd/AgentCommand.swift index 76eb7f78..b361dde2 100644 --- a/vminitd/Sources/vminitd/AgentCommand.swift +++ b/vminitd/Sources/vminitd/AgentCommand.swift @@ -150,8 +150,8 @@ struct AgentCommand: AsyncParsableCommand { } t.start() - let eg = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount) - let blockingPool = NIOThreadPool(numberOfThreads: System.coreCount) + let eg = MultiThreadedEventLoopGroup(numberOfThreads: 1) + let blockingPool = NIOThreadPool(numberOfThreads: 2) blockingPool.start() let server = Initd(log: log, group: eg, blockingPool: blockingPool)