In this video, we'll compare HTTP vs. WebSockets: what's the difference between these two protocols and how they are typically used? Also, we'll create a simple benchmark to illustrate the differences in practice and why you may want to choose one or the other. We'll measure latency, the requests per second each server can handle, network usage, CPU, and memory. When we think about HTTP, we usually think of the common request-response model, where you have a server and a client. When you need to get any data, you would send a request and get a reply from the server with the data. Now, when it comes to WebSockets, we usually think of it as a mechanism for real-time applications and streaming of data. For example, you can stream price data or monitoring data and visualize it on the dashboard. It can be used in live chat applications. The server can push data to the client without the client having to explicitly request every piece of data. WebSockets also enable full-duplex communication, which means the client and server can send data to each other simultaneously over the same connection. Well, you can stream data using HTTP polling, and you can use WebSockets in a request-response model as well. Now, when you use HTTP, you first need to establish a connection with a server and perform a TLS handshake if you use HTTPS. After that, you send a request to the server and get a reply from the server with the requested data. If you need to send another request, you need to establish a connection again and send the request. When it comes to WebSockets, you only need to establish a connection and perform a handshake once, and your connection will be kept open. If you just stream data, you don’t even need to send a request, but frequently, we still need to authorize our client first. And if you use WebSockets in a request-response model, you don’t need to terminate the connection and establish a new one after every single request. Now, many crypto exchanges actually allow you to submit orders using WebSockets exactly because it is more efficient. So, for HTTP, we’ll send a request to the server with all those headers and verbs and the JSON payload, and the server will parse the data, register our order, and return it back to the client again with a bunch of headers. On WebSockets, when we send a request, we only send a JSON payload and no headers whatsoever, and the server replies with a JSON payload as well without headers, using the same TCP connection. So, from this simple example, you can see that using HTTP creates a lot of overhead: not only do you need to perform a handshake for every single request, but also you send back and forth the same headers again and again. In WebSockets, there is no additional overhead; the network usage is much smaller. I run all my tests on AWS just to make it more realistic and created an EKS cluster with taints and affinity to properly distribute my clients and applications on their own nodes. For example, I pin each HTTP and WebSocket server to its own node and use a bunch of clients as Kubernetes jobs to simulate the traffic. Alright, let’s go ahead and run the test. I used the same uWebSockets framework to create both HTTP and WebSockets servers; that way, the framework itself would not play a role in the performance of each application. And of course, I used C++, and you can find the source code in my public GitHub repository. Alright, first we’ll start with around 2,000 requests per second. To measure latency, when I create a request, I generate a timestamp and send that timestamp to the client, and after the client parses the request, it sends back that timestamp. So, in each case, I measure the round-trip duration of each request, and I use Prometheus to calculate the p90 percentile and visualize it in Grafana. And you can see that, as expected, WebSockets have lower latency, but when you send a request over a network or even over the internet, the difference is not as big as you might think. The biggest overhead is actually network usage; all those headers create much more traffic than simply sending a JSON payload, as with WebSockets. Alright, let me run this test for 1 more minute while increasing the load on each server, and we’ll go over each graph at the end of the test.
Segment 2 (05:00 - 07:00)
First, we have latency, and as you would expect, WebSockets perform better just because they have lower overhead compared to stateless HTTP requests. Next, we have requests per second, and both servers can handle a similar amount of requests—around 90 requests per second for a single-threaded application—which means each server only uses 1 CPU core. Next, we have network usage, where I measure how many bytes every server receives, and here is actually the biggest difference. And if you host your applications on AWS or any other public cloud, you know that you have to pay for network data transfer, and by switching to WebSockets, you potentially can reduce the infrastructure bill. Next, we have CPU usage, and there is no significant difference between these two applications, as well as memory usage. To summarize, WebSockets are a little bit more efficient in terms of latency, but the biggest difference is in how much extra data you need to send with each HTTP request compared to WebSockets. In the following video, we’ll compare WebSockets and gRPC.