Skip to main content
GameServerAllocation is the mechanism for assigning a GameServer from a pool (typically a Fleet) to a game session. It provides powerful filtering, prioritization, and metadata patching capabilities.

Allocation Basics

When you create a GameServerAllocation, Agones:
  1. Finds GameServers matching your selectors
  2. Sorts them by scheduling strategy and priorities
  3. Transitions the chosen GameServer from Ready → Allocated
  4. Applies metadata patches (labels, annotations, counters, lists)
  5. Returns connection details to the client
Source: pkg/apis/allocation/v1/gameserverallocation.go
apiVersion: allocation.agones.dev/v1
kind: GameServerAllocation
metadata:
  generateName: allocation-
spec:
  selectors:
    - matchLabels:
        agones.dev/fleet: simple-fleet

Allocation Lifecycle

Allocation States (gameserverallocation.go:33-41):
  • Allocated: Successfully allocated a GameServer
  • UnAllocated: No matching GameServers found
  • Contention: Allocation failed due to concurrent update conflict (retry recommended)

Selectors

Selectors define which GameServers are eligible for allocation: Source: gameserverallocation.go:128-156

Label Selectors

Use Kubernetes label matching:
spec:
  selectors:
    - matchLabels:
        agones.dev/fleet: my-fleet
        version: v1.2.0
    - matchExpressions:
        - key: tier
          operator: In
          values: ["premium", "standard"]
        - key: region
          operator: NotIn
          values: ["eu-west"]
Operators:
  • In: Value must be in the list
  • NotIn: Value must not be in the list
  • Exists: Key must exist (any value)
  • DoesNotExist: Key must not exist

Ordered Selectors

Selectors are evaluated in order. If no match is found, the next selector is tried:
spec:
  selectors:
    - matchLabels:  # Try canary fleet first
        agones.dev/fleet: game-canary
    - matchLabels:  # Fall back to stable fleet
        agones.dev/fleet: game-stable
This is useful for canary deployments, A/B testing, or gradual rollouts where you want to prefer specific GameServers but have fallbacks.

GameServer State Filter

Specify which state GameServers must be in: Source: gameserverallocation.go:132-135
spec:
  selectors:
    - matchLabels:
        agones.dev/fleet: my-fleet
      gameServerState: Ready  # or Allocated
States:
  • Ready (default): Allocate from available GameServers
  • Allocated: Re-allocate an already allocated GameServer (for reconnection scenarios)
Using gameServerState: Allocated requires the GameServer to already be allocated. This is primarily for reconnection flows where you want to retrieve an existing session.

Player Capacity Filters (Alpha)

Filter by available player slots: Source: gameserverallocation.go:158-162
spec:
  selectors:
    - matchLabels:
        agones.dev/fleet: my-fleet
      players:
        minAvailable: 4   # Need at least 4 player slots
        maxAvailable: 16  # But no more than 16
Feature Gate: PlayerAllocationFilter

Counter Filters (Beta)

Filter by Counter values and available capacity: Source: gameserverallocation.go:164-178
spec:
  selectors:
    - counters:
        rooms:
          minCount: 1        # At least 1 room active
          maxCount: 5        # But no more than 5
          minAvailable: 2    # At least 2 room slots available
          maxAvailable: 10   # But no more than 10
        sessions:
          minAvailable: 1    # At least 1 session slot
Available capacity = capacity - count Matching logic (gameserverallocation.go:294-318):
  • All specified counters must match
  • maxCount: 0 or maxAvailable: 0 means unlimited (max int64)
  • If Counter doesn’t exist on GameServer, it doesn’t match
Feature Gate: CountsAndLists

List Filters (Beta)

Filter by List values and available capacity: Source: gameserverallocation.go:180-192
spec:
  selectors:
    - lists:
        players:
          containsValue: "player-123"  # Must have this player
          minAvailable: 5               # Need 5+ open slots
          maxAvailable: 20              # But not more than 20
        rooms:
          minAvailable: 1               # At least 1 room slot
Available capacity = capacity - len(values) Matching logic (gameserverallocation.go:364-397):
  • All specified lists must match
  • containsValue checks if value exists in the list
  • maxAvailable: 0 means unlimited
  • If List doesn’t exist on GameServer, it doesn’t match
