AWS Game Server Hosting Setup: 15 Steps, 120 Min [2026]

Every multiplayer shooter, battle royale, or co-op survival game needs somewhere to run its authoritative game logic, and that somewhere is almost never the player’s own machine. It is a dedicated server, spun up on demand, torn down when the match ends, and billed by the minute. That demand has turned into real money: SNS Insider sized the global game server hosting platform market at $2.31 billion in February 2025 and projects it will climb to $6.83 billion by 2035 as more studios move off self-managed hardware. Getting that infrastructure right is a different problem than streaming a game’s video output the way GeForce NOW or Xbox Cloud Gaming do. This tutorial is about the other half of cloud gaming: the backend that keeps thousands of concurrent matches alive without an ops team babysitting servers around the clock.

By the end of this guide you will have a working Amazon EKS cluster running Agones, Google’s open-source game server orchestrator built on Kubernetes, capable of scaling a fleet of dedicated game servers up and down automatically as players connect and disconnect. The same pattern powers game server hosting at companies shipping session-based multiplayer titles today, and it plugs directly into AWS GameLift if you later want a fully managed alternative. Expect roughly 120 minutes end to end, most of it spent waiting on EKS cluster provisioning rather than typing commands.

If you’d rather not spend AWS credits while you’re still learning the moving pieces, everything through Step 3 (installing Agones and deploying a Fleet) works identically on a local cluster created with kind or minikube. This tutorial provisions a real EKS cluster from Step 4 onward because the security group and IAM steps only make sense against real AWS infrastructure, but treat that as an option if you want to validate your Fleet and FleetAutoscaler manifests for free first.

Google · Preferred Sources

Don't miss new tech stories on Google

Add Tech Insider once in the Google app and our stories appear in your news suggestions.

Add Now

What Game Server Hosting Really Means in 2026

It is worth separating two things that get lumped together under “cloud gaming.” Services like Amazon Luna, Xbox Cloud Gaming, and GeForce NOW render a full game on a remote GPU and stream video to your device, so you can play a AAA title on a phone. That is cloud gaming as a consumer product. Game server hosting is a backend engineering problem: when a player starts a multiplayer match, something has to run the authoritative simulation, track player positions, resolve hits, and broadcast state to every client in the session. That “something” is a dedicated game server process, and at any real scale it has to be provisioned, health-checked, and destroyed automatically thousands of times a day. The category has grown to match: Market Intelo pegged the broader game server hosting market at $5.8 billion in 2025, forecasting growth to $19.4 billion by 2034 at a 14.4% CAGR, while a 2026 LinkedIn market report tracked game server hosting services climbing from $4.2 billion in 2024 toward $10.78 billion by 2033 on a 12.5% CAGR starting in 2026.

Historically, studios either rented physical dedicated servers by the month (wasteful when player counts swing by time of day) or wrote custom orchestration scripts around raw EC2 instances (fragile and hard to maintain). AWS GameLift emerged as a managed answer, and more recently the combination of Kubernetes with Agones, the open-source project originally built by Ubisoft and Google, has become the default for teams that want portability and don’t want to be locked into one vendor’s fleet model. Agones adds game-server-aware primitives, GameServer, Fleet, and FleetAutoscaler, on top of standard Kubernetes objects, so the cluster understands the difference between “this pod is unhealthy” and “this pod has 8 players mid-match, don’t kill it yet.” By June 2026, Market Intelo found cloud deployment accounted for 68.3% of dedicated game server hosting, with AWS holding a 21.3% share of the market, Azure at 18.9%, and Google Cloud at 6.8%; AWS GameLift alone was supporting more than 450,000 server deployments annually by that point.

Running Agones on Amazon EKS gives you the portability of Kubernetes (the same manifests work on GKE or self-managed clusters) plus the option to fall back to AWS GameLift for specific fleets if you want AWS to manage the underlying capacity for you. That flexibility is why this stack shows up repeatedly in dedicated game server hosting architecture discussions for 2026 launches, and why it is worth learning even if you eventually migrate pieces of it to a fully managed service. The dollars at stake keep climbing across market trackers: Business Research Insights valued game server hosting platforms at $0.7 billion in 2026, growing toward $1.67 billion by 2035 at an 11.5% CAGR, while it separately sized the broader global game servers market at $5.85 billion in January 2026 en route to $10.88 billion by 2035; Data Insights Market put the game server hosting services segment even higher, at $14.22 billion in 2025.

