Network Sockets

What is a socket?

When most developers think of communications over the web they likely start and stop with HTTP. If you want to achieve better performance you have to go deeper.

First, let's get to know the OSI model. For our concerns of thinking about how things work across the internet we can start at Layer 4, the Transport Layer. This is where communications are exchanged between different networks, and it's also where network sockets live.

To think of a network socket let's think of a highway. Cars and trucks driving on that highway are the equivalent of network packets and where they originate and stop are places with addresses. Once one of these cars gets to its destination it must determine where in the parking lot to park, which would be the equivalent of a network port if each parking space were uniquely numbered.

The next layer of the OSI model is the Session Layer, which determines things like availability, access, and connection establishment. Continuing to use our highway analogy an example of the session layer will specify where guests are allowed to park, any restrictions for entry, and what types of business are authorized.

The sixth layer of the OSI model is the Presentation Layer, which determines what data should look like or how it should be formatted. This layer of the model is often ignored unless specified. Email, for example, has a separate specification for data presentation set apart from the protocol specification.

The final layer of the OSI model is the Application Layer. HTTP is an application layer protocol that uses a text-based header whose syntax is largely based upon the presentation definitions specified for email headers, originally RFC822.

When we think about communicating at the socket level we are more concerned with the ability to establish a connection than the information that travels upon that connection.

Why bother?

The strength of HTTP is its flexibility. HTTP is what's considered connection-less. This means an HTTP transmission does not require prior connection establishment and the server does not know or care who the client is. This saves a lot of headaches that come with connection establishment criteria, but it also comes at a cost because its slow and insecure.

The connection-less nature of HTTP means a dedicated socket is created for each single message exchange and then torn down once the server sends its response. There are exceptions to this, such as the HTTP 1.1 keep-alive header and various aspects of HTTP revisions 2 and 3, but for the most part each separate HTTP message get its own temporary dedicated socket. That is expensive from a network perspective as it takes time to create and destroy sockets. In many cases it takes more time than just performing a small message exchange.

The security aspect of a connection-less protocol is also quite complex. In most cases HTTP must be assisted with additional technologies to apply security in the most basic of forms. Some of these additional technologies may include cookies, server-side session management, sandboxes, single origin policies, and much more.

Security is generally more straight forward for network sockets that make use of access and authorization criteria baked into the connection step as all such negotiations occur only once, separate and unrelated from any data that will traverse the socket. This is also faster, because the performance hit for socket establishment occurs once for all messages that will traverse the socket.

Let's go deeper...

So yeah, dedicated network sockets are maybe a little bit faster and have some cheaper security. In performance testing my Aphorio application I found I could perform about 100 HTTP 1.1 transmissions per second. This includes socket creation, message transmission, awaiting the response, and then socket destruction in a synchronous fasion. That same application is able to send about 5,000,000 WebSocket messages per second including socket creation, message transmission, response message received, and then socket destruction once all responses are counted. That is a performance difference of 50,000 times.

The difference in practice is actually much more significant than that 50,000 times difference due to down stream consequences. System resources are not spent separately securing or rejecting each message, for example. Let's think about this in terms of traffic redirection. Traffic redirection generally occurs in one of two ways.

  1. A response message is sent indicating the source or client should direct their network messaging elsewhere, such as a HTTP 301 response. This is like a road way detour where a driver receives directions to drive somewhere else because their planned route is not available.
  2. A network application moves the traffic automatically, such as a proxy or DNS relay. This is actually more common than you might think. In fact you were likely redirected multiple times just to read this blog from the third party DNS provider and at least one or two more times at the web server.

These series of redirections occur for each network socket. They actually occur for each message sent on each socket, but I will get to that in a little bit. Each time a traffic redirection occurs the time to receive the message grows longer, which is called latency.

Dedicated sockets on a well configured applications, or series of applications, are much more efficient about this. For example a socket level proxy in Node.js is as simple as: socket.pipe(proxy);proxy.pipe(socket); This operation shifts data from one socket on the network buffer to another socket on the network buffer without populating additional artifacts in memory, which is fast and invisible to everybody except the application executing those instructions.

What does this mean?

Understanding communications at the socket level allows for transmission management that is faster, cheaper, more secure, and requires less effort to scale across a network. For existing applications this shift can be extremely challenging like transitioning from an automobile to an airplane for transportation. The goods still get to the destination, but making the change requires new processes and conventions, like hiring pilots and building an airport.

Additional benefits from communications at the socket level allows for applications to do more with their network traffic than merely send and receive. As I mentioned above many web applications require a series of proxies to move network data between network locations, encryption schemes, protocols, and more. In most cases those proxies are dedicated application instances each with a large dedicated configuration per traffic classification. That is more expensive to maintain and execute as well as labor intensive to modify. Thinking at the socket level relieves much of this burden by allowing internalization of these proxies into a series of simple rules. In the Aphorio application, for example, a proxy is as simple as an array of 3 values.

Due to the differences in scale, costs, and labor it may be a challenge to convert an existing application from a legacy approach to a socket based approach that is fully management. Yet, the costs are so staggeringly different its really the difference between hand writing each network message on paper for a mail carrier to deliver opposed to streaming over the internet.