As a senior developer at Microsoft, you often find yourself participating on a number of v-teams. One of the v-teams I’m on is responsible for approving new services added to Windows. As I’ve mentioned before, I’m a nutcase about stuff running on my machines, and services are absolutely among the things I care about passionately. As a part of my work on that v-team, I wrote this little bit up a couple of years ago (it’s been edited slightly to remove proprietary information):
I’ve been sitting watching the <new services v-team> process for a couple of months now, and I’ve seen a number of trends that concern me.
Every single new feature (and it seems like there have been thousands of new features) seems to require its own service to perform operations. Don’t get me wrong – it’s wonderful that these functions are running as services and not as separate processes.
But every single one of the new services that I see being requested is enabled on all SKUs of Windows. All of them, it seems. And they’re all auto-start.
The <new services v-team> has done a terrific job of reducing the number of own-process services that are running. That’s truly awesome, and it’s great for our customers.
But I don’t think that they’re going far enough. We need to take a harder line on our services. Because even if multiple services are hosted in a single process, they each still burns at least one thread. And that thread consumes working set. And it affects startup time. And if your code has memory (or GDI/User object) leaks, it can render computers unusable. The other thing to consider is that every running service in Windows increases the Windows attack surface.
In Windows XP, we had 40ish services on a running system. We’ve got almost twice that on a default Vista install these days (assuming my test machine is a default longhorn install).
Now I appreciate that everyone’s feature is critical for their customers, but I’m wondering if they’re all necessary for all customers. Do you REALLY believe that your code is going to be used by every single one of the nearly a billion users of Windows? Is your service going to make every single one of those billion people’s lives better? If your service isn’t, then maybe every one of those billion people don’t need to be running your code.
As I’ve said, I’ve been thinking about this for a while, and I think I’ve got a few things that should be considered when you’re trying to figure out if your service really needs to be installed.
First off, I know that your feature is the most important thing you’re doing, but that’s true for every single one of the developers working on the Windows product. We can’t all be number one, so think very seriously about the relative importance of your feature.
If your service is auto-start, is it REALLY necessary? Will every user of Windows achieve positive benefits from your service?
If your service is tied to a piece of hardware, does your service need to be running if the hardware isn’t present? Can you tie the service to the installer for your hardware?
If your service is tied to a particular UI, and the user never invokes your UI, is your service doing the user any good? Can your UI start the service if it’s not running?
Does your service REALLY need to be enabled and auto-start (even auto-start-delay) on every SKU? Really?
How is your feature/service discoverable? If your feature isn’t easily discoverable, does the service that supports that feature really have to be run until the user discovers your feature and starts to use it?
Now for some services this is clearly the case. But for a huge number of the services that we’ve been coming up with, it’s equally clearly not.
Even my own service, Windows Audio doesn’t meet all of these criteria. I’d be more than willing to have the service be manual start unless there’s an audio card present, and to change the installer for audio adapters to enable the service. Because on a machine without audio hardware, there’s no point in the service running until the hardware arrives. There IS one important scenario where it’s important to have the Windows Audio service running: that’s Remote Desktop – when running a remote desktop, even if the server doesn’t have audio hardware, we can still play audio using the TS client’s audio hardware.
But that’s a relatively weak scenario. And I’d be willing to change it (or work to change the remote desktop service to ensure that the audio service is started when a client connects). Are you?
This all is a bit of a digression – it’s not about mitigations, it’s about the hard decisions you should make when thinking about adding services, but it’s worth publishing anyway.
So how do you mitigate services? First off, combine like services into a single process. That way, instead of taking two processes, you only consume one process (see my earlier post where I listed the costs of a process).
Secondly, as I indicated above, consider making your service a manual start service that’s triggered by some UI action. Unless there’s a real need for your service to be running all the time, let the UI (or an API if your service surfaces an API) start your service.
Third, seriously consider making your service a delayed auto-start service – this is functionality new in Vista/Windows Server 2K8 that allows the service controller to delay starting your service so it doesn’t interfere with boot time.
In addition, seriously consider how much time you spend in your service’s start routine. The less time the better (especially if you’re an auto-start service). The less work you can do before reporting that your service has started to the service controller, the faster the system will boot.
Tomorrow: Applet best practices – collecting the thoughts of the previous several posts into a single post.
 Please note: While there ARE more services in Vista than in XP, this comment is mostly hyperbole.
 This didn’t happen, the powers that be decided that since every workstation class machine with a Vista logo had to have an audio solution that it was ok to keep the audio service as an auto-start service (they also felt that audio was going to be used by every one of those users 🙂
 Yeah, I know – it’s a vista-only mitigation, but it’s a good one.