It also helps to know what this tutorial is deliberately not covering. Consumer cloud gaming platforms sit adjacent to this stack but solve a different problem: GeForce NOW streams existing games at up to 1440p and 120fps to a client device, Xbox Cloud Gaming runs on Azure infrastructure tied into Game Pass at up to 1080p and 60fps, and Amazon Luna streams from AWS-hosted Nvidia GPU instances, also topping out around 1080p and 60fps. Every one of those services still needs a dedicated game server or a full game instance running somewhere in the background for session-based multiplayer titles, which is exactly the layer this guide builds.

Agones vs Raw Kubernetes vs AWS GameLift: Picking Your Approach

Before installing anything, it’s worth being deliberate about which of three reasonable paths you’re actually on, because they lead to different amounts of work. You could run dedicated game servers as plain Kubernetes Deployments behind a Service, skip Agones entirely, and hand-roll your own session affinity and scaling logic. You could run Agones on top of Kubernetes, which is what this tutorial does. Or you could skip Kubernetes altogether and let AWS GameLift manage fleets directly. Each is a legitimate choice depending on how much control you need versus how much operational work you’re willing to take on.

ApproachOperational EffortPortabilityBest Fit
Raw Kubernetes DeploymentsHigh, you build session affinity and scaling yourselfFull, standard Kubernetes objects onlyTeams with very custom scheduling needs Agones doesn’t cover
Agones on Kubernetes (this tutorial)Moderate, Agones handles game-server-aware schedulingHigh, same manifests run on EKS, GKE, or on-prem clustersTeams that want portability and are already comfortable with Kubernetes
AWS GameLift (fully managed)Low, AWS manages fleet capacity and health checksLow, tied to AWS-specific APIs and SDKsSmall teams that want to skip infrastructure work entirely

None of these choices are permanent. It’s common for a studio to prototype on Agones because the local development loop (via minikube or kind) is fast, then run production traffic through a mix of self-managed EKS fleets and GameLift capacity depending on region and cost. The rest of this tutorial builds the Agones-on-EKS path specifically, since it’s the one that keeps every option open for later.

Prerequisites: Accounts, Tools, and Versions You Need

This is a hands-on infrastructure tutorial, not a conceptual overview, so you will need real accounts and real tools installed before Step 1. None of this is optional: eksctl and kubectl both need to authenticate against an actual AWS account, and Agones needs an actual running Kubernetes cluster to install into. Budget for a small AWS bill (a few dollars) if you leave the cluster running for the full 120 minutes. The teardown step at the end prevents it from becoming a recurring charge.

Tool / AccountVersion NeededPurpose
AWS accountActive, billing enabledHosts the EKS cluster, ECR repository, and worker nodes
IAM user or roleProgrammatic access + AdministratorAccess (or scoped EKS/EC2/ECR policy)Lets eksctl and kubectl create cluster resources
AWS CLIv2.x (latest)Configures credentials, talks to ECR and EKS APIs
eksctlLatest releaseProvisions the EKS cluster and node groups with one command
kubectlMatching your EKS cluster’s Kubernetes minor versionApplies manifests and inspects cluster state
Helm3.x (latest)Installs the Agones controller, allocator, and CRDs
DockerLatest stableBuilds and pushes the game server container image
Agonesv1.59.0 (latest stable, released July 2026)Adds GameServer, Fleet, and FleetAutoscaler objects to Kubernetes

You do not need a finished game to follow along. The container image in Step 8 is a minimal UDP server that exists just to demonstrate the Agones SDK lifecycle calls (Ready(), Health(), Shutdown()). Swapping in your actual Unity, Unreal, or custom engine dedicated server build later is a matter of replacing the Dockerfile’s entrypoint, not redoing the Kubernetes side. If you’ve never built a container image before, it’s worth working through Docker’s own get-started guide first, since Step 8 assumes you’re comfortable with basic Dockerfile syntax.

Step 1: Map Your Architecture Before You Provision Anything

