Source: https://gameye.com/agones-migration/

---
title: "Agones to Gameye Migration Guide"
description: "Moving off Agones? Keep your container, remove the Agones SDK calls, replace GameServerAllocation with one POST /session call, and stop running Kubernetes clusters for your game servers."
---

Migration Guide

# Agones to Gameye migration guide

Your game server already runs in a container. Moving to Gameye means removing the Agones SDK calls, swapping GameServerAllocation for one API call, and handing the clusters, fleets and autoscalers to Gameye.

Same container No SDK No Kubernetes 6 steps

Updated November 13, 2026

📦

Built for Agones? Your image is the starting point.

Agones runs each game server as a container in a Kubernetes Pod. Gameye runs each match as one Linux container. The server build inside the image stays. The code change is taking out the Agones SDK.

[Jump to the migration steps →](#path)

Agones is an open-source project that adds game server resources to Kubernetes: GameServer, Fleet, GameServerAllocation and FleetAutoscaler. It is a sound choice for studios that want to run their own clusters. Running it means you also own the clusters, the node pools in every region, the Agones and Kubernetes upgrades, and the on-call rota.

On Gameye you keep the game server and the matchmaker. You stop operating the layer underneath them. If you are still deciding whether to self-host, read [Run Agones yourself or use managed hosting?](https://gameye.com/blog/agones-self-hosted-vs-managed/) first.

What changes

- Agones SDK calls (`Ready`, `Health`, `Shutdown`, and `Allocate` if you use it) come out of the server
- `GameServerAllocation` becomes `POST /session`
- GameServer port specs become ports on a Gameye application
- Your image goes to Docker Hub or GitHub Container Registry, with a new tag per build
- Fleets, FleetAutoscalers and clusters are no longer yours to run

What stays the same

- Your dedicated server build and netcode
- Your matchmaker and its rules
- Clients still receive an IP and port
- Match config passed as args or environment variables
- `SIGTERM` handling for a clean shutdown

## Where does the cost difference come from?

Agones is free software. The bill comes from what it runs on and who runs it. These are the lines that go away or change when you move.

Idle nodes

A Fleet keeps Ready game servers waiting on nodes you pay for, and a Buffer policy keeps that headroom on purpose. On Gameye you start a session when a match forms, and billing stops when the container exits.

Cloud egress

On a managed Kubernetes service, outbound game traffic is billed by your cloud provider per gigabyte. Gameye includes bandwidth in its [published pricing](https://gameye.com/pricing/).

Cluster engineering

Each Agones release supports three Kubernetes versions, so cluster upgrades and Agones upgrades are planned together, in every region you run. Someone also owns autoscaler tuning, allocation services and on-call. On Gameye none of that sits with your team.

Regions

Adding a region on Agones means another cluster with its own node pools and allocation endpoint. On Gameye a region is a `location` value in the session request.

For a worked cost comparison of self-run Agones and Gameye, see the [Gameye vs Agones cost breakdown](https://gameye.com/gameye-vs-agones/#tco). For current rates, see [Gameye pricing](https://gameye.com/pricing/). Agones facts on this page were checked against agones.dev on November 13, 2026.

## What does the migration path look like?

1
Push your image where Gameye can pull it

Gameye pulls images from Docker Hub or GitHub Container Registry. Push the same Linux x86-64 server image you deploy to Agones, create a Gameye application for it, and give Gameye read access. Gameye does not host a registry, so you keep using your own.

Use a new tag for every build, such as a build number or commit SHA. Nodes that already have a tag do not download it again, so re-pushing `latest` will not deliver a new build.

[Getting started in Gameye Docs →](https://gameye.com/docs/getting-started/)

2
Remove the Agones SDK calls

On Agones, your server talks to the SDK server that runs alongside it in the Pod. Take those calls out:

- `SDK.Ready()`: remove. A Gameye session is running once `POST /session` returns.
- `SDK.Health()` ping loop: remove. Gameye does not expect health pings.
- `SDK.Shutdown()`: replace with a normal process exit. When the server process exits, the session ends and billing stops.
- `SDK.Allocate()`, if your server self-allocates: remove. Your backend starts the session instead.

Keep your `SIGTERM` handler. When your backend calls `DELETE /session/{id}` or a session's `ttl` runs out, Gameye sends `SIGTERM`, then `SIGKILL` if the process is still running 50 seconds later. Save results and logs in that window, then exit.

The engine guides show the shutdown path for each engine: [Unreal](https://gameye.com/docs/guides/integrations/unreal/), [Unity](https://gameye.com/docs/guides/integrations/unity/) and [Godot](https://gameye.com/docs/guides/integrations/godot/).

3
Declare your ports on the application

The `ports` list in your GameServer spec becomes the ports on your Gameye application: a protocol and a container port, for example UDP 7777.

- **Bridge networking** (the default) is closest to the Agones `Dynamic` port policy. Your server listens on a fixed container port and Gameye maps it to a free host port.
- **Host networking** is closest to `Passthrough`. Your server reads its assigned port at startup from a variable such as `GAMEYE_PORT_UDP_7777` and listens on it.

Gameye sets the port variables in both modes, along with `GAMEYE_IP`, `GAMEYE_REGION` and `GAMEYE_CONTAINER`, so a server that advertises its own address can still do so.

[Container environment variables →](https://gameye.com/docs/guides/using-gameye/using-variables/)

4
Replace GameServerAllocation with POST /session

Wherever your backend or matchmaker creates a `GameServerAllocation`, it calls the Gameye API instead. The response carries the address and ports, like the allocation status does.

Before (Agones)

```
apiVersion: allocation.agones.dev/v1
kind: GameServerAllocation
spec:
selectors:
- matchLabels:
agones.dev/fleet: my-fleet
# status: state Allocated, gameServerName, address, ports
```

After (Gameye)

```
POST /session
{ "image": "my-game-server", "version": "build-142",
"location": "europe", "env": { "MAX_PLAYERS": "16" },
"labels": { "match": "m-8812" }, "ttl": "1h" }

201 Created
{ "id": "...", "host": "203.0.113.42",
"ports": [{ "type": "udp", "container": 7777, "host": 49152 }] }
```

Match settings you put in GameServer labels, annotations or container args carry over to `labels`, `env` and `args`. Do not put secrets in `env`: the values are visible to anyone with Admin Panel access.

[POST /session reference →](https://gameye.com/docs/api-v2/reference/post-session/) · [Custom matchmaker guide →](https://gameye.com/docs/guides/integrations/custom-matchmaker/)

5
Pick regions per session

Instead of one cluster per region, you choose a region on each request. For a single-region game, pass a fixed `location`. For a global game, call `GET /available-location/{image}` to get the regions where your image is available and an IP for each, have clients ping those IPs, and start the session in the region with the best result for the match.

[Region selection guide →](https://gameye.com/docs/guides/using-gameye/region-selection/)

6
Track players, then move traffic

If you count connected players, report them from your backend with `PUT /session/player/join` and `DELETE /session/player/leave`, each taking a `session` ID and a `players` list.

Then run both platforms side by side. Send one region's matches to Gameye, compare session start, server behaviour and cost, and move the rest region by region. Your Agones clusters keep serving everything else until you switch them off.

[Player join reference →](https://gameye.com/docs/api-v2/reference/post-session-player-join/)

✓

**What stays the same:** your server logic, netcode, client connection flow and matchmaking rules. The migration touches the SDK calls, the allocation call and where the image lives.

## How do Agones concepts map to Gameye?

| Agones | Gameye |
| --- | --- |
| GameServer | Session: one running container, started by `POST /session` |
| Fleet | Application and image tag. No pool of Ready servers to size |
| FleetAutoscaler | None. Gameye places each session on bare metal first and uses cloud capacity when a region's bare metal is full |
| GameServerAllocation | `POST /session`, which returns `host` and `ports` |
| `SDK.Ready()` | Not needed |
| `SDK.Health()` | Not needed |
| `SDK.Shutdown()` | Process exit, or `DELETE /session/{id}` from your backend |
| SDK server in the Pod | None. Nothing runs next to your server |
| Port policy `Dynamic` | Bridge networking (default) |
| Port policy `Passthrough` | Host networking with `GAMEYE_PORT_*` variables |
| GameServer labels and annotations | `labels` and `env` on `POST /session` |
| Counting players through the SDK | `PUT /session/player/join` and `DELETE /session/player/leave` |
| One cluster per region | `location` per session, chosen with `GET /available-location/{image}` |
| Kubernetes and Agones upgrades | None on your side |

## What does your team stop running?

Clusters and node pools

No Kubernetes clusters, node pools or Agones controllers per region. Gameye runs the machines and the orchestration.

Version upgrades

Each Agones release supports three Kubernetes versions, so the two upgrade cycles are linked. With no SDK in your server, there is no SDK version to keep in step either.

Autoscaler tuning

No buffer sizes, webhook policies or schedules to tune. You start a session per match and Gameye places it.

Allocation services

No allocator endpoint per cluster and no multi-cluster routing. Your backend makes one HTTP call to one API.

Your matchmaker stays

Gameye Docs have guides for [Nakama](https://gameye.com/docs/guides/integrations/nakama/), AWS FlexMatch, Unity Matchmaker, PlayFab, Photon Fusion, Colyseus and [custom matchmakers](https://gameye.com/docs/guides/integrations/custom-matchmaker/).

Agent-ready

The open-source [gameye-mcp server and gameye-skills](https://gameye.com/docs/guides/using-gameye/ai-agents/) let a coding agent containerize a Unity, Unreal, Godot or Node.js server and start and stop sessions and read their logs through the Gameye API.

## Frequently asked questions

Can I reuse my Agones game server image on Gameye?

Yes. Gameye runs your dedicated server as a Linux container, so the image you built for Agones is the starting point. Remove the Agones SDK calls, push the image to Docker Hub or GitHub Container Registry with a new tag, and register the game port on a Gameye application. [Getting started →](https://gameye.com/docs/getting-started/)

What replaces the Agones SDK on Gameye?

Nothing. Gameye needs no SDK, sidecar or plugin in your server. Your server does not call `Ready` or send `Health` pings. The session ends when your server process exits, and billing stops when the container exits. If Gameye stops the session, through `DELETE /session` or a `ttl`, it sends `SIGTERM` and then `SIGKILL` 50 seconds later.

What replaces GameServerAllocation?

One HTTP call. When your matchmaker forms a match, your backend calls [`POST /session`](https://gameye.com/docs/api-v2/reference/post-session/) with the application name (`image`), a `location` and optionally a `version` tag, `args`, `env`, `labels` and a `ttl`. The 201 response contains the `host` IP and a `ports` array that maps each container port to its host port. Your backend sends that IP and port to the players.

Do I still need Fleets and FleetAutoscalers on Gameye?

No. There is no fleet to size and no autoscaler policy to tune. You start one session per match through the API. Gameye places sessions on bare metal first and uses cloud capacity when bare metal in that region is full.

Do I keep my matchmaker when I move off Agones?

Yes. Whatever calls the Agones allocator today calls `POST /session` instead. Gameye Docs have integration guides for Nakama, AWS FlexMatch, Unity Matchmaker, PlayFab, Photon Fusion, Colyseus and [custom matchmakers](https://gameye.com/docs/guides/integrations/custom-matchmaker/).

How does my server find its port on Gameye?

Bridge networking is the default. Your server listens on a fixed container port, such as UDP 7777, and Gameye maps it to a free host port. With host networking, your server reads its port from an environment variable at startup, such as `GAMEYE_PORT_UDP_7777`. Gameye sets these port variables in both modes. [Container environment variables →](https://gameye.com/docs/guides/using-gameye/using-variables/)

## Ready to move off Agones?

Start a Developer Trial, push your existing image with the SDK calls removed, and start your first session with one API call.

[Start Building →](https://trial.gameye.com/)

Further reading

- [Gameye vs Agones: full comparison](https://gameye.com/gameye-vs-agones/)
- [Run Agones yourself or use managed hosting?](https://gameye.com/blog/agones-self-hosted-vs-managed/)
- [What is Agones?](https://gameye.com/glossary/agones/)
- [How Gameye orchestration works](https://gameye.com/how-it-works/)
- [Gameye pricing](https://gameye.com/pricing/)
- [All Gameye integration guides](https://gameye.com/docs/guides/integrations/)