Feature Gate: CountsAndLists

Scheduling Strategies

Control how GameServers are selected when multiple matches exist: Source: gameserverallocation.go:108-109
Goal: Minimize infrastructure usage
spec:
  scheduling: Packed
Behavior:
  • Groups allocations on fewer nodes
  • Allows cluster autoscaler to scale down empty nodes
  • Picks GameServer from most utilized node first
Best for: Cloud environments with autoscaling

Priorities (Beta)

Define custom sorting for GameServer selection: Source: gameserverallocation.go:88-100
spec:
  priorities:
    - type: Counter     # Counter or List
      key: rooms        # Counter/List name
      order: Ascending  # Ascending or Descending
    - type: List
      key: players
      order: Descending
How priorities work:
  1. Position 0 has highest priority
  2. Compares available capacity between GameServers
  3. Ascending: Prefers GameServers with less available capacity
  4. Descending: Prefers GameServers with more available capacity
Impact by scheduling:
Priorities are a tie-breaker within the same node:
  • First, choose most utilized node (most GameServers)
  • Within that node, use priorities to pick the best GameServer
Feature Gate: CountsAndLists

Metadata Patching

Apply labels and annotations to the allocated GameServer: Source: gameserverallocation.go:111-113, gameserverallocation.go:552-564
spec:
  metadata:
    labels:
      session-id: "abc-123"
      game-mode: "deathmatch"
      player-count: "4"
    annotations:
      allocation-time: "2026-03-10T10:00:00Z"
      matchmaking-pool: "ranked-gold"
      server-region: "us-west"
Use cases:
  • Session tracking and identification
  • Debugging and observability
  • Custom routing or load balancing
  • Integration with external systems
Metadata is applied atomically with the allocation. If allocation fails, no metadata changes are made.

Counter and List Actions (Beta)

Modify Counters and Lists during allocation:

Counter Actions

Source: gameserverallocation.go:194-205, gameserverallocation.go:320-337
spec:
  counters:
    rooms:
      action: Increment   # or Decrement
      amount: 1           # Must be positive
      capacity: 20        # Optional: update max capacity
    sessions:
      capacity: 50        # Just update capacity
Actions:
  • Increment: Adds amount to current count (clamped to capacity)
  • Decrement: Subtracts amount from current count (clamped to 0)
  • Capacity: Updates maximum capacity
Validation (gameserverallocation.go:511-531):
  • amount must be positive
  • If action is set, amount must also be set
  • Both action and capacity can be specified together

List Actions

Source: gameserverallocation.go:207-218, gameserverallocation.go:339-362
spec:
  lists:
    players:
      addValues:
        - player-456
        - player-789
      deleteValues:
        - player-123  # Removed players
      capacity: 100   # Optional: update max capacity
Actions:
  • addValues: Appends unique values (duplicates ignored)
  • deleteValues: Removes specified values (non-existent values ignored)
  • capacity: Updates maximum capacity (0-1000)
Validation (gameserverallocation.go:533-544):
  • capacity must be 0-1000 if specified
  • Duplicate values in addValues are silently ignored
  • Non-existent values in deleteValues are silently ignored
Feature Gate: CountsAndLists

Allocation Response

Successful allocation returns connection details: Source: gameserverallocation.go:566-581
status:
  state: Allocated
  gameServerName: simple-fleet-7dv8s-vwpx5
  address: 192.168.1.100
  addresses:
    - type: ExternalIP
      address: 35.203.45.67
    - type: InternalIP  
      address: 10.1.2.3
  nodeName: gke-node-abc123
  ports:
    - name: default
      port: 7654
  source: local  # or remote cluster endpoint
  metadata:
    labels:
      session-id: abc-123
    annotations:
      map: dust2
  counters:
    rooms:
      count: 2
      capacity: 10
  lists:
    players:
      capacity: 100
      values:
        - player-456
        - player-789
Access the response:
# Get connection string
kubectl get gsa <name> -o jsonpath='{.status.address}:{.status.ports[0].port}'

# Get full response
kubectl get gsa <name> -o yaml

Performing Allocations

Via kubectl

# Create allocation
kubectl create -f gameserverallocation.yaml