Five minutes of planning here saves an hour of debugging later. The architecture you are about to build has four moving pieces: an EKS cluster running on EC2 worker nodes, the Agones controller and allocator running as pods inside that cluster, a Fleet of GameServer pods each running your dedicated server binary on its own dynamically assigned UDP port, and a client-facing allocation flow that hands out a ready server’s IP and port whenever a match needs to start.

The detail that trips up newcomers coming from typical web-app Kubernetes experience is the networking model. A normal Kubernetes Deployment behind a Service load-balances traffic across identical, interchangeable pods. Game servers are not interchangeable: once a client connects to GameServer pod A, every subsequent packet in that match must keep reaching pod A specifically, because that is where the authoritative match state lives. Agones solves this by assigning each GameServer pod its own externally reachable port on the node’s host network, drawn from a configurable range (30000 to 32767 by default), rather than putting a load balancer in front of a pool of servers. Keep that distinction in mind, because it explains several configuration choices in the steps ahead, especially the security group rule in Step 4 and the pitfalls section near the end of this guide.

Step 2: Install the AWS CLI, eksctl, kubectl, and Helm

On a Linux machine or in WSL, install all four CLIs in sequence. macOS users can substitute brew install awscli eksctl kubectl helm for the same result.

# AWS CLI v2
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

# eksctl (latest release)
curl --silent --location "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_Linux_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin

# kubectl (matches the current stable Kubernetes release)
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

# Helm 3
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# Confirm everything installed correctly
aws --version
eksctl version
kubectl version --client
helm version

Expect output roughly like aws-cli/2.23.0 Python/3.12.6 Linux/6.8.0 exe/x86_64.ubuntu.24 for the AWS CLI and a semantic version string for each of the other three. If any command returns “command not found,” double-check that /usr/local/bin is on your PATH.

Step 3: Configure IAM Permissions and AWS Credentials

Create (or reuse) an IAM user with programmatic access and attach enough permissions to create EKS clusters, EC2 instances, and ECR repositories. For a personal test environment, attaching the AWS-managed AdministratorAccess policy is the path of least resistance. For a shared or production AWS account, scope it down to AmazonEKSClusterPolicy, AmazonEC2FullAccess, AmazonEC2ContainerRegistryFullAccess, and IAM permissions to create the node role that eksctl generates automatically.

aws configure
# AWS Access Key ID [None]: AKIA................
# AWS Secret Access Key [None]: ****************************************
# Default region name [None]: us-east-1
# Default output format [None]: json

# Confirm the credentials actually resolve
aws sts get-caller-identity

A working credential set returns a JSON block with your Account, UserId, and Arn. If you get an ExpiredToken or InvalidClientTokenId error instead, you are likely reusing temporary SSO credentials that expired between sessions. Re-run aws sso login or regenerate a long-lived access key pair.

Step 4: Provision Your Amazon EKS Cluster

Rather than clicking through the console, define the cluster as a YAML file so it is reproducible and so you can delete and recreate it identically later. Save this as cluster.yaml. The Kubernetes version matters here: Agones 1.57 and later officially test against Kubernetes 1.33 through 1.35, so pin your cluster to a version inside that range rather than whatever eksctl defaults to.

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: game-server-cluster
  region: us-east-1
  version: "1.33"
managedNodeGroups:
  - name: game-server-nodes
    instanceType: c6i.xlarge
    minSize: 2
    maxSize: 6
    desiredCapacity: 3
    volumeSize: 40
    labels:
      role: game-server
    ssh:
      allow: false

Then provision it with a single command. This is the slow part of the tutorial, expect 15 to 20 minutes while eksctl creates the underlying CloudFormation stacks, VPC networking, and managed node group.

eksctl create cluster -f cluster.yaml

Compute-optimized instance families like c6i are the conventional choice for game server fleets because dedicated server ticks are usually CPU-bound simulation work rather than memory- or network-bound, so you get more concurrent matches per dollar than on general-purpose instance types.

Step 5: Verify Cluster Access With kubectl

eksctl updates your local kubeconfig automatically, but it is worth confirming explicitly before you build anything on top of it.

aws eks update-kubeconfig --region us-east-1 --name game-server-cluster
kubectl get nodes
kubectl cluster-info

