In IIS, what is an application pool, and how does it relate to the w3wp.exe worker process that actually runs your web application?
answer
- the unit of isolation, not the site
- one worker process per pool
- kernel queue, then a process is started
- identity, recycling and pipeline live here
- w3wp.exe -ap "PoolName"
basics
~20 sAn IIS application pool is the isolation boundary for one or more web applications. IIS runs each pool in its own w3wp.exe worker process, so a crash, a recycle, or an identity change affects only the applications assigned to that pool.
solid answer
~40 sAn application pool is a named configuration object in IIS that defines a process boundary: it carries the identity the code runs as, the managed pipeline mode (Integrated or Classic), the .NET CLR version, 32- vs 64-bit, recycling rules and the idle time-out. Requests are accepted in the kernel by HTTP.sys and queued per pool; the Windows Process Activation Service starts a `w3wp.exe` worker process for that pool on demand, and that process loads the IIS modules and executes your application. The mapping people get wrong is that it is one worker per *pool*, not per site — a single site's applications can sit in different pools, and one pool can host applications from several sites. Everything sharing a pool shares its memory, its identity and its crash.
go deeper
Be able to say plainly that the application pool is the configuration for a worker process, that IIS runs one w3wp.exe per pool, and that applications sharing a pool share its fate.
Explain the HTTP.sys queue, WAS starting the worker on demand, and which settings live on the pool rather than the site — identity, pipeline mode, CLR version, bitness, recycling.
Show that you reason about blast radius: which applications share a process, what a memory-limit recycle or a crash takes down with it, and the memory cost of splitting pools for isolation.
Own the hosting-density trade for a whole fleet — how many pools per server, when isolation justifies the per-worker memory overhead, and when the answer is to stop co-hosting on IIS at all.
## The three layers behind one request IIS is not a single process. A request to an IIS-hosted application passes through three distinct pieces before any of your code runs. **HTTP.sys** is a kernel-mode driver that owns the TCP ports. It listens, parses the request line and headers, matches the URL against the set of registered URL prefixes, and places the request into a *request queue*. There is one request queue per application pool. Because HTTP.sys is in the kernel, it can accept connections and even serve cached responses while no user-mode process for that application is running at all. **WAS** — the Windows Process Activation Service — watches those queues. When a request lands in a queue that has no worker process behind it, WAS starts one. The World Wide Web Publishing Service (W3SVC) sits alongside it and owns the HTTP-specific configuration, handing the port and prefix registrations to HTTP.sys. **w3wp.exe** is the worker process. It loads the native IIS modules, loads the CLR if the application is managed, and runs your request pipeline. This is the process you attach a debugger to, the process that shows up in Task Manager eating memory, and the process that dies when your application faults. ## What the pool actually owns The application pool is the configuration object that describes that worker process. Its settings live in `applicationHost.config` under `<applicationPools>`: ```xml <add name="ContosoPool" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated" enable32BitAppOnWin64="false"> <processModel identityType="ApplicationPoolIdentity" idleTimeout="00:20:00" /> <recycling><periodicRestart time="1.05:00:00" /></recycling> </add> ``` The pool decides: the **identity** the code runs as (and therefore every file, share and database it can reach); the **managed pipeline mode**, Integrated or Classic, which decides whether managed modules see every request or only ASP.NET-mapped ones; the **CLR version**, including the value `No Managed Code` used for ASP.NET Core; **bitness**; **recycling** rules and the **idle time-out**; **rapid-fail protection**; and the request **queue length**. ## Sites, applications, and pools are three different things A **site** is a set of bindings (protocol, IP, port, host name) plus a root application. An **application** is a virtual path such as `/shop` mapped to a physical directory, and every application is assigned to exactly one application pool. A **virtual directory** is just a path alias inside an application and has no process of its own. That means the relationship is many-to-many in the useful direction: one site can spread its applications across several pools, and one pool can host applications drawn from several sites. Counting worker processes by counting sites is the classic beginner error. ## One process per pool — with two exceptions By default a running pool has exactly one `w3wp.exe`. Two things change that. A **web garden** (`maxProcesses` greater than 1) runs several workers for the same pool; requests are spread across them, which breaks any in-memory session or cache and is rarely the right answer today. And during an **overlapped recycle** you briefly see two workers for one pool while the new one warms up and the old one drains. To see the mapping live, `appcmd list wp` prints each running worker with its pool, and the worker's own command line carries `-ap "PoolName"`, which is why adding the Command Line column in Task Manager tells you instantly which pool a hungry `w3wp.exe` belongs to. ## Why the boundary is the point Everything in one pool shares one address space. An unhandled exception that takes down the process takes down every application in that pool. A memory-limit recycle triggered by one leaky application discards the in-memory caches and sessions of its neighbours. The identity is shared, so granting one application write access to a folder grants it to all of them. A stuck thread pool starves them all. Conversely, separating applications into their own pools buys real isolation at the cost of memory: each additional worker process carries its own CLR, its own JIT-compiled code and its own caches, typically tens to a couple of hundred megabytes before your application allocates anything. One consequence worth memorising for diagnosis: if a pool is stopped — either manually or by rapid-fail protection after repeated startup failures — HTTP.sys still accepts the connection and answers **503 Service Unavailable**, not 404. A 503 that appears instantly, with nothing at all in the application's own logs, almost always means the request never reached a worker process.
- If the application pool is stopped, what does a client actually get back, and why?A 503 Service Unavailable, returned almost instantly. HTTP.sys accepts the connection in the kernel and finds the pool's request queue disabled or with no worker behind it, so it answers itself. Nothing reaches your code, which is why the application log is silent — you look in the System event log and at the pool's state instead.
- What is a web garden in IIS, and why is it usually a bad idea?Setting an application pool's maximum worker processes above one runs several `w3wp.exe` instances for the same pool, with requests spread across them. It sidesteps nothing that matters on modern hardware — a single worker already uses all cores — while multiplying memory and destroying any in-process session state or cache, since consecutive requests from one user can land in different processes.
- What is the practical difference between Integrated and Classic managed pipeline mode?In Integrated mode the managed modules are merged into the single IIS pipeline, so ASP.NET modules such as authentication and rewriting see every request, including static files. Classic mode reproduces the old ISAPI behaviour: managed code runs only for extensions mapped to ASP.NET. Classic exists for legacy applications whose configuration or module assumptions break under Integrated.
saying these in an interview costs you the question
- Says IIS starts one w3wp.exe per website
- Treats application pool and website as the same object
- Thinks IIS itself executes the managed application code
- Assumes two apps in one pool are isolated from each other
- Expects 404 rather than 503 when a pool is stopped