Guide
When to Use Ports
A Port is an isolated App instance on its own dedicated RemoteEvent. Use one when you need complete namespace isolation between game systems.
App routes vs Ports
| App routes | Ports | |
|---|---|---|
| RemoteEvent count | 1 | 1 per Port |
| Namespace | Shared | all routes on same remote | Isolated | each system on its own remote |
| Token bucket | Shared per App | Separate per Port |
| Middleware | Shared | Separate |
| Push/Broadcast | Same channel | Separate channel |
| Use for | Most things | Distinct systems: shop, combat, admin |
RemoteEvent limit. Roblox enforces a cap on RemoteEvents per place. Don't create a Port per route. A Port is for an entire system | combat, shop, admin | not for each individual action.
Structure
-- server — ports are created via app:Listen
local app = RoExpress("App")
app:Listen("combat", function(port) -- creates own RemoteEvent
port:Post("hit", hitHandler)
port:Post("reload", reloadHandler)
end)
app:Listen("shop", function(port) -- creates own RemoteEvent
port:Get("catalogue", catalogueHandler)
port:Post("buy", buyHandler)
end, { Max = 20, Refill = 5 }) -- optional rate-limit override
-- client — connect via RoExpress("Network", portName)
local combatNet = RoExpress("Network", "combat")
local shopNet = RoExpress("Network", "shop")
combatNet:Post("hit", hitData)
shopNet:Get("catalogue", nil, function(res) ... end)
When you need a Port
- Two systems that should never share rate limiting (e.g. combat and chat)
- A system with completely separate middleware that would interfere with other routes
- A system handled by a different team | clean contract boundary
When you don't need a Port
- Just want to organise routes into logical groups | use route prefixes:
"shop/buy","combat/hit" - Only one of the systems will ever run | just use App
See also
Port API · App | single-remote baseline · TokenBucket | rate limiting per Port · Middleware | per-Port middleware setup