Why Serverless WebSockets Need a Connection Database
Cortlet is a software brand specailizing in: Lightweight, secure-first, no-bloat, problem-solving, and balance of opensource and closed source software.
WebSockets sound simple at first.
A client connects.
It sends messages.
The server sends messages back.
But once you combine WebSockets with serverless infrastructure, one question appears almost immediately:
Where do you store the active connections?
That is where a lot of the complexity starts.
A traditional server can remember connections
With a long-running WebSocket server, active connections can often live in memory.
Conceptually, the server can keep something like:
user_123 → connection_abc
As long as that server process stays alive, it knows which connection belongs to which user.
If the backend wants to send a message to user_123, it already knows where to send it.
Serverless changes that.
Serverless functions do not stay around
A serverless function is usually created to handle an event, run some code, return a result, and disappear.
The next event may run on a completely different instance.
That means a function cannot safely rely on in-memory connection state.
If one function handles a WebSocket connection event and another function later needs to send data back to that client, the second function needs some way to know:
which connection belongs to that user
whether the connection is still active
where that connection is hosted
whether it has already disconnected
The connection state has to live somewhere else.
This is where a database enters the picture
A common serverless WebSocket setup looks roughly like this:
Client → WebSocket Gateway → Serverless Function → Connection Database
When a client connects, the backend stores the connection ID.
When the client disconnects, the backend removes it.
When the backend wants to send data later, it first looks up the connection ID and then sends the message through the WebSocket gateway.
So a simple realtime feature can become:
accept the connection
generate or receive a connection ID
store the connection ID
map it to a user or session
look it up later
send the message
clean it up on disconnect
handle stale entries when disconnect events fail
The database is not storing application data.
It is storing infrastructure state.
Why this feels strange
Databases are usually introduced because the application needs durable data.
Users.
Orders.
Messages.
Sessions.
But in a serverless WebSocket architecture, developers may end up adding a database table simply to answer:
“Which socket is this user connected to?”
That creates extra code, extra reads and writes, extra failure cases, and extra infrastructure.
The realtime feature may be small.
The connection-management layer is not.
Disconnects make it harder
Connection tracking also depends on knowing when a client is gone.
That sounds straightforward, but WebSocket disconnects are not always clean.
A browser may close suddenly.
A laptop may lose Wi-Fi.
A mobile device may switch networks.
A process may crash.
If the disconnect event is delayed or never arrives, the database can still contain a connection that no longer exists.
Now the application needs cleanup logic.
It may need retries, TTLs, heartbeat checks, or stale-connection detection.
The problem grows beyond simply storing an ID.
The backend starts managing transport state
This is the part that matters.
The application backend is no longer only handling business logic.
It is now managing the state of the transport layer.
That means developers start writing code for things like:
connection registration
connection lookup
disconnect cleanup
stale connection detection
retry logic
connection-to-user mappings
That is infrastructure work created by the mismatch between persistent WebSockets and stateless compute.
What if the gateway owned the connection state?
Another model is to move this responsibility into the WebSocket layer itself.
For example:
Client → WebSocket Gateway → HTTP Webhook → Serverless Backend
The gateway already owns the persistent connection.
So it could also own the connection identity and lifecycle.
The backend would receive ordinary HTTP events containing the information it needs, without having to build a separate connection-tracking system first.
That is one of the ideas behind Cortlet.
Instead of asking every serverless application to rebuild the same connection-management layer, the gateway could handle that state once.
The bigger problem is not the database
A connection database is not inherently bad.
For many applications, it is completely reasonable.
The issue is that developers often need one because their compute layer cannot retain connection state itself.
That means every realtime feature inherits an additional architectural responsibility.
The real question is:
Should every serverless developer have to manage WebSocket connection state themselves?
That is the part we think is worth rethinking.