kubectl get nodes should list three nodes in Ready status, matching the desiredCapacity from your cluster config. If the command hangs or times out, your local machine’s outbound network access to the EKS API endpoint is likely being blocked by a corporate firewall or VPN.

Step 6: Install Agones on the Cluster via Helm

With a working cluster in hand, add the official Agones Helm repository and install it into its own namespace. Pin the chart version to match the Agones release you want, v1.59.0 is the current stable release as of July 2026, per the project’s GitHub releases page.

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.59.0

This installs the Agones controller, the allocator service, and a set of Kubernetes Custom Resource Definitions, GameServer, Fleet, FleetAutoscaler, and GameServerAllocation, that everything else in this tutorial depends on.

Step 7: Verify the Agones Installation

kubectl get pods --namespace agones-system
kubectl get crds | grep agones.dev

You should see pods named roughly agones-controller-..., agones-ping-..., and agones-allocator-..., all in Running status, and the CRD list should include gameservers.agones.dev, fleets.agones.dev, fleetautoscalers.agones.dev, and gameserverallocationpolicies.agones.dev. If any controller pod is stuck in CrashLoopBackOff, the most common cause is a Kubernetes version outside Agones’ supported range from Step 4.

Step 8: Containerize Your Dedicated Game Server

Your real game server binary integrates the Agones SDK to call three lifecycle functions: Ready() when it can accept players, Health() on a periodic tick so Agones knows the process hasn’t hung, and Shutdown() when the match ends so Agones can recycle the pod. Wrap that binary in a minimal container image. A distroless base keeps the image small and reduces attack surface, which matters when you are pushing new builds frequently during active development.

FROM golang:1.23 AS build
WORKDIR /app
COPY . .
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux go build -o /gameserver ./cmd/server

FROM gcr.io/distroless/static-debian12
COPY --from=build /gameserver /gameserver
EXPOSE 7654/udp
ENTRYPOINT ["/gameserver"]

Inside cmd/server, the Agones SDK integration is a handful of lines: connect to the SDK sidecar, call Ready() once your listener is bound, and start a background goroutine that calls Health() every couple of seconds for as long as the process is alive.

sdk, err := agonessdk.NewSDK()
if err != nil {
    log.Fatalf("could not connect to Agones sdk: %v", err)
}
if err := sdk.Ready(); err != nil {
    log.Fatalf("could not send Ready: %v", err)
}
go func() {
    tick := time.Tick(2 * time.Second)
    for range tick {
        sdk.Health()
    }
}()

Build the image locally before you worry about ECR at all, just to confirm it compiles and runs: docker build -t game-server:1.0 . followed by docker run --rm -p 7654:7654/udp game-server:1.0.

Step 9: Push the Image to Amazon ECR

Kubernetes needs to pull this image from somewhere the cluster can reach, so create a private Amazon ECR repository and push your build there.

aws ecr create-repository --repository-name game-server --region us-east-1

aws ecr get-login-password --region us-east-1 | \
  docker login --username AWS --password-stdin ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com

docker tag game-server:1.0 ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/game-server:1.0
docker push ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/game-server:1.0

Replace ACCOUNT_ID with your actual 12-digit AWS account number, which you can pull from the aws sts get-caller-identity output in Step 3. ECR authentication tokens expire after 12 hours, so if you come back to this tutorial the next day and pushes suddenly fail with a login error, just rerun the get-login-password command.

Step 10: Define Your Agones Fleet Manifest

A Fleet is Agones’ equivalent of a Deployment, except every replica is a GameServer with its own dynamically allocated port instead of an interchangeable pod behind a Service. Save this as fleet.yaml, substituting your actual ECR image URI.

apiVersion: agones.dev/v1
kind: Fleet
metadata:
  name: game-server-fleet
spec:
  replicas: 3
  template:
    spec:
      ports:
        - name: default
          portPolicy: Dynamic
          containerPort: 7654
          protocol: UDP
      health:
        initialDelaySeconds: 10
        periodSeconds: 5
        failureThreshold: 3
      template:
        spec:
          containers:
            - name: game-server
              image: ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/game-server:1.0
              resources:
                requests:
                  memory: "256Mi"
                  cpu: "250m"
                limits:
                  memory: "512Mi"
                  cpu: "500m"

