Multiplayer game studios have a scaling problem that regular web apps don’t: a game server can’t just spin up and shut down on a whim mid-match. It has to hold state, keep a UDP socket open, and survive until the round ends. That mismatch is why so many teams either build brittle in-house fleet managers or pay a premium for a fully managed platform. Agones, the open-source project originally built by Google in collaboration with Ubisoft, closes that gap by teaching Kubernetes to understand game server lifecycles natively. As of September 1, 2026, the project is on version 1.60.0, released August 11, 2026, with support for Kubernetes 1.36, a stable PortPolicyNone mode, and an upgraded Go 1.26.5 toolchain.
This tutorial walks through standing up a working Agones deployment from a bare Kubernetes cluster to a fleet of dedicated game servers that autoscale under load. You’ll install Agones 1.60.0, deploy a sample UDP game server, wire up a Fleet with autoscaling policies, and troubleshoot the failure modes that trip up most first-time installs. By the end you’ll have a reproducible setup you can point at GKE, AKS, EKS, or even a local Minikube cluster.
Don't miss new tech stories on Google
Add Tech Insider once in the Google app and our stories appear in your news suggestions.
What Agones Actually Does (and Why Kubernetes Alone Isn’t Enough)
Kubernetes was built around a specific assumption: workloads are stateless, interchangeable, and safe to kill at any moment. A Deployment can terminate any pod and replace it without anyone noticing. Game servers break that assumption completely. A dedicated server hosting a live match has 8 to 100 players connected over UDP, holds match state in memory, and needs a graceful drain process, not an instant kill. Standard Kubernetes primitives (Deployments, ReplicaSets, Services) have no concept of “this pod is mid-match, don’t touch it.”
Agones solves this by extending the Kubernetes API with Custom Resource Definitions (CRDs) purpose-built for game servers: GameServer, Fleet, FleetAutoscaler, and GameServerAllocation. According to the project’s own documentation, “Agones is a library for hosting, running and scaling dedicated game servers on Kubernetes.” That framing matters: Agones isn’t a replacement for Kubernetes, it’s a controller and SDK layer that teaches the cluster a new vocabulary for a different kind of workload.
The project’s GitHub repository description puts it more concretely: with Agones, “Kubernetes gets native abilities to create, run, manage and scale dedicated game server processes within Kubernetes clusters using standard Kubernetes tooling and APIs.” That last part is the real selling point. You still use kubectl, Helm, GitOps pipelines, RBAC, and namespaces exactly as you would for any other workload. There’s no separate control plane to learn, no proprietary orchestration language, just a set of CRDs and a controller that understands match lifecycles.
Agones is governed as a Linux Foundation project (“a Series of LF Projects, LLC”), distinct from the Cloud Native Computing Foundation (CNCF) that oversees Kubernetes itself. That lineage matters for enterprise adoption decisions, since procurement and security teams increasingly want open-source infrastructure with a visible governance model rather than a single-vendor project that could be abandoned or relicensed without warning.
Agones runs anywhere Kubernetes runs, which in practice means Google Kubernetes Engine (GKE), Azure Kubernetes Service (AKS), Amazon EKS, bare-metal clusters, and local development environments like Minikube or kind. This tutorial uses generic kubectl and Helm commands that work across all of them, with cloud-specific notes called out where it matters, mainly around firewall rules and load balancer provisioning.
Prerequisites and Version Requirements
Before starting, confirm your tooling matches these versions. Agones is strict about Kubernetes compatibility, and mismatches are the single most common cause of failed installs.
| Requirement | Minimum Version | Notes |
|---|---|---|
| Kubernetes cluster | 1.33 – 1.36 | Agones 1.60.0 officially supports this range; check the compatibility table before upgrading either component |
| Agones | 1.60.0 | Released August 11, 2026; adds Kubernetes 1.36 support and stable PortPolicyNone |
| Helm | 3.12 or newer | Used for the recommended installation method |
| kubectl | Matching your cluster’s minor version | Skew of more than one minor version can cause CRD apply errors |
| Docker or a container builder | 24.x or newer | Needed to containerize your own game server binary |
| Go (only if building a custom SDK integration) | 1.26.5 | Matches the toolchain Agones 1.60.0 itself was built with |
| netcat | Any recent build | Used to manually test UDP connectivity to a deployed GameServer |
You’ll also need cluster-admin permissions, since installing CRDs and a controller requires cluster-scoped RBAC grants. If you’re testing locally, Minikube or kind both work, though production traffic testing really needs a real cloud cluster with proper node pools. For teams weighing Kubernetes distributions for this kind of workload, it’s worth comparing full-fat Kubernetes against lighter distributions in K3s vs Kubernetes vs MicroK8s before committing infrastructure budget, since Agones’ resource footprint and node-pool sizing needs differ meaningfully between them.
One more prerequisite that’s easy to skip: decide your target realm topology now. If your game has players in North America, Europe, and Asia, you’ll eventually want separate clusters per region tied together through a matchmaker, rather than trying to force one cluster to serve global traffic. This tutorial covers a single-cluster setup, but the architecture notes near the end explain how to extend it.
Step 1: Provision or Confirm Your Kubernetes Cluster
If you already have a cluster running Kubernetes 1.33 through 1.36, skip to Step 2. If not, here’s the fastest path on GKE, which is the reference platform the Agones docs use most:
gcloud container clusters create agones-tutorial \
--cluster-version=1.36 \
--num-nodes=3 \
--machine-type=e2-standard-4 \
--tags=game-server \
--zone=us-central1-a
gcloud container clusters get-credentials agones-tutorial --zone=us-central1-a
kubectl get nodes
Three nodes is enough to see Fleet scaling behavior without burning through cloud credits during testing. If you’re deploying to AKS or EKS instead, the cluster creation commands differ but the Agones installation from Step 2 onward is identical, since Agones talks to the Kubernetes API, not the underlying cloud provider.
Confirm the API server version before moving on:
kubectl version --short
# Expect: Server Version: v1.36.x
Step 2: Open the Required Firewall Ports
This is the step most tutorials bury in a footnote, and it’s the number one reason first installs fail silently. Agones’ quickstart documentation is explicit: a Kubernetes cluster needs “the UDP port range 7000-8000 open on each node” before GameServers can accept player connections. Dedicated game servers bind directly to host ports in this range (or a range you configure), and if the firewall blocks it, players will see connection timeouts even though kubectl get gameserver reports the pod as Ready.
On GKE:
gcloud compute firewall-rules create game-server-firewall \
--allow udp:7000-8000 \
--target-tags game-server \
--description "Firewall to allow game server traffic"
On AKS, you’d add an equivalent Network Security Group rule; on EKS, a security group inbound rule on the worker node group. The port range itself is configurable in the Helm values file if 7000-8000 conflicts with something else in your environment, but whatever range you choose, the firewall rule must match it exactly.
Step 3: Install Agones 1.60.0 via Helm
Helm is the officially recommended installation method. Add the Agones chart repository and install the stable release:
helm repo add agones https://agones.dev/chart/stable
helm repo update
kubectl create namespace agones-system
helm install my-agones --namespace agones-system agones/agones \
--version 1.60.0 \
--set gameservers.minPort=7000 \
--set gameservers.maxPort=8000
Pin the chart version explicitly with --version 1.60.0. Letting Helm grab whatever “latest” resolves to at install time is a common source of drift between what your documentation describes and what’s actually running, especially on a team where different engineers set up clusters at different times.
Verify the controller and its CRDs came up cleanly:
kubectl get pods --namespace agones-system
kubectl get crds | grep agones.dev
Expect output resembling:
NAME READY STATUS RESTARTS AGE
agones-controller-7d9f8b6c5d-xk2p1 1/1 Running 0 45s
agones-extensions-6f5d8c9b4a-p9r3s 1/1 Running 0 45s
agones-ping-5b7c6d9f8e-m4n2q 1/1 Running 0 45s
gameservers.agones.dev 2026-09-01T10:12:03Z
fleets.agones.dev 2026-09-01T10:12:03Z
gameserversets.agones.dev 2026-09-01T10:12:03Z
fleetautoscalers.agones.dev 2026-09-01T10:12:03Z
If any pod sits in CrashLoopBackOff, check kubectl logs against that pod before touching anything else. The most common cause at this stage is a Kubernetes version outside the 1.60.0 compatibility window, which we’ll cover in the troubleshooting section.
Step 4: Deploy Your First GameServer
Agones ships a simple UDP echo server image specifically for testing installs, so you don’t need a real game binary yet. Create a file named gameserver.yaml:
apiVersion: agones.dev/v1
kind: GameServer
metadata:
generateName: simple-game-server-
spec:
ports:
- name: default
portPolicy: Dynamic
containerPort: 7654
template:
spec:
containers:
- name: simple-game-server
image: us-docker.pkg.dev/agones-images/examples/simple-game-server:0.43
resources:
requests:
memory: "64Mi"
cpu: "20m"
limits:
memory: "64Mi"
cpu: "20m"
Apply it and watch the status transition:
kubectl create -f gameserver.yaml
kubectl get gameserver -o wide -w
A healthy GameServer moves through the states PortAllocation → Creating → Starting → Scheduled → RequestReady → Ready. That last state is what matters: once you see Ready, the server is holding an allocated port and accepting connections.
NAME STATE ADDRESS PORT NODE
simple-game-server-9k2mx Ready 34.66.123.201 7802 gke-agones-tutorial-default-pool-a1b2c3d4-x9y2
Test it manually with netcat over UDP:
nc -u 34.66.123.201 7802
# Type a message, hit enter — the echo server should reply with "ACK: your message"
If that round-trip works, your base Agones install is functional. The rest of this tutorial builds toward production concerns: Fleets, autoscaling, allocation, and health checks.
Step 5: Integrate Your Own Game Server Binary With the Agones SDK
A real game server needs to talk back to Agones, not just sit passively in a container. The Agones SDK (available for Go, C++, Node.js, Rust, REST, and several community-maintained language bindings) gives your process three critical calls:
SDK.Ready()— tell Agones the server has finished booting and can accept playersSDK.Health()— a periodic heartbeat; miss enough of these and Agones marks the server Unhealthy and replaces itSDK.Shutdown()— signal a graceful match-end so Agones can reclaim the pod without an abrupt kill
The Agones FAQ lays out the integration sequence plainly: integrate the SDK and lifecycle hooks into the binary, containerize it with Docker, publish the image to a container registry, write a gameserver.yaml manifest pointing at that image, then test the manifest in the cluster. Here’s a minimal Go example showing the Ready and Health calls:
package main
import (
"log"
"time"
sdk "agones.dev/agones/sdks/go"
)
func main() {
s, err := sdk.NewSDK()
if err != nil {
log.Fatalf("could not connect to sdk server: %v", err)
}
// tell Agones this instance is ready for players
if err := s.Ready(); err != nil {
log.Fatalf("could not send ready message: %v", err)
}
// send a health ping every 5 seconds
go func() {
for {
if err := s.Health(); err != nil {
log.Printf("health ping failed: %v", err)
}
time.Sleep(5 * time.Second)
}
}()
// your game loop and match logic goes here
}
Build and push the image, then reuse the same gameserver.yaml shape from Step 4, swapping in your image reference. If you’re building the SDK from source rather than pulling a pre-built module, use Go 1.26.5 to match the toolchain the Agones 1.60.0 release itself was compiled against, which avoids subtle API mismatches in the generated protobuf bindings.
Step 6: Create a Fleet for Managed Scaling
A single GameServer is fine for testing, but production traffic needs a Fleet: a pool of identical GameServer templates that Agones keeps warm and ready to allocate to incoming matches. Create fleet.yaml:
apiVersion: agones.dev/v1
kind: Fleet
metadata:
name: simple-game-server-fleet
spec:
replicas: 5
template:
spec:
ports:
- name: default
portPolicy: Dynamic
containerPort: 7654
template:
spec:
containers:
- name: simple-game-server
image: us-docker.pkg.dev/agones-images/examples/simple-game-server:0.43
resources:
requests:
memory: "64Mi"
cpu: "20m"
limits:
memory: "64Mi"
cpu: "20m"
kubectl create -f fleet.yaml
kubectl get fleet
kubectl get gameservers
You should see five GameServer instances spin up and transition to Ready. This is your standing pool of warm servers, sitting idle until a matchmaker requests one.
Step 7: Allocate a GameServer From the Fleet
When a match needs a server, your matchmaking service, whatever that is in your stack, calls the Agones allocation API rather than picking a Ready GameServer directly. This is what marks a server Allocated and takes it out of the pool of servers available for new matches:
apiVersion: allocation.agones.dev/v1
kind: GameServerAllocation
spec:
selectors:
- matchLabels:
agones.dev/fleet: simple-game-server-fleet
kubectl create -f allocation.yaml
In production this call happens over gRPC from your matchmaker, not by hand-applying YAML, but the manual version is useful for confirming allocation logic works before wiring up automated matchmaking. Once allocated, that GameServer’s state flips to Allocated and Agones will not hand it to another match request.
Step 8: Configure a FleetAutoscaler
Fixed replica counts waste money during off-peak hours and fall over during a launch spike. A FleetAutoscaler watches how many Ready servers remain in your Fleet and scales the replica count to maintain a buffer:
apiVersion: autoscaling.agones.dev/v1
kind: FleetAutoscaler
metadata:
name: simple-game-server-autoscaler
spec:
fleetName: simple-game-server-fleet
policy:
type: Buffer
buffer:
bufferSize: 5
minReplicas: 5
maxReplicas: 40
kubectl create -f fleetautoscaler.yaml
kubectl get fleetautoscaler
This policy keeps 5 Ready servers on standby at all times, scaling the Fleet up to 40 replicas total as matches consume the buffer. The Buffer policy is the simplest option; Agones also supports a WebhookPolicy for teams that want custom scaling logic driven by external signals like matchmaker queue depth. For general Kubernetes autoscaling strategy beyond just Agones Fleets, node pool scaling and cluster autoscaler tuning, see How to Set Up Karpenter for EKS Autoscaling, since your node pool needs to scale in step with your Fleet or the FleetAutoscaler will request pods the cluster has nowhere to schedule.
Step 9: Set Up Health Checks and Graceful Shutdown
By default, Agones considers a GameServer unhealthy if it misses health pings for a configurable window. Tune this in the GameServer spec under health:
spec:
health:
disabled: false
periodSeconds: 5
failureThreshold: 3
initialDelaySeconds: 10
With this config, the server has 10 seconds after startup before health checks begin, then must ping at least once every 5 seconds, tolerating up to 3 consecutive misses, 15 seconds, before Agones marks it Unhealthy and replaces it. Tune failureThreshold up if your game logic occasionally blocks the main thread for longer stretches, physics-heavy tick processing for example, since an aggressive threshold will cause false-positive server churn mid-match.
For shutdown, call SDK.Shutdown() from your game code when a match ends normally. This tells Agones to move the GameServer to a Shutdown state and reclaim it cleanly, rather than waiting for a hard timeout or, worse, a Kubernetes-initiated pod eviction mid-match.
Step 10: Handle Windows Game Servers (If Applicable)
Most Agones tutorials assume Linux containers, but a meaningful share of game engines, particularly Unreal Engine dedicated server builds, ship Windows binaries. Agones’ Windows GameServers guide, last updated in late August 2026 alongside the 1.60.0 release, uses the same manifest shape with a Windows-tagged image:
kubectl create -f https://raw.githubusercontent.com/googleforgames/agones/release-1.60.0/examples/simple-game-server/gameserver-windows.yaml
The prerequisites are identical: the same UDP port range, the same firewall rule, and a Windows-based node pool tainted so only Windows-compatible pods schedule onto it. Mixed Linux/Windows Fleets are possible but require separate Fleet definitions with node selectors, since a single Fleet template can’t span both operating systems.
Step 11: Test the Full Manifest in Your Cluster
Before calling the setup done, run through this validation checklist end to end:
- Deploy the Fleet and confirm all replicas reach Ready within 60 seconds
- Allocate one GameServer and confirm its state flips to Allocated
- Connect a real client (or netcat) to the allocated server’s external IP and port
- Manually kill one Ready, unallocated, pod and confirm the Fleet replaces it automatically
- Trigger a load spike, allocate several servers at once, and confirm the FleetAutoscaler scales replicas up
- Let allocated servers idle past your health check window and confirm Agones does not kill an allocated server just because it goes health-silent briefly (tune thresholds if it does)
Step 4 in that list is the one teams skip most often, and it’s the one that catches the most bugs. If a Ready pod dies and the Fleet controller doesn’t replace it, something in your RBAC or controller health is broken, and you want to find that in a test cluster, not during a live launch.
Step 12: Secure the Cluster Before Going to Production
Agones’ controller needs cluster-scoped RBAC permissions to manage GameServer CRDs across namespaces, which makes the agones-system namespace a high-value target if compromised. Lock down access with namespace-scoped RBAC for anyone who doesn’t need cluster-admin, restrict the container registry your GameServer images pull from to a private, scanned registry, and apply network policies so game server pods can’t reach the Kubernetes API server directly. A broader hardening pass covering pod security standards, network policies, and secrets management is covered in Kubernetes Security Hardening, and it’s worth running that checklist against any cluster running Agones before it takes real player traffic, since a compromised game server container with unrestricted egress is a much bigger blast radius than a compromised stateless web pod.
Common Pitfalls When Deploying Agones
These are the mistakes that come up repeatedly in Agones GitHub issues and community discussion channels, roughly in order of how often they trip up new deployments.
- Forgetting the firewall rule. The GameServer shows Ready in kubectl but players can’t connect. Nine times out of ten, the UDP 7000-8000 range isn’t open on the node’s firewall or security group.
- Version mismatch between Agones and Kubernetes. Installing Agones 1.60.0 against a Kubernetes 1.29 cluster, well outside the supported range, causes CRD validation errors or a controller that crashes on startup. Always check the compatibility table before upgrading either component independently.
- Using portPolicy Dynamic when you need Static. Dynamic ports work fine for most setups, but if you’re running behind a strict corporate firewall on the client side that only allows a known port range, you need Static port allocation instead, configured explicitly per GameServer.
- Skipping the SDK’s Ready() call. A GameServer container that starts but never calls SDK.Ready() sits in the Scheduled state indefinitely and never becomes allocatable, which looks like a stuck deployment but is actually a missing SDK integration.
- Oversized health check thresholds for tick-heavy game loops. Physics-heavy or AI-heavy game servers can block their main thread long enough to miss health pings, causing Agones to kill and replace an otherwise-fine server mid-match. Widen failureThreshold for CPU-intensive game logic.
- Running Fleets larger than the documented cluster ceiling. The Agones FAQ recommends production clusters stay at or below 500 nodes based on observed real-world workloads; pushing past that without splitting into multiple clusters can degrade controller reconciliation performance.
- Not tainting Windows node pools. Mixed OS clusters without proper node taints let the scheduler place Linux GameServer pods on Windows nodes or vice versa, causing CrashLoopBackOff errors that have nothing to do with Agones itself.
- Forgetting to pin the Helm chart version. Installing without –version pulls whatever the chart repo currently resolves as latest, which can silently upgrade your cluster to a newer, or older if the repo index is stale, Agones release than what your runbooks describe.
Troubleshooting Guide
Work through these in order when something isn’t behaving as expected.
| Symptom | Likely Cause | Fix |
|---|---|---|
| GameServer stuck in Scheduled, never reaches Ready | Game binary never called SDK.Ready() | Check container logs for SDK connection errors; confirm the sidecar SDK server started before your game process tried to connect |
| Players get connection timeouts to a Ready server | Firewall or security group blocking the UDP port range | Re-verify the firewall rule matches the exact port range in your Helm values |
| agones-controller pod in CrashLoopBackOff after install | Kubernetes version outside the 1.33 to 1.36 support window | Check kubectl version against the Agones compatibility table; upgrade or downgrade one side |
| Fleet won’t scale past a certain replica count | Node pool out of capacity, not an Agones limit | Check kubectl describe nodes for resource pressure; scale the underlying node pool or configure cluster autoscaling |
| Allocated GameServer gets killed mid-match | Health check failureThreshold too aggressive for a busy game loop | Increase failureThreshold and/or periodSeconds in the GameServer health spec |
| Helm install hangs on CRD creation | Previous partial install left orphaned CRDs | Run kubectl get crds and manually delete stale Agones CRDs before reinstalling |
| GameServerAllocation returns no available servers | Fleet buffer exhausted, autoscaler hasn’t caught up yet | Check FleetAutoscaler status; temporarily raise minReplicas during known traffic spikes |
| Windows GameServer pod fails to schedule | Missing node taint or toleration for the Windows node pool | Add the correct nodeSelector and toleration to the Windows GameServer template |
| SDK calls fail with connection refused | Game process trying to reach the SDK server before it’s initialized | Add a short retry loop with backoff around the initial SDK connection |
| Metrics or monitoring show no Agones data | Prometheus ServiceMonitor not configured for the agones-system namespace | Enable the Agones Helm chart’s built-in metrics export and point your Prometheus scrape config at it |
Advanced Tips for Production Fleets
Once the basic Fleet-and-autoscaler pattern is working, a few refinements make a real difference at scale. First, use Fleet scheduling: Packed for cost efficiency, which biases the scheduler to fill existing nodes before spreading to new ones, letting the cluster autoscaler scale down idle nodes faster during off-peak hours. Use Distributed scheduling instead if you’re optimizing for failure isolation over cost.
Second, if you’re running in multiple regions, look into Agones’ Allocator service, which exposes a gRPC endpoint your global matchmaker can call to request a server from whichever regional cluster has capacity, rather than hardcoding region logic into your matchmaking layer. This is the practical version of the realms concept Google Cloud describes for grouping clusters by latency requirements.
Third, track your actual cloud spend against Fleet size once you’re in production. A FleetAutoscaler with a generous buffer is great for player experience but can quietly balloon your compute bill if nobody’s watching utilization. Tools built for Kubernetes cost visibility, covered in How to Set Up Kubecost, can break down spend per namespace, which is useful for isolating exactly how much your game server Fleet costs versus the rest of your cluster’s workloads.
Fourth, if you outgrow a single managed Kubernetes cluster’s cost efficiency for this workload, it’s worth comparing against fully managed alternatives. Teams that don’t want to run their own Kubernetes control plane at all sometimes evaluate a managed game server fleet service instead of self-hosting Agones; our AWS GameLift deployment guide covers that managed path for comparison, since the tradeoff between running Agones yourself on Kubernetes and paying for a managed fleet service comes down to how much Kubernetes operations expertise your team already has in-house.
Complete Working Project: Minimal Multiplayer Server Stack
Putting everything together, here’s the full file set for a working, autoscaling multiplayer server deployment. Save each block as its own file in a directory named agones-tutorial/.
01-namespace.yaml:
apiVersion: v1
kind: Namespace
metadata:
name: agones-system
02-fleet.yaml:
apiVersion: agones.dev/v1
kind: Fleet
metadata:
name: production-game-fleet
spec:
replicas: 5
scheduling: Packed
template:
spec:
health:
disabled: false
periodSeconds: 5
failureThreshold: 3
initialDelaySeconds: 10
ports:
- name: default
portPolicy: Dynamic
containerPort: 7654
template:
spec:
containers:
- name: game-server
image: us-docker.pkg.dev/agones-images/examples/simple-game-server:0.43
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
03-autoscaler.yaml:
apiVersion: autoscaling.agones.dev/v1
kind: FleetAutoscaler
metadata:
name: production-game-fleet-autoscaler
spec:
fleetName: production-game-fleet
policy:
type: Buffer
buffer:
bufferSize: 5
minReplicas: 5
maxReplicas: 50
Deploy the whole stack in order:
kubectl apply -f 01-namespace.yaml
helm install my-agones --namespace agones-system agones/agones --version 1.60.0
kubectl apply -f 02-fleet.yaml
kubectl apply -f 03-autoscaler.yaml
# confirm everything is healthy
kubectl get fleet production-game-fleet
kubectl get fleetautoscaler production-game-fleet-autoscaler
kubectl get gameservers -l agones.dev/fleet=production-game-fleet
That’s a complete, working, autoscaling multiplayer server backend running on standard Kubernetes tooling, with no proprietary orchestration layer beyond the Agones CRDs themselves. Running kubectl get gameservers -l agones.dev/fleet=production-game-fleet immediately after this deploy should return five rows, all in the Ready state, all showing distinct dynamic ports on your cluster’s nodes:
NAME STATE ADDRESS PORT NODE
production-game-fleet-7x2k-a1b2 Ready 34.66.123.201 7412 gke-agones-tutorial-default-pool-a1b2c3d4-x9y2
production-game-fleet-7x2k-c3d4 Ready 34.66.123.202 7588 gke-agones-tutorial-default-pool-a1b2c3d4-p8q1
production-game-fleet-7x2k-e5f6 Ready 34.66.123.201 7901 gke-agones-tutorial-default-pool-a1b2c3d4-x9y2
production-game-fleet-7x2k-g7h8 Ready 34.66.123.203 7233 gke-agones-tutorial-default-pool-a1b2c3d4-m4n7
production-game-fleet-7x2k-i9j0 Ready 34.66.123.202 7677 gke-agones-tutorial-default-pool-a1b2c3d4-p8q1
If instead you see servers cycling through Scheduled without ever reaching Ready, or the command returns fewer than five rows after a couple of minutes, stop here and work through the troubleshooting table below before adding the autoscaler or wiring up a real matchmaker on top of this stack. Debugging a broken base Fleet is much faster than debugging it after three more layers of infrastructure have been stacked on top.
Agones vs Self-Built Fleet Management: When It’s Worth the Setup
Not every multiplayer project needs Agones. A small indie game with a handful of dedicated servers running on a single VM doesn’t need Kubernetes at all, let alone a CRD layer on top of it. Agones earns its complexity once you have enough concurrent matches that manual server management becomes a full-time job: dozens of concurrent Fleets, autoscaling that needs to react in seconds rather than minutes, or multi-region deployment requirements.
The build-versus-adopt calculus usually comes down to existing Kubernetes expertise. If your team already runs production Kubernetes workloads for the rest of your backend, matchmaking APIs, leaderboards, chat services, adding Agones is a relatively small incremental cost since the operational knowledge already exists. If your team has never run Kubernetes and your game’s concurrency doesn’t demand elastic Fleet scaling, a managed platform or a simpler self-hosted process manager will get you to launch faster.
Monitoring and Observability for Agones Fleets
Agones exposes controller and GameServer metrics in Prometheus format out of the box when enabled in the Helm values. Turn it on at install time:
helm upgrade my-agones --namespace agones-system agones/agones \
--version 1.60.0 \
--set agones.metrics.enabled=true \
--set agones.metrics.prometheusServiceDiscovery=true
The metrics that matter most day to day are Fleet replica counts by state (Ready, Allocated, Scheduled), controller reconciliation latency, and allocation request failure rate. A sudden spike in allocation failures with plenty of Ready servers available usually points to an RBAC or network policy issue blocking the allocator service, not a capacity problem, so check permissions before assuming you need to scale up.
Multi-Region Architecture: Scaling Beyond a Single Cluster
Everything covered so far assumes one cluster in one region, which is fine for testing and for games with a geographically concentrated player base. Once you have players spread across North America, Europe, and Asia, latency becomes the dominant design constraint, and a single cluster anywhere in the world will feel bad to at least some fraction of your players no matter how well the Fleet scales.
The standard pattern is to run a separate Kubernetes cluster with its own Agones install per region, then group those clusters into what Google Cloud’s documentation calls realms: logical groupings based on acceptable latency thresholds. Your matchmaker (or the Agones Allocator service running in front of each cluster) picks the realm closest to a given match’s players before requesting a GameServer allocation. This keeps the region-selection logic outside of Agones itself, which only ever manages GameServers within a single cluster.
Practically, this means your infrastructure-as-code needs to template the same Fleet and FleetAutoscaler manifests across N clusters rather than writing them once. Terraform or a GitOps tool like Argo CD applied per-region keeps configuration drift from creeping in between, say, your us-central1 cluster and your europe-west1 cluster. Skipping this discipline is how teams end up with one region running Agones 1.58.0 and another on 1.60.0 because someone manually patched a single cluster during an incident and never backported the change everywhere else.
Where Agones Fits Next to Other Cloud Game-Hosting Options
Kubernetes-native fleet orchestration is one of several ways to solve dedicated-server hosting, and picking the right one depends heavily on how much of your stack is already cloud-native. Studios standardizing their entire backend around a broader Kubernetes and cloud-computing strategy, spanning CI/CD, cost governance, and multi-cluster networking, tend to find Agones a natural fit rather than an outlier tool, since it slots into infrastructure they’re already operating and monitoring.
The alternative worth naming directly is a fully managed fleet service, where the cloud provider runs the orchestration layer and bills per server-hour rather than per node. That model trades control and cost transparency for a shorter setup time, which matters most for small teams shipping their first multiplayer title on a tight runway. Larger studios with dedicated platform engineers, by contrast, often prefer owning the Kubernetes layer directly, since it lets them reuse the same monitoring, autoscaling, and security tooling across game servers and every other backend service they run.
For a broader view of how cloud infrastructure decisions like this fit into a wider platform strategy, see our cloud computing coverage, which tracks the AWS, Azure, and GCP tooling changes that affect how teams provision and manage the clusters Agones runs on.
Frequently Asked Questions
What is Agones and who maintains it?
Agones is an open-source platform for deploying, hosting, scaling, and orchestrating dedicated game servers on Kubernetes, originally developed by Google in collaboration with Ubisoft. It continues as an actively maintained open-source project with regular releases, the latest being 1.60.0 in August 2026.
Does Agones work on any Kubernetes cluster, or only Google Cloud?
Agones runs anywhere Kubernetes runs, including GKE, AKS, Amazon EKS, bare-metal clusters, and local development environments like Minikube. It has no hard dependency on Google Cloud infrastructure.
What Kubernetes version does Agones 1.60.0 support?
Agones 1.60.0, released August 11, 2026, adds support for Kubernetes 1.36 and generally supports a rolling window of recent minor versions. Always check the current compatibility table in the Agones documentation before upgrading either component, since support windows shift with each release.
Why does my GameServer stay stuck in Scheduled and never become Ready?
This almost always means the game server binary never called the Agones SDK’s Ready() function. Agones needs that explicit signal to mark the server as available; without it, the pod runs but is never allocatable.
How many nodes can a production Agones cluster handle?
The Agones FAQ recommends keeping production clusters at or below roughly 500 nodes based on observed workload behavior. Larger deployments should be split across multiple clusters rather than scaling a single cluster indefinitely.
Is Agones a replacement for a matchmaking service?
No. Agones manages the lifecycle and scaling of the game server processes themselves. You still need a separate matchmaking layer that calls the Agones allocation API to request a server once it has matched players together.
Can Agones run Windows-based dedicated game servers?
Yes. Agones’ Windows GameServers guide, updated alongside the 1.60.0 release, documents the manifest and node-pool configuration needed to run Windows container images, which is common for Unreal Engine dedicated server builds.
What’s the difference between Agones and Google Cloud Game Servers?
Google Cloud Game Servers was a managed service built on top of Agones and Kubernetes, handling fleet orchestration and lifecycle management with less manual setup. Teams evaluating that path versus self-managed Agones should weigh operational overhead against the flexibility of running the open-source project directly on their own clusters.


