Runtime & limits
Your app runs around the clock on dedicated compute. No cold starts, no request timeouts.
Apps run as long-lived processes, not serverless functions. Your process can run indefinitely, hold connections open, and do background work. There are no cold starts and no request timeouts.
Always on
On every plan, your app runs 24/7. It doesn't sleep between requests, and it restarts itself if it crashes. This is true on the free plan too.
App size: CPU and memory
You buy compute and split it across as many apps as you want. Each app gets a size you choose, and CPU rides with memory, so there's one knob, not two. Every account starts with a free 256 MB of compute. Buy more for $5 a month per 512 MB and the choices look like this:
| App size | CPU | Good for |
|---|---|---|
| 256 MB (free) | 0.25 vCPU | A test or preview app. Start here. |
| 512 MB | 0.5 vCPU | A Python cron job or a small script. |
| 1 GB | 1 vCPU | A Node API with light traffic. |
| 2 GB | 2 vCPU | A small Go service. |
| 4 GB | 4 vCPU | A heavier app, or more traffic. |
See pricing for the full breakdown. There's no limit on the number of apps, only on how much compute you've bought, so you can split the pool across many apps or give all of it to one. If an app is bumping against its memory or CPU, the dashboard shows it live (see Logs & monitoring) and you can resize it in one click from its Size tab.
Need more than 4 GB for one app? Write to [email protected] and we will size it with you.
Network access
Every app has full outbound internet on every plan: LLM APIs, third-party services, package registries, anything reachable over HTTPS. Apps are isolated from each other and can't reach other tenants' apps. That isolation is enforced at the network layer, not left to your config.
WebSockets and streaming responses
WebSockets and server-sent events work on every app, on its normal
https:// address, with nothing to set up. Listen on
$PORT as usual and upgrade the connection in your code.
Quiet connections stay open. Measured on a public app on 2 October 2026: a WebSocket with no traffic at all stayed open for 10 minutes, a WebSocket sending a small message every 25 seconds stayed open for an hour, and an event stream with one event every 30 seconds ran for 30 minutes without a gap.
On a private app, a WebSocket with no traffic in either direction for 5 minutes is closed.
A deploy or a restart closes open connections, and so can routine platform maintenance. Two habits cover all of it:
- Send a ping every 30 seconds on a long-lived WebSocket.
-
Reconnect when a connection closes, with a short
backoff. The browser's
EventSourcedoes this for event streams on its own; for WebSockets, add it to your client.
Variables Dockhold injects
These are set for you in every app. Read them; don't define them.
PORT # the port your app must listen on, on 0.0.0.0
DATABASE_URL # set when the managed database add-on is on
On top of those, you get any plain variables you set in the dashboard and any secrets you connected to the app. See Environment variables & secrets.