Comparison

View Source

How asobi compares to other game backend platforms.

asobi is one Erlang/OTP node containing the game backend, the Lua runtime and the operator console. There are two front doors into it: run the image (ghcr.io/widgrensit/asobi) and write Lua, or depend on the Hex package and write Erlang. Same node, same features, different surface.

The asobi column is checked against this repository. The other columns are summarised from each vendor's own public documentation (Nakama, Colyseus, PlayFab) and were last read on 2026-08-06. Check them against the vendor before you make a decision on one.

Feature matrix

FeatureasobiNakamaColyseusPlayFab
RuntimeBEAM (Erlang/OTP)GoNode.jsCloud
AuthenticationBuilt-inBuilt-inPluginBuilt-in
Anonymous / guest authBuilt-in, upgradeable, opt-inBuilt-inManualBuilt-in
Player managementBuilt-inBuilt-inManualBuilt-in
Real-time multiplayerWebSocketWebSocketWebSocketWebSocket
Server-authoritative game loopBuilt-in, tick-basedLua / Go / TS runtimeRoom-basedCloudScript
MatchmakingModes plus pluggable strategiesQuery-basedManualBuilt-in
LeaderboardsETS reads, PostgreSQL persistenceBuilt-inManualBuilt-in
Virtual economyWallets, store, inventoryIAP validationManualBuilt-in
Friends / groupsBuilt-inBuilt-inManualBuilt-in
ChatBuilt-in, channels plus DMsBuilt-inManualManual
TournamentsBuilt-inBuilt-inManualManual
Cloud savesBuilt-inStorage APIManualBuilt-in
NotificationsBuilt-inBuilt-inManualBuilt-in
Background jobsShigoto, built-inManualManualScheduled tasks
Custom server-side logicLua callbacks plus extension RPCRuntime modules and RPCsRoom handlersCloudScript
Operator consoleBuilt-in, read-onlyNakama Console, mutatingMonitorGame Manager
DatabasePostgreSQL, Kura ORMPostgreSQL or CockroachDBMongoDB / customManaged
Self-hostedYesYesYesNo

Two rows are worth reading twice.

The console is a React SPA served from priv/console by the same node that serves the game. Core's ops routes are reads apart from erasing and exporting one player; the third mutating route is /api/v1/ops/ext/:extension/:action, whose behaviour comes from an installed extension. So there is no ban, kick, grant, refund or match-end button. Nakama Console and PlayFab Game Manager both mutate; if you are moving from one of those, that is a real gap. See Operator console.

Custom server-side logic that is not per-match goes over the WebSocket as rpc.call with {protocol: 1, method, params}, answered by rpc.ok or rpc.error and correlated by cid. All seven client SDKs speak it. That is the replacement for a Nakama RPC, a PlayFab CloudScript function and a Hathora custom message. See Extensions.

Runtime characteristics

Concernasobi (BEAM)Nakama (Go)Colyseus (Node.js)
Garbage collectionPer-process, isolated per matchStop-the-worldStop-the-world
Fault toleranceOTP supervision, crashed matches restartPanic recovery, manualProcess crash, manual
Live game-logic reloadLua re-evaluated in place on the next tickRestart requiredRestart required
Pub/subpg, cluster-nativeBuilt-in plus optional RedisBuilt-in, single node
In-memory stateETS and process heapsIn-process mapsIn-process objects
ClusteringDistributed Erlang, built inetcd / ConsulRedis, presence only
SchedulingPre-emptive, fair across all processesCooperative goroutinesSingle-threaded event loop

Live reload is a Lua mechanism, not an OTP release upgrade: the runtime stats the script file each tick, and a changed mtime re-executes the script body against the running Luerl state, re-declaring globals and functions while in-flight game state survives. It needs the game directory to be a live mount. asobi ships no appup or relup, so upgrading the node itself is a restart.

Connection density on a single node is 3,000-7,000 concurrent WebSocket connections measured on 8 cores, at 4.4ms p50 round-trip with 3,500 connections. Each connection costs ~13-20KB, so at that concurrency the ceiling is CPU spent on message processing, not memory. Figures and method are in Benchmarks.

When to choose asobi

  • You want a single deployable with auth, matchmaking, economy, social and real-time multiplayer.
  • You need fault-tolerant game sessions that survive crashes without losing state.
  • You want hot-reloadable Lua so bug fixes ship without kicking players.
  • You are building for many simultaneous matches or worlds.
  • You prefer self-hosted Apache-2.0 over a closed managed cloud, with a real exit runbook (see Exit guarantee).
  • You want a PostgreSQL-backed system with a proper ORM.

When to choose something else

  • You need sub-3ms UDP latency for a twitch FPS, fighting game or racer. Pair asobi with a UDP relay, or use a physics-first product for the simulation.
  • You need deep LiveOps tooling (A/B testing, segmentation, push campaigns) today.
  • You need a fully managed cloud at hyperscaler breadth. asobi's managed version is asobi.dev/cloud, which is the same open-source core rather than a different product - invite-only today, and narrower than self-hosting in ways Cloud lists.
  • You are building a single-player game that only needs analytics and IAP. Analytics plus a store validator is cheaper than any backend here.

Clustering

Multiple nodes share Postgres and pg-scoped presence, chat and process lookups. Four things stay node-local and change how you deploy: the matchmaker queue, the rate-limit buckets, the console session store and the player-to-world table - so the console needs a sticky route, players queuing against different nodes never match each other, and a player who reconnects to a different node loses their world with no error. That last one is the only item here a player notices and an operator does not, which is why it belongs in the summary rather than only in the full list. Clustering has the rest.

Client SDKs

Seven first-class SDKs: Godot, Defold, LÖVE, Unity, Unreal, JavaScript/TypeScript and Dart/Flutter. flame_asobi is a Flame bridge on top of the Dart SDK rather than an eighth protocol implementation. The table with guides and demos is in the README.

Migrating from another backend