One Windows VPS can comfortably host dozens of websites. IIS was designed for exactly this: a single server splits traffic across multiple sites, each with its own content folder, application pool, and — optionally — its own SSL certificate. The mechanism that makes it work is the binding, the combination of protocol, IP address, port, and host name that tells IIS which site should answer which request. This guide shows how to add a second, third, and tenth site to one VPS using IIS Manager and PowerShell, including HTTPS with SNI.
Before you start stacking sites, check your resources. Each site adds memory for its application pool and bandwidth for its traffic; a 1 GB VPS is fine for two or three small sites, while a busier portfolio wants 4 GB or more. Our comparison table of Windows VPS providers shows RAM, vCPU, and monthly bandwidth per plan, which makes sizing easier.
How bindings and host headers work
Every IIS site has at least one binding in the form IP:Port:HostHeader. When a request arrives, IIS walks all bindings and matches the Host header of the request against the HostHeader part. Two sites can therefore share port 80 on the same IP as long as their host names differ, for example site1.example.com and site2.example.com. If no binding matches, the request falls to the default site (usually the first one created), which is why you should keep a placeholder default site.
Add a site with IIS Manager
- Open IIS Manager (inetmgr) and go to Sites → Add Website…
- Site name: site2; Physical path: D:\sites\site2 (create the folder and grant read access to IIS_IUSRS).
- Binding: Type http, IP address All Unassigned, Port 80, Host name site2.example.com.
- Application pool: leave the default (a new pool is created for you) or pick an existing one.
Repeat for each site. That is the entire process for plain HTTP.
Add a site with PowerShell
New-Website -Name "site2" -PhysicalPath "D:\sites\site2" `
-Port 80 -HostHeader "site2.example.com" -Force
Get-Website | Select-Object Name, State, @{n="Bindings";e={$_.bindings.Collection.bindingInformation}}
To see exactly which host names are bound where:
Get-WebBinding -Name site2 | Select-Object protocol, bindingInformation, sslFlags
HTTPS for many sites on one IP: SNI
With a single public IP, port 443 is shared, so each HTTPS site needs its own certificate and a way to be told apart. That is what SNI (Server Name Indication) does: the client announces the host name during the TLS handshake, and IIS picks the right certificate. SNI works on IIS 8 and later, so every modern Windows Server VPS supports it. Create the HTTPS binding with sslFlags set to 1 (SNI enabled):
New-WebBinding -Name site2 -Protocol https -Port 443 `
-IPAddress "*" -HostHeader "site2.example.com" -SslFlags 1
Then assign the certificate. The easy way is IIS Manager → site2 → Bindings → https binding → Edit → Select… and choose the certificate for site2.example.com. The PowerShell way is:
$cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object Subject -like "*site2.example.com*"
$site = Get-IISSiteBinding -Name site2 -Protocol https
$site.CertificateHash = $cert.Thumbprint
$site.CertificateStoreName = "My"
$site | Set-IISSiteBinding
Alternative: one wildcard certificate (*.example.com) covers every subdomain with a single SNI binding. For sites on unrelated domains, buy one certificate per domain — Let’s Encrypt works fine on IIS via the win-acme tool.
Isolate each site in its own app pool
Separate application pools are what stop one misbehaving site from taking down the others. A crashed worker process (w3wp.exe) recycles only its own pool:
New-WebAppPool -Name "site2_pool"
Set-ItemProperty -Path "IIS:\AppPools\site2_pool" -Name managedRuntimeVersion -Value "v4.0"
Set-ItemProperty -Path "IIS:\Sites\site2" -Name applicationPool -Value "site2_pool"
Start-WebAppPool -Name site2_pool
Set a CPU limit per pool so one noisy site cannot starve its neighbors, and recycle pools periodically to keep memory in check:
Set-ItemProperty -Path "IIS:\AppPools\site2_pool" -Name cpu.limit -Value 50000 # 50%
Set-ItemProperty -Path "IIS:\AppPools\site2_pool" -Name recycling.periodicRestart.requests -Value 5000
Point DNS at the VPS and test
Each host name must resolve to your VPS IP. Add A records at your DNS provider, or on the server itself with Add-DnsServerResourceRecordA if it hosts DNS. To test before DNS propagates, edit the hosts file on a test machine, or test locally from the server:
curl -H "Host: site2.example.com" http://127.0.0.1/
curl -k -H "Host: site2.example.com" https://127.0.0.1/
Common mistakes
- Two sites with identical IP:port and no host header: IIS refuses the second binding with a conflict error — always set the Host name.
- Missing physical path ACL: the app pool identity (IIS AppPool\site2_pool) needs read access (and write, if the app writes) on D:\sites\site2.
- HTTPS without SNI: if sslFlags is 0, IIS serves the default site’s certificate to everyone, and browsers show a name mismatch.
- No default site: an unmatched host name returns 404 instead of your placeholder — keep a catch-all site bound to *:80:.
Wrap up
Hosting several sites on one IIS instance is the fastest way to make a single Windows VPS pay for itself: one license, one firewall rule set, one server to patch. For a plan with enough RAM and bandwidth for the whole portfolio, see the full specs and pricing in our Windows VPS comparison.
If you are running more than a handful of sites, pick a host that does not meter bandwidth aggressively. Hostwinds Windows VPS plans come with generous monthly transfer and full administrative access, so adding site after site never triggers surprise overage bills.