# Or use generateName for unique names
kubectl create -f - <<EOF
apiVersion: allocation.agones.dev/v1
kind: GameServerAllocation
metadata:
  generateName: game-
spec:
  selectors:
    - matchLabels:
        agones.dev/fleet: simple-fleet
EOF

# Get allocation result
kubectl get gameserverallocation <name> -o jsonpath='{.status}'

Via Allocator Service

For production, use the allocator service (gRPC/REST):
# gRPC allocation (recommended)
grpcurl -proto allocation.proto \
  -H "authorization: Bearer ${TOKEN}" \
  ${ALLOCATOR_ENDPOINT}:443 \
  allocation.AllocationService/Allocate

# REST allocation
curl -X POST \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d @allocation.json \
  https://${ALLOCATOR_ENDPOINT}/v1/allocation
Benefits of Allocator Service:
  • Sub-second allocation latency
  • Multi-cluster allocation support
  • No need for Kubernetes credentials
  • Production-ready authentication

Multi-Cluster Allocation

Allocate across multiple Kubernetes clusters: Source: gameserverallocation.go:72-74
spec:
  multiClusterSetting:
    enabled: true
    policySelector:
      matchLabels:
        cluster.agones.dev/region: us-west
Requires:
  1. GameServerAllocationPolicy resources in each cluster
  2. Allocator service configured with multi-cluster support
  3. Network connectivity between allocator and target clusters
Multi-cluster allocation enables global GameServer pools, geographic routing, and cross-region failover.

Common Patterns

Session-Based Allocation

apiVersion: allocation.agones.dev/v1
kind: GameServerAllocation
metadata:
  generateName: session-
spec:
  selectors:
    - matchLabels:
        game-mode: deathmatch
      counters:
        sessions:
          maxCount: 0      # Any count
          minAvailable: 1  # Need at least 1 slot
  metadata:
    labels:
      session-id: "${SESSION_ID}"
      player-count: "${PLAYER_COUNT}"
  counters:
    sessions:
      action: Increment
      amount: 1

Region-Aware Allocation

spec:
  selectors:
    - matchLabels:  # Prefer local region
        region: us-west
        tier: premium
    - matchLabels:  # Fallback to any region
        tier: premium
  metadata:
    annotations:
      requested-region: us-west
      allocated-region: "${ACTUAL_REGION}"

Reconnection Flow

Retrieve an already-allocated GameServer:
spec:
  selectors:
    - matchLabels:
        session-id: "abc-123"  # Session identifier
      gameServerState: Allocated

Troubleshooting

No GameServers allocated (UnAllocated)

# Check if GameServers exist
kubectl get gs -l agones.dev/fleet=my-fleet

# Check GameServer states
kubectl get gs -l agones.dev/fleet=my-fleet -o jsonpath='{.items[*].status.state}'

# Verify selector matches
kubectl get gs -l <your-label-selector>

# Check counter/list values
kubectl get gs <name> -o jsonpath='{.status.counters}'
kubectl get gs <name> -o jsonpath='{.status.lists}'

Contention errors

Multiple allocations competing for the same GameServer:
# Check allocation request rate
kubectl get events --field-selector reason=AllocationContention

# Increase Fleet size to reduce contention
kubectl scale fleet my-fleet --replicas=20
Contention is expected under high load. Clients should retry with exponential backoff.

Allocation too slow

# Check allocator service latency (if using)
kubectl logs -n agones-system deploy/agones-allocator

# Verify scheduling strategy is appropriate
kubectl get fleet my-fleet -o jsonpath='{.spec.scheduling}'

# Consider using allocator service instead of kubectl
# (50-100x faster)

Best Practices

Use allocator service in production

The allocator service provides sub-second latency and multi-cluster support.

Implement retry logic

Handle Contention states with exponential backoff and retries.

Add session metadata

Use labels/annotations for tracking, debugging, and analytics.

Monitor allocation rates

Track allocation success rate and latency to right-size Fleets.

Next Steps

Allocator Service Setup

Configure the production allocator service

Multi-Cluster Allocation

Set up allocation across multiple clusters

Autoscaling

Automatically scale based on allocation demand

Session Management

Build robust session tracking with allocations

Build docs developers (and LLMs) love