{"id":844,"date":"2026-10-06T22:11:59","date_gmt":"2026-10-06T22:11:59","guid":{"rendered":"https:\/\/windows-vps.org\/blog\/?p=844"},"modified":"2026-10-06T22:11:59","modified_gmt":"2026-10-06T22:11:59","slug":"iis-websocket-signalr-connection-limits-windows-server","status":"publish","type":"post","link":"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/","title":{"rendered":"IIS WebSocket vs SignalR Connection Limits on Windows Server"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Real-time features &mdash; chat, dashboards, notifications, live collaboration &mdash; all need a persistent connection, and on Windows Server that means WebSockets. Once you move past a demo, the questions change: how many concurrent sockets can IIS hold, what does SignalR change, and where does the ceiling actually sit? This article covers the architecture, the tuning knobs, and the limits that bite in production, so you can size an instance against reality rather than guesswork.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How IIS Handles WebSockets<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">IIS supports WebSockets through the WebSocket Protocol feature, which runs inside the request pipeline and hands the upgraded connection to the application pool worker process. Each open socket consumes a worker thread only while actively processing, but it holds memory, a connection slot, and kernel-side state for as long as it lives. Two limits govern scale: the connection limits of the Windows HTTP stack (Http.sys) and the resources of the worker process itself.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The upgrade itself is an ordinary HTTP request that asks to switch protocols. If the feature is not installed, the request simply stays a normal HTTP connection and the real-time layer silently fails over &mdash; or breaks. Confirm the feature is present before debugging anything else: <code>Get-WindowsOptionalFeature -Online -FeatureName IIS-WebSockets<\/code> should report Enabled on a host that fronts a real-time app.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">SignalR Does Not Replace the Transport &mdash; It Manages It<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">ASP.NET Core SignalR is an abstraction: it picks the best available transport at runtime, preferring WebSockets and falling back to Server-Sent Events or long polling when sockets are unavailable. That fallback matters on a VPS behind a proxy that strips the upgrade header, but it also means your server must handle all three modes. The practical difference:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Concern<\/th><th>Raw WebSockets<\/th><th>SignalR<\/th><\/tr><\/thead><tbody><tr><td>Protocol handling<\/td><td>You write it<\/td><td>Built in<\/td><\/tr><tr><td>Fallback transport<\/td><td>None<\/td><td>SSE \/ long polling<\/td><\/tr><tr><td>Connection tracking<\/td><td>Manual<\/td><td>Hubs and groups<\/td><\/tr><tr><td>Scale-out<\/td><td>Custom backplane<\/td><td>Redis or Azure SignalR<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The fallback modes are more expensive per client than a socket, because long polling opens repeated short requests. A server sized for 5,000 WebSocket clients may handle far fewer if the proxy forces long polling. Always test with the transport you will actually get, not the one you hope for.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Real Limits and How to Tune Them<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Http.sys connection ceiling<\/strong> &mdash; configured via <code>netsh http<\/code> and app pool settings; raise it deliberately, not blindly.<\/li>\n<li><strong>App pool worker threads<\/strong> &mdash; each active socket may briefly need a thread; starvation appears as rising request queue length.<\/li>\n<li><strong>Memory per connection<\/strong> &mdash; budget a few kB minimum per idle socket; thousands of connections add up fast on a small instance.<\/li>\n<li><strong>Idle timeout<\/strong> &mdash; IIS and load balancers close quiet sockets, so implement application-level keep-alives.<\/li>\n<li><strong>Proxy buffering<\/strong> &mdash; ARR and third-party reverse proxies must be told not to buffer or time out the upgrade.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If you front IIS with ARR, confirm the proxy preserves the <code>Upgrade<\/code> and <code>Connection<\/code> headers and has a generous timeout. A correctly configured WebSocket that dies after 60 seconds is almost always a proxy timeout, not an application bug. Our <a href=\"https:\/\/windows-vps.org\/blog\/iis-url-rewrite-reverse-proxy-setup\/\">IIS reverse proxy guide<\/a> covers the surrounding configuration, including the header rewrite rules that keep the upgrade alive.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Scaling Beyond a Single Instance<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">WebSockets are stateful, which makes them awkward to load-balance. A client&#8217;s socket is bound to one server, so any server-side state (who is in which group, what they have seen) must be shared or externalised. SignalR solves this with a backplane: a Redis pub\/sub channel or the managed Azure SignalR service. Once a backplane is in place you can run multiple IIS nodes behind a load balancer with sticky sessions or, better, a shared connection service.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On a single VPS, the honest way to find your ceiling is to measure. Send a few thousand idle connections from a load-test client and watch worker process memory, thread count, and request queue length. The first metric to bend tells you where to tune next. Repeat after every change so you can attribute the gain to the right knob.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sizing guidance, in rough terms: a 2&nbsp;GB instance comfortably hosts a few hundred to low thousands of idle WebSocket clients, a 4&ndash;8&nbsp;GB instance scales into the low tens of thousands provided the proxy is tuned, and beyond that you should be planning multiple nodes with a backplane rather than a bigger single box. These are starting points for your own measurements, not guarantees &mdash; the only number that matters is the one you observe on your workload.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Checklist for Production Real-Time on IIS<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enable the WebSocket Protocol Windows feature and confirm the handshake returns 101.<\/li>\n<li>Set explicit connection and idle limits rather than relying on defaults.<\/li>\n<li>Verify every proxy in the path preserves the upgrade.<\/li>\n<li>Implement keep-alives and reconnect logic on the client.<\/li>\n<li>Adopt a backplane before you need more than one node.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Bottom Line<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">SignalR is the right default for most .NET real-time work because it manages transport negotiation, fallback, and scale-out for you; raw WebSockets win only when you need total control and have proven the trade-off. Either way, the ceiling on Windows Server is set by Http.sys limits, worker memory, and proxy behaviour &mdash; not by the framework. Size your instance against those realities and real-time features stay smooth. Pick an appropriately sized host via our <a href=\"https:\/\/windows-vps.org\/\">Windows VPS overview<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Real-time features &mdash; chat, dashboards, notifications, live collaboration &mdash; all need a persistent connection, and on Windows Server that means WebSockets. Once you move past a demo, the questions change: how many concurrent sockets can IIS hold, what does SignalR change, and where does the ceiling actually sit? This article covers the architecture, the tuning &#8230; <a title=\"IIS WebSocket vs SignalR Connection Limits on Windows Server\" class=\"read-more\" href=\"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/\" aria-label=\"Read more about IIS WebSocket vs SignalR Connection Limits on Windows Server\">Read more<\/a><\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":2,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-844","post","type-post","status-publish","format-standard","hentry","category-reviews"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>IIS WebSocket vs SignalR Connection Limits on Windows Server - Windows VPS Blog<\/title>\n<meta name=\"description\" content=\"Real-time features &mdash; chat, dashboards, notifications, live collaboration &mdash; all need a persistent connection, and on Windows Server that means\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"IIS WebSocket vs SignalR Connection Limits on Windows Server\" \/>\n<meta property=\"og:description\" content=\"IIS WebSocket vs SignalR Connection Limits on Windows Server\" \/>\n<meta property=\"og:url\" content=\"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/\" \/>\n<meta property=\"og:site_name\" content=\"Windows VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-06T22:11:59+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/\",\"url\":\"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/\",\"name\":\"IIS WebSocket vs SignalR Connection Limits on Windows Server - Windows VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/windows-vps.org\/blog\/#website\"},\"datePublished\":\"2026-10-06T22:11:59+00:00\",\"author\":{\"@id\":\"\"},\"description\":\"Real-time features &mdash; chat, dashboards, notifications, live collaboration &mdash; all need a persistent connection, and on Windows Server that means\",\"breadcrumb\":{\"@id\":\"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/windows-vps.org\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"IIS WebSocket vs SignalR Connection Limits on Windows Server\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/windows-vps.org\/blog\/#website\",\"url\":\"https:\/\/windows-vps.org\/blog\/\",\"name\":\"Windows VPS Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/windows-vps.org\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"IIS WebSocket vs SignalR Connection Limits on Windows Server - Windows VPS Blog","description":"Real-time features &mdash; chat, dashboards, notifications, live collaboration &mdash; all need a persistent connection, and on Windows Server that means","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/","og_locale":"en_US","og_type":"article","og_title":"IIS WebSocket vs SignalR Connection Limits on Windows Server","og_description":"IIS WebSocket vs SignalR Connection Limits on Windows Server","og_url":"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/","og_site_name":"Windows VPS Blog","article_published_time":"2026-10-06T22:11:59+00:00","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/","url":"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/","name":"IIS WebSocket vs SignalR Connection Limits on Windows Server - Windows VPS Blog","isPartOf":{"@id":"https:\/\/windows-vps.org\/blog\/#website"},"datePublished":"2026-10-06T22:11:59+00:00","author":{"@id":""},"description":"Real-time features &mdash; chat, dashboards, notifications, live collaboration &mdash; all need a persistent connection, and on Windows Server that means","breadcrumb":{"@id":"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/windows-vps.org\/blog\/iis-websocket-signalr-connection-limits-windows-server\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/windows-vps.org\/blog\/"},{"@type":"ListItem","position":2,"name":"IIS WebSocket vs SignalR Connection Limits on Windows Server"}]},{"@type":"WebSite","@id":"https:\/\/windows-vps.org\/blog\/#website","url":"https:\/\/windows-vps.org\/blog\/","name":"Windows VPS Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/windows-vps.org\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"_links":{"self":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts\/844","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/comments?post=844"}],"version-history":[{"count":1,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts\/844\/revisions"}],"predecessor-version":[{"id":845,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts\/844\/revisions\/845"}],"wp:attachment":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/media?parent=844"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/categories?post=844"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/tags?post=844"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}