Sites and apps
WebSocket hosting for a chat, an online game or live updates
In short
WebSocket needs hosting where the server runs continuously and keeps long-lived connections open, instead of starting up for one short request. A chat, an online game or a live feed should listen on 0.0.0.0 and the port from the PORT variable, while the browser connects over a secure wss:// address and reconnects after a drop. On platforms like Netrun WebSocket works through the same HTTPS link as the website, with no server setup. For anything that must stay online all the time, choose the Pro plan.
- A WebSocket connection starts as a regular HTTP request with an Upgrade header and stays open until one side closes it.
- A page opened over HTTPS can only connect to a wss:// address, because the browser blocks plain ws:// as mixed content.
- The WebSocket built into the browser does not reconnect after a drop by itself, while the Socket.IO client does it automatically.
- Uvicorn accepts WebSocket connections only when the websockets or wsproto package is installed, for example through uvicorn[standard].
- WebSocket support in Vercel Functions is in beta, and a connection closes when the function reaches its maximum duration.
A regular website answers a request and forgets about the visitor. A chat, an online game, a board showing other people's cursors or a live order feed needs something else: a connection that stays open so the server can push a new message the moment it appears. That is what WebSocket is for. The code takes an evening to write, and the trouble starts when you publish it: it worked locally, but on the host the connection never opens or drops every few minutes.
The cause is almost never the code itself but where and how it runs. Short serverless functions are built for quick replies, a browser on an HTTPS page refuses an insecure connection, and a server listening only on localhost is not visible from outside at all, as explained in the guide on an app listening on localhost. Below is what a WebSocket app needs from hosting and how to prepare the code.
| Criterion | Serverless functions | Platform with a long-running process | Your own VPS |
|---|---|---|---|
| How the code runs | A function starts per request and then exits | One program runs continuously | A program runs continuously, and you set up everything around it |
| Long-lived connections | Closed at the function duration limit, if supported at all | Stay open while the process runs | Stay open while the process runs |
| Rooms and participants in memory | A new connection may land on another instance, so you need an external store like Redis | One process sees every participant | One process sees every participant |
| wss:// address and certificate | Provided by the platform | An HTTPS link is issued right away, and wss:// works through it | You configure the proxy and certificate yourself |
| What you do | Rewrite the server for the function model | Upload the code, listen on 0.0.0.0 and PORT | Install the OS, proxy, autostart and updates |
| Best for | Short sessions in a project that already lives on that platform | Chats, games, live dashboards and notifications | Unusual workloads that need full control of the machine |
Run the server as a long-running program#
A WebSocket server is a program that runs all the time and keeps every participant connection open. FastAPI with uvicorn, Node.js with the ws library, Socket.IO, Flask-SocketIO or Go all work. For FastAPI, make sure requirements.txt includes uvicorn[standard] or the websockets package: without them uvicorn serves normal requests but rejects WebSocket connections.
Listen on 0.0.0.0 and the port from PORT#
The server must listen on 0.0.0.0 and on the port from the PORT environment variable. WebSocket does not need a separate port: it runs on the same port and the same link as your web pages, and only the path differs, for example /ws. If the code hardcodes localhost or a separate socket port, nobody can reach it from outside.
Connect over wss:// on the same address#
A page opened over HTTPS can only connect to a wss:// address. Do not hardcode localhost and a port number in the client: build the address from the current page address, so the same build works on your machine and on the host. If the page and the server live on different addresses, the server has to allow connections from the page address.
Add reconnects and a ping#
The connection will drop sooner or later: a phone switches networks, a laptop sleeps, the server gets updated. The WebSocket built into the browser does not reconnect on its own, so add a reconnect with a growing delay and request the current state again after it. The Socket.IO client reconnects by itself. Many proxies close idle connections, so it helps to send a short ping every thirty seconds or so.
Do not keep important data only in memory#
A list of room participants can live in process memory, but message history, game scores and orders cannot: memory is wiped on a code update or restart. Save them to a database, for example SQLite in the persistent /data folder or PostgreSQL as a separate service. Also run the server as a single worker process: several processes have separate memory, and people in the same room stop seeing each other.
Publish and test from two tabs#
On Netrun you upload the code as an archive, a folder or from GitHub, the language and start command are detected automatically, and you get an HTTPS link that WebSocket works through as well. Open the app in two tabs or on two devices and send a message: it should appear in both. If it does not, open the live project logs and the browser console to see whether the connection reached the server.
A WebSocket app needs little, but without compromises: an always-running process, an HTTPS address for wss:// and a client that survives drops. On Netrun you get all of that from ordinary code, with no proxy or certificate setup, plus live logs and automatic restarts after a crash. The free plan is handy for checking that connections open and messages get through. If your chat, game or dashboard has to stay online all the time, go with Pro. Try Netrun.
Common questions
Why does my WebSocket work locally but not on the host?
Most often the client connects to ws://localhost or to a hardcoded port, while on the host it needs the wss:// address of the same link as the site. The second cause is a server listening on 127.0.0.1 instead of 0.0.0.0. For FastAPI, check one more thing: uvicorn[standard] or the websockets package must be in your dependencies.
Can I run WebSocket on Vercel or another serverless host?
Vercel WebSocket support is currently in beta: a connection closes when the function reaches its maximum duration, and new connections may land on a different instance, so shared rooms have to live in an external store. That works for short sessions. For a chat or a game where people stay for hours, an always-running server is simpler.
Does WebSocket need a separate port?
No. A WebSocket connection starts as a regular HTTP request and runs on the same port and the same link as the site. It usually gets its own path, such as /ws or /socket.io, while the server listens on a single port from the PORT variable.
Should I use Socket.IO or plain WebSocket?
Socket.IO gives you rooms, automatic reconnects and a fallback over regular requests, but it needs its own client on both ends. Plain WebSocket is a browser standard, lighter and usable from any language, but you write reconnects yourself. For a chat with rooms Socket.IO is more convenient, and for a simple live feed plain WebSocket is enough.
Why do people in the same room not see each other's messages?
Most often the server runs several worker processes, and each one has its own list of connections in memory. A message only reaches people connected to the same process. Run the server as a single process, or pass messages between processes through a shared store like Redis.
How do I put a website online?
Upload your site code as a ZIP archive or from GitHub — Netrun builds it and gives you a working link with HTTPS. A static site (HTML, CSS, JS), a React app or a Python site all work. There is no domain to buy and no server or certificates to set up.
Is my data kept when I update the code?
Yes, as long as your data lives in persistent storage. For a regular project that is the /data folder: anything your app saves there stays in place when you update the code or restart, and you can browse and download the files on the "Data" tab. If you described the services yourself in docker-compose, persistent storage means the named volumes from your file, and such a project has no /data folder. Files written outside persistent storage are created from scratch on the next deploy. Your project link stays the same either way.
What is different about the Pro plan?
On the Pro plan your project runs around the clock: a website does not sleep and responds instantly, with no pause to wake up, while a bot or a background script keeps running with no time limit. On top of that, Pro gives more memory, CPU and disk space, and a Pro website can use your own domains — as many as you need, each with HTTPS.