The portPolicy: Dynamic setting is what tells Agones to assign each replica its own host port rather than sharing one, which is the piece of the multiplayer game backend puzzle that plain Kubernetes doesn’t handle out of the box. Setting explicit resource requests and limits matters more here than in typical web workloads: an under-resourced game server can start dropping tick rate under load well before Kubernetes would ever OOM-kill it.

Step 11: Deploy the Fleet and Confirm GameServers Reach Ready

kubectl apply -f fleet.yaml
kubectl get fleet game-server-fleet
kubectl get gameservers

Within a minute or two, kubectl get gameservers should show three entries transitioning from Scheduled to Ready, something like:

NAME                            STATE   ADDRESS         PORT   NODE
game-server-fleet-abc12-xk9zt   Ready   34.201.55.12    7724   ip-192-168-45-201
game-server-fleet-abc12-p2m4q   Ready   34.201.55.12    7891   ip-192-168-67-114
game-server-fleet-abc12-rt7wj   Ready   34.201.55.12    7655   ip-192-168-45-201

If a GameServer sits in Scheduled indefinitely and never reaches Ready, your container is almost certainly never calling the SDK’s Ready() function, or it is crashing before it gets there, check kubectl logs on the pod directly.

Step 12: Configure a FleetAutoscaler for Demand-Based Scaling

Running a fixed replica count defeats the purpose of cloud infrastructure. A FleetAutoscaler watches how many Ready (unallocated, available) GameServers exist and keeps a buffer of spare capacity, scaling the Fleet up as that buffer gets consumed by matches and back down as matches end.

apiVersion: autoscaling.agones.dev/v1
kind: FleetAutoscaler
metadata:
  name: game-server-autoscaler
spec:
  fleetName: game-server-fleet
  policy:
    type: Buffer
    buffer:
      bufferSize: 2
      minReplicas: 2
      maxReplicas: 20
kubectl apply -f autoscaler.yaml
kubectl get fleetautoscaler

This Buffer policy is the simplest of Agones’ autoscaling strategies and the right starting point for most teams. Agones’ more recent releases also support WebAssembly-based custom autoscaling policies for teams that need scaling logic beyond a simple buffer, useful if you want to factor matchmaking queue depth or time-of-day traffic patterns into the scaling decision instead of just a flat buffer count.

Step 13: Allocate a Game Session and Test Client Connectivity

Allocation is the step your matchmaking service would normally trigger the moment a match is ready to start: it asks Agones for one Ready GameServer, marks it Allocated so the autoscaler and health checker treat it differently, and hands back its address and port.

apiVersion: allocation.agones.dev/v1
kind: GameServerAllocation
spec:
  selectors:
    - matchLabels:
        agones.dev/fleet: game-server-fleet
kubectl create -f allocation.yaml -o yaml

The response includes a status.address and status.ports block, exactly what a real matchmaker would forward to a connecting client. You can sanity-check the raw UDP path yourself with netcat:

nc -u 34.201.55.12 7724

If the connection hangs with no response, jump to the troubleshooting table below, this is almost always a security group problem, not an Agones problem.

Step 14: Add Health Checks and Graceful Shutdown

The health check settings from your Fleet manifest (initialDelaySeconds, periodSeconds, failureThreshold) control how aggressively Agones kills a GameServer that stops calling Health(). Tune these against your actual game loop rather than leaving the defaults: a physics-heavy simulation that occasionally blocks for 4 to 5 seconds during level streaming needs a more forgiving failureThreshold than a lightweight lobby server.

Graceful shutdown matters just as much as startup. When a match ends, your game server process should call sdk.Shutdown() explicitly rather than just exiting, and your container should handle SIGTERM by finishing in-flight work (saving match results, notifying connected clients) before it actually terminates. Set terminationGracePeriodSeconds generously enough, 30 seconds is a reasonable starting point, so Kubernetes doesn’t SIGKILL a server mid-cleanup.

Step 15: Monitor With Grafana and Tear Down When You’re Done

Recent Agones releases ship an updated Grafana Helm chart specifically for visualizing Fleet and GameServer state, worth enabling even for a test cluster so you can watch allocation and scaling behavior in real time rather than polling kubectl repeatedly.

helm upgrade my-agones --namespace agones-system agones/agones \
  --reuse-values \
  --set agones.metrics.prometheusServiceDiscovery=true

