Websites with Blazor Server (part 2)
Does Blazor Server require too many resources?
Blazor Server is a stateful app framework, meaning the connection from the client to the server needs to be maintained. The current status is stored in the server’s memory, otherwise known as the circuit, for the entire duration of the connection. A simple Hello World app requires roughly 250 kB of memory for each circuit. If 5000 users are connected at the same time, roughly 1.5 GB of memory is required for the app. The more complex the website, the more RAM is required.
Dependency injection frameworks (e.g. Inversion of Control containers) are often used in website development. Dependency injection frameworks manage dependencies between individual app components, making them just as easy to modify even when they get bigger or more complex. The components are generated in different scopes in the process. This includes the application scope, for example, in which a component only exists while the application is running (Singleton) and is used by all requests to the server. With traditional websites, multiple components are created when a request is sent to the server. Once the request has been managed, these components are destroyed, freeing up the required RAM. By contrast, with Blazor Server applications, these components continue to exist as long as the connection to the client is maintained. As a result, the RAM taken up by the components is still occupied after a request has been managed. If required, another development pattern like the service locater pattern may need to be used.
Blazor uses significantly more RAM than stateless web apps. The amount of memory actually required and how many active circuits an app can manage at the same time largely depends on how the app is coded. In light of this, it's a good idea to estimate roughly how many users will need to use the app at the same time and which resources are available at the start of the development stage for a Blazor Server app. If you plan carefully, you hopefully won’t encounter any nasty surprises.
Blazor Server and load balancing— a viable solution?
Establishing a WebSocket connection between the client and server requires multiple HTTP requests to be sent from the client to the server at the start of the initialization stage. SignalR requires that all HTTP requests for this connection are handled by the same server process. Load balancers are used in signal farms (multiple servers) to ensure that all requests are equally distributed to all servers. As a result, it can’t be ensured that HTTP requests are forwarded to the same process. Luckily, session persistence can be used to make sure that all HTTP requests required to establish the SignalR connection are managed by the same server process. Session persistence is often also referred to as sticky sessions or session affinity. Azure App Service uses application request routing (ARR) to forward requests. Sticky sessions can be activated by selecting the ARR affinity option in Azure App Service. Sending messages to clients poses another problem. Each server in a server farm only acknowledges the clients connected to it. Due to this, it isn’t possible to send messages to all clients. Redis backplane offers a handy workaround: If a server wants to send a message to all clients, the message is first sent to the Redis server. The server then forwards the message to all servers in the server farm to ensure that the message is sent to all clients connected to them.
Microsoft recommends using Azure SignalR Service, which is an alternative to the ASP.NET Core proprietary service SignalR. When using Azure SignalR Service, sticky sessions are not required as the clients are immediately forwarded to the service when the connection is established and the service then sends the requests to the right servers. As Azure SignalR Service is aware of all connected clients, it also functions as a backplane. If a server wants to send a message to all clients, it passes it on to SignalR Service, which then forwards the message to the connected clients.
I can highly recommend the video Deploying and Scaling Blazor Server Apps: Carl Franklin's Blazor Train if you want to learn more about scaling.
Blazor is suitable for virtually all areas of application, but truly shines if you require server-client communication with real-time functionality. This often involves applications in the field of business and IoT whereby sales or measurement data need to be provided in real-time. However, Blazor is an equally great option for social media apps, chats and message-based services.