The Web Garden ModelThe Web garden model is configurable through the section of the machine.config file. Notice that the section is the only configuration section that cannot be placed in an application-specific web.config file. This means that the Web garden mode applies to all applications running on the machine. However, by using the node in the machine.config source, you can adapt machine-wide settings on a per-application basis.
Two attributes in the section affect the Web garden model. They are webGarden and cpuMask. The webGarden attribute takes a Boolean value that indicates whether or not multiple worker processes (one per each affinitized CPU) have to be used. The attribute is set to false by default. The cpuMask attribute stores a DWORD value whose binary representation provides a bit mask for the CPUs that are eligible to run the ASP.NET worker process. The default value is -1 (0xFFFFFF), which means that all available CPUs can be used. The contents of the cpuMask attribute is ignored when the webGarden attribute is false. The cpuMask attribute also sets an upper bound to the number of copies of aspnet_wp.exe that are running.
Web gardening enables multiple worker processes to run at the same time. However, you should note that all processes will have their own copy of application state, in-process session state, ASP.NET cache, static data, and all that is needed to run applications. When the Web garden mode is enabled, the ASP.NET ISAPI launches as many worker processes as there are CPUs, each a full clone of the next (and each affinitized with the corresponding CPU). To balance the workload, incoming requests are partitioned among running processes in a round-robin manner. Worker processes get recycled as in the single processor case. Note that ASP.NET inherits any CPU usage restriction from the operating system and doesn't include any custom semantics for doing this.
All in all, the Web garden model is not necessarily a big win for all applications. The more stateful applications are, the more they risk to pay in terms of real performance. Working data is stored in blocks of shared memory so that any changes entered by a process are immediately visible to others. However, for the time it takes to service a request, working data is copied in the context of the process. Each worker process, therefore, will handle its own copy of working data, and the more stateful the application, the higher the cost in performance. In this context, careful and savvy application benchmarking is an absolute must.