When you are finished experimenting, tear everything down in reverse order so nothing keeps billing after you close your terminal. This is the single most important command in this entire tutorial if you care about your AWS bill.

kubectl delete -f autoscaler.yaml
kubectl delete -f fleet.yaml
helm uninstall my-agones --namespace agones-system
eksctl delete cluster -f cluster.yaml

eksctl delete cluster removes the EKS control plane, the managed node group’s EC2 instances, and the associated CloudFormation stacks, VPC, and NAT gateways. It typically takes 8 to 10 minutes to finish. Don’t assume it’s done just because your terminal returns a prompt on an interrupted run, check the CloudFormation console if you’re unsure.

Common Pitfalls When Hosting Game Servers on AWS

Most of the pain in a first Agones deployment comes from a small set of recurring mistakes, not from Agones itself being fragile. Almost every one of these traces back to a mismatch between how a normal stateless web service behaves on Kubernetes and how a stateful, session-affinity-dependent game server needs to behave instead. These are the ones worth watching for specifically.

  • Blocking the dynamic port range at the security group level. Agones assigns each GameServer a host port from a configurable range (30000 to 32767 by default), but that range does nothing if the EKS node security group only allows inbound traffic on 443 and 22. Open the full UDP range explicitly.
  • Putting a standard Kubernetes Service or Load Balancer in front of the Fleet. This reintroduces the interchangeable-pod model Agones exists to avoid, breaking session affinity the moment a client’s traffic gets routed to a different pod mid-match.
  • Skipping resource requests and limits. Without them, the Kubernetes scheduler can pack too many game server pods onto one node, and CPU contention shows up to players as rubber-banding and lag spikes long before any container actually crashes.
  • Never calling the SDK’s Health() function on a tick. A game server that never heartbeats gets marked unhealthy and killed by Agones mid-session, taking every connected player’s match down with it.
  • Setting the FleetAutoscaler buffer too small. A bufferSize of zero or one means every traffic spike produces a window where players hit “no available GameServers” instead of a match starting instantly.
  • Forgetting to tear down test clusters. An EKS control plane left running racks up $0.10 an hour on its own, and idle worker nodes and NAT gateways add considerably more, this is the single most common source of surprise AWS bills from tutorial environments.
  • Assuming a rolling update will replace every GameServer immediately. Agones deliberately will not terminate an Allocated GameServer with players still connected just because a new Fleet image was pushed. If you deploy an update and old pods seem to be “stuck,” check whether they’re actually mid-match before assuming something is broken.

Troubleshooting Guide: 9 Problems You’ll Likely Hit

These are the failures that come up most often when teams stand up dedicated game server hosting on EKS and Agones for the first time, along with the fix for each. Work through this table before opening a support ticket or filing a GitHub issue, most of these are configuration mismatches rather than actual bugs in Agones or EKS.

SymptomLikely CauseFix
GameServers stuck in “Scheduled,” never reach “Ready”Container never calls the SDK’s Ready() function, or crashes on startupCheck kubectl logs on the pod; confirm the SDK sidecar is reachable before Ready() is called
eksctl create cluster fails with an IAM errorThe credential in aws configure lacks CloudFormation or IAM role-creation permissionsAttach AdministratorAccess for testing, or add the specific IAM/CloudFormation permissions eksctl needs
Agones controller pods stuck in CrashLoopBackOffEKS cluster is running a Kubernetes version outside Agones’ supported rangeRecreate the cluster pinned to a version Agones currently tests against (1.33 to 1.35 as of mid-2026)
kubectl get crds shows no agones.dev resourcesHelm install targeted the wrong namespace, or didn’t completeRe-run helm status my-agones -n agones-system and check for failed hooks
GameServerAllocation returns “no available GameServers”Fleet’s Ready replica pool is exhausted, or the autoscaler buffer is too smallIncrease bufferSize and maxReplicas on the FleetAutoscaler
Client connects but gets no UDP responseNode security group blocks the dynamic port range Agones assignedOpen inbound UDP 30000 to 32767 (or your configured range) on the node security group
docker push to ECR fails with “no basic auth credentials”The ECR login token expired (tokens last 12 hours)Re-run aws ecr get-login-password and pipe it into docker login again
Fleet rollout hangs on old GameServersAgones won’t terminate Allocated GameServers with active players mid-match by defaultWait for matches to end, or configure a rolling update strategy with an explicit maxUnavailable
Players in distant regions report high latencyFleet is running in a single AWS region close to some players and far from othersDeploy fleets in multiple regions, or route allocation through AWS GameLift FlexMatch for latency-based matchmaking

Advanced Tips: Spot Instances, Multi-Region Fleets, and Cost Control

Once the base setup works, a few refinements make the difference between a tutorial cluster and something you would actually trust in production.

Run worker nodes on Spot Instances where the game tolerates it. AWS advertises Spot Instances at up to 90% off On-Demand pricing, and short, session-based matches are a reasonable fit since a two-minute Spot interruption notice is usually enough time for Agones to stop allocating new sessions to a node marked for reclamation. Pair this with Karpenter or the Kubernetes autoscaling primitives so node-level scaling reacts to Agones’ pod scheduling pressure automatically rather than requiring manual node group resizing.

Consider AWS GameLift for fleets you don’t want to operate yourself. GameLift’s pricing page confirms it bills strictly by GameLift instance-hours with no separate enrollment fee or pricing agreement, and it can absorb some of the fleet management overhead this tutorial handles manually through eksctl and Helm. Pricing keeps shifting in buyers’ favor, too: Gameye’s June 2026 hosting guide lists its own managed offering starting at $0.07 per vCPU per hour, and AWS began offering free bandwidth on gen-6-and-later GameLift instances starting in June 2026, narrowing the cost gap with self-managed EKS fleets. Many teams run Agones on EKS for flexibility during development and lean on GameLift for specific regions or peak-load bursting later.

Go multi-region before you need to, not after. A single-region Fleet is fine for a regional launch, but latency-sensitive competitive titles typically need Fleets in at least three regions (for example us-east-1, eu-west-1, and ap-northeast-1) with allocation logic that picks the nearest healthy Fleet to the requesting player.

Use ARM-based Graviton instances if your game server binary supports it. Compute-optimized Graviton instance types are generally cheaper per vCPU-hour than their x86 equivalents, and Go, Rust, and most modern game engine dedicated server builds cross-compile to ARM without much friction, worth testing against your specific engine before committing a whole fleet to it.

Load-test the Fleet before you announce a launch date. A FleetAutoscaler tuned against synthetic traffic behaves differently from one facing a real player spike, because real launches produce correlated demand, everyone connects in the first ten minutes, not a smooth ramp. Script a load test that allocates dozens of GameServerAllocations in a tight loop and watch how quickly new replicas actually reach Ready, not just how quickly the Fleet’s replica count changes. If provisioning new nodes is the bottleneck rather than starting new pods on existing nodes, over-provision your node group’s minSize ahead of a known launch window rather than trusting the autoscaler to react in time.

What This Setup Actually Costs Per Month

The EKS control plane itself is the one flat, predictable line item. Everything else scales with your actual player traffic, which is exactly the tradeoff that makes this architecture worth the setup effort in the first place.

Cost ComponentPricing ModelNotes
EKS control plane (standard support)$0.10 per cluster, per hourRoughly $73/month if left running continuously
EKS control plane (extended support)$0.60 per cluster, per hourOnly applies once a Kubernetes version ages out of standard support
Worker node compute (On-Demand)Billed per EC2 instance-hourThe largest variable cost; scales directly with Fleet replica count and instance family
Worker node compute (Spot)Same instance types, Spot market pricingUp to 90% cheaper than On-Demand per AWS’s published Spot pricing
AWS GameLift (alternative to self-managed EKS)Billed by GameLift instance-hoursNo separate enrollment or pricing agreement required
Data transferBilled per GB transferred to the internetScales with concurrent players, session length, and game state update frequency

The practical takeaway: a small test cluster like the one in this tutorial costs single-digit dollars if you tear it down within a couple of hours, and the control plane’s flat $0.10-an-hour fee, confirmed on AWS’s official EKS pricing page, is rarely the line item that determines whether this architecture is affordable for your project. Worker node count and instance family choice are where the real cost control levers live, which is exactly why the Spot Instance and Graviton suggestions above matter more than which support tier your cluster runs under. Managed alternatives are sweetening their own terms too: Haptic’s pricing page, updated in August 2026, advertises a 10% discount for quarterly billing and 25% off for paying yearly compared to month-to-month game server hosting rates, worth factoring in if you’re weighing a managed provider against the DIY EKS route priced above.

Frequently Asked Questions

Do I need both AWS GameLift and Agones, or is that redundant?
No, they solve overlapping problems and most teams pick one primary path. Agones on EKS gives you Kubernetes-native portability and full control. GameLift gives you a fully managed alternative with less operational overhead. Some teams do use GameLift FlexMatch for matchmaking on top of an Agones-managed Fleet, but that is an optimization, not a requirement.

What Kubernetes version should my EKS cluster run?
Match whatever range the Agones release you’re installing officially supports. As of mid-2026, Agones 1.57 and its successors test against Kubernetes 1.33 through 1.35, so pin your cluster.yaml to a version in that band rather than accepting eksctl’s default.

Can I use this setup with Unity or Unreal Engine dedicated server builds?
Yes. The Kubernetes and Agones layer doesn’t care what engine produced your server binary. You integrate the Agones SDK (available for C++, C#, Go, Node.js, and Rust, among others) into your existing dedicated server build, then containerize it the same way Step 8 describes.

How do I handle UDP traffic through AWS networking correctly?
Make sure the EKS node security group allows inbound UDP traffic across whatever dynamic port range Agones is configured to use (30000 to 32767 by default), since Agones assigns host ports directly rather than routing through a load balancer.

Is Agones actually production-ready?
Yes. It has been an active open-source project since 2018, backed jointly by Google and Ubisoft, and reached v1.59.0 in July 2026 with continued monthly releases, active CNCF governance, and a public roadmap on agones.dev.

What’s the real difference between GameLift Servers and GameLift Streams?
GameLift Servers, documented in AWS’s GameLift developer guide, is the dedicated-server hosting product this tutorial’s architecture parallels, built for session-based multiplayer game logic. GameLift Streams is a separate, newer product for streaming full game video to a browser or device, closer to what GeForce NOW or Xbox Cloud Gaming do than to anything covered in this guide.

Why did my FleetAutoscaler not scale even though the buffer looked too small?
Check that the FleetAutoscaler’s fleetName field exactly matches your Fleet’s metadata name, and confirm the autoscaler controller pod in agones-system is actually running. A common cause is a typo in fleetName that silently points the autoscaler at a Fleet that doesn’t exist.

How much does it cost to keep this running for a small live game?
It depends almost entirely on concurrent player count and instance family, not on the EKS or Agones layer itself, which adds a flat $0.10-an-hour control plane fee. Running worker nodes on Spot Instances and scaling the Fleet down aggressively during off-peak hours are the two levers with the biggest impact on the bill.

Can I test this whole setup without an AWS account?
Yes, for everything except the AWS-specific steps. Create a local cluster with kind or minikube, install Agones with the same Helm commands from Step 6, and apply the same Fleet and FleetAutoscaler manifests from Steps 10 and 12. The only parts that require real AWS infrastructure are the EKS cluster itself, ECR image hosting, and the security group configuration, everything else in the Agones layer is identical.

Which programming languages does the Agones SDK support?
Officially maintained SDKs cover C++, C#, Go, Node.js, Rust, and REST/gRPC for anything else, which in practice means Unity (C#), Unreal Engine (C++), and most custom Go or Rust dedicated servers all have a direct integration path without writing your own SDK client from scratch.

Related Coverage

For broader context on the cloud infrastructure decisions behind this stack, see tech-insider.org’s cloud computing coverage.

Sofia Lindström

Sofia Lindström

Editor-in-Chief

Sofia Lindström is the Editor-in-Chief at Tech Insider, where she leads editorial strategy and oversees coverage across AI, cybersecurity, and enterprise technology. With over a decade in Swedish tech journalism, she previously served as technology editor at Dagens Industri and covered the Nordic startup ecosystem for Breakit. Sofia holds an MSc in Media Technology from KTH Royal Institute of Technology and is a frequent speaker at Web Summit and Slush. She is passionate about making complex technology accessible to business leaders.

View all articles