PlanyDocs
API reference

Shared types

Messages and enums used by more than one service — resource requirements, locations, money and the rest.

The LogLine object

LogLine is one line a game server wrote.

The unit is a line rather than a byte stream because that is the unit a pattern matches. Everything downstream — template matching, sampling for the model, the events themselves — works line by line, so splitting once at the source is cheaper than doing it in three places and disagreeing.

Attributes

  • observe_timeTimestampRequired

    When the server printed the line. Not when Plany received it: a server that could not reach Plany for ten minutes buffers its lines, and they keep their original times.

  • textstringRequired

    The line, verbatim and without its trailing newline.

    Verbatim matters: a template is a regular expression over exactly these bytes, so any normalisation here would silently invalidate every template learned before it was introduced.

  • streamStream

    Which stream it came from.

    Kept distinct because a game server that logs everything to stderr is common, and collapsing the two loses the only signal that something was actually wrong.

    STREAM_STDOUTSTREAM_STDERRSTREAM_AGENT
  • sequenceint64

    Monotonic sequence within one agent run, starting at 1.

    Two lines can share a timestamp — most servers log to the second — and ordering between a connect and the disconnect that follows it is the whole point. This is what breaks that tie.

LogLine
{
"observe_time": "2026-10-04T12:00:00Z",
"stream": "STREAM_STDOUT",
"text": "",
"sequence": "0"
}

The Player object

Player identifies who an event was about.

Every field is optional because games disagree on what a player is. Steam games have a 64-bit id and nothing else; Minecraft has a UUID and a name that can change; some games log only a name and an address. Requiring any one of them would exclude a game that never prints it.

Attributes

  • display_namestring

    Display name as the server printed it. Unstable — Minecraft names change and Steam personas change hourly — so it is for humans, not for joins.

  • player_idstring

    Stable identifier, when the game logs one: a Minecraft UUID, a SteamID64, an EOS product id. This is what a session is keyed on when it exists.

  • id_typestring

    Which namespace player_id belongs to, e.g. "steam", "minecraft", "eos". Two games can both log a 17-digit number and mean different things.

  • addressstring

    Source address, when logged.

    A personal datum, and a game server prints it unasked. It is kept because it is often the only stable identifier a game offers, and it is the field most likely to need suppressing per account — which is why it is separate rather than folded into attributes.

Player
{
"display_name": "My server",
"player_id": "my-player",
"id_type": "",
"address": ""
}

The ResourceRequirements object

ResourceRequirements is everything a workload needs to run: CPU, memory, disks, network interfaces, and where and how it is scheduled. Game servers and sandboxes express their needs in the same terms, so a number means the same thing — and is priced the same way — in both.

Attributes

  • cpuCpuSpecRequired
    Show child attributes
    • vcpusint32Required

      Number of virtual CPUs the workload sees. Required, must be at least 1.

    • reserved_millisint64

      CPU time reserved on the host, in millicores (1000 = one full core).

      Must be <= vcpus * 1000. Zero means "reserve the full vcpus * 1000", i.e. no oversubscription. Below that, the VM is burstable and the difference is the burst headroom.

    • limit_millisint64

      Hard ceiling on host CPU time, in millicores, enforced by the agent via cgroup cpu.max. Zero means the ceiling is vcpus * 1000. Set this below vcpus * 1000 to cap a burstable VM that would otherwise consume all idle capacity on the node.

    • architectureCpuArchitecture
      CPU_ARCHITECTURE_X86_64CPU_ARCHITECTURE_ARM64
    • required_featuresrepeated string

      CPUID feature flags the workload requires, lowercase as they appear in /proc/cpuinfo — e.g. "avx2", "aes". Placement rejects nodes lacking any of them. Anti-cheat and DRM in game servers occasionally depend on these.

    • dedicated_coresbool

      Pin each vCPU to a distinct physical core and let no other workload share those cores. Removes noisy-neighbour jitter for latency-sensitive tick loops, at the cost of a dedicated-core price.

    • isolate_smt_siblingsbool

      Require SMT siblings of the pinned cores to stay idle. Only meaningful with dedicated_cores; used for workloads that are sensitive to hyperthread contention or that need side-channel isolation.

  • memoryMemorySpecRequired
    Show child attributes
    • size_bytesint64Required

      Memory the workload sees, in bytes. Required.

    • reserved_bytesint64

      Memory guaranteed to the workload, in bytes. Must be no more than size_bytes. Zero means all of size_bytes is guaranteed.

      Reserving less than size_bytes requires balloon_enabled, so unused memory can be reclaimed when it is needed elsewhere.

    • balloon_enabledbool

      Allow memory the workload is not using to be reclaimed. Required when reserved_bytes is less than size_bytes.

    • hugepagesbool

      Back the workload's memory with 2 MiB pages. Noticeably faster for memory-heavy servers — large voxel worlds, big entity counts — but can only be placed where such memory is available.

    • hotplug_max_bytesint64

      Allow memory to grow to this size while running, without a restart. Zero disables it. Must be at least size_bytes when set.

    • sharedbool

      Allow identical memory pages to be shared with other workloads on the same machine. Saves memory when many servers run the same game, at some CPU cost and with weaker isolation between them.

  • Block devices, in attachment order. Exactly one must set boot unless the workload boots from an initramfs alone.

    Show child attributes
    • disk_idstringRequired

      Identifier for this disk within the workload, e.g. "root" or "world-data". Must be unique within it.

    • sourceDiskSpec.SourceRequired
      Show child attributes
      • imagestringOne of source

        Boot from a platform or project image, e.g. projects/{project}/locations/{location}/images/{image}. The image is copied (or CoW-cloned where the node supports it) into a fresh disk.

      • volumestringOne of source

        Attach an existing persistent volume by resource name. The volume must be in the same location and unattached.

      • snapshotstringOne of source

        Restore from a snapshot resource name.

      • blankboolOne of source

        Create an empty, zero-filled disk of size_bytes.

    • size_bytesint64

      Size of the device. Required for a blank disk; for an image or snapshot source, zero means "the source's own size" and any larger value grows the filesystem on first boot.

    • DISK_TYPE_LOCAL_NVMEDISK_TYPE_NETWORK_SSDDISK_TYPE_NETWORK_SSD_HIGH_IOPS
    • read_onlybool

      Attach read-only. Several instances may share one read-only volume, which is how a common asset bundle is mounted into many game servers at once.

    • bootbool

      Marks the disk the workload boots from. Exactly one disk may set this.

    • delete_on_instance_deletebool

      Delete the underlying storage when the instance is deleted. Always true in effect for LOCAL_NVME.

    • Show child attributes
      • bandwidth_bytes_per_secondint64

        Sustained bytes/second. Zero means unlimited.

      • bandwidth_burst_bytesint64

        Burst allowance in bytes above the sustained rate.

      • iopsint64

        Sustained IO operations/second. Zero means unlimited.

      • iops_burstint64

        Burst allowance in operations above the sustained rate.

    • direct_iobool

      Use direct IO (O_DIRECT), bypassing the host page cache. Lowers memory pressure on the node and makes latency more predictable, at the cost of losing host-side caching.

  • Show child attributes
    • interface_idstringRequired

      Stable identifier within the instance, e.g. "eth0".

    • networkstring

      Private network to attach to, as a resource name. Empty means the project's default network in this location.

    • private_ipv4string

      Requested private IPv4 address. Empty allocates one from the subnet.

    • PUBLIC_ADDRESS_MODE_NONEPUBLIC_ADDRESS_MODE_SHARED_IPV4PUBLIC_ADDRESS_MODE_DEDICATED_IPV4PUBLIC_ADDRESS_MODE_IPV6
    • NETWORK_TIER_STANDARDNETWORK_TIER_PREMIUM
    • Show child attributes
      • ingress_bits_per_secondint64

        Sustained bits/second. Zero means unlimited.

      • egress_bits_per_secondint64
      • ingress_burst_bitsint64

        Burst allowance in bits above the sustained rate.

      • egress_burst_bitsint64
      • ingress_packets_per_secondint64

        Packets/second ceiling, which is what actually protects a node from a small-packet flood. Zero means unlimited.

      • egress_packets_per_secondint64
    • mac_addressstring

      The interface's MAC address. Empty generates one. Pinning it matters for game licences tied to a MAC.

    • multi_queuebool

      Enable multi-queue virtio-net with one queue pair per vCPU. Raises packet throughput for servers handling many concurrent clients.

    • tagsrepeated string

      Network tags, which firewall rules on this interface's network target.

      Per interface rather than per instance because a rule belongs to one network, and an instance with an interface on each of two networks is answerable to two sets of rules. Lowercase letters, digits and hyphens, up to 63 characters each.

    • deny_inboundbool

      Refuse every inbound connection on this interface, whatever the network's firewall rules say. Replies to connections the workload opened still arrive.

      For an interface that exists so a workload can reach a network rather than be reached on it — a sandbox connected to one of your networks, for example.

    • no_default_routebool

      Send no internet traffic and no DNS through this interface: only the network's own range is reached through it. Without this, a workload with two interfaces could send its internet traffic out of either.

  • placementPlacementSpec
    Show child attributes
    • zonesrepeated string

      Zones the instance may land in, as location ids ("eu-west-2a"). Empty means any zone in the region. More than one entry is a preference list in priority order, not a hard set.

    • required_node_selectorsrepeated NodeSelectorRequirement

      Hard node requirements. A node must satisfy every entry.

      Show child attributes
      • keystringRequired
      • OPERATOR_INOPERATOR_NOT_INOPERATOR_EXISTSOPERATOR_DOES_NOT_EXISTOPERATOR_GREATER_THANOPERATOR_LESS_THAN
      • valuesrepeated string

        Values to match. Empty for EXISTS and DOES_NOT_EXIST; exactly one entry for GREATER_THAN and LESS_THAN.

    • preferred_node_selectorsrepeated NodeSelectorRequirement

      Soft node preferences. Nodes satisfying more of these score higher, but none of them can make placement fail.

      Show child attributes
      • keystringRequired
      • OPERATOR_INOPERATOR_NOT_INOPERATOR_EXISTSOPERATOR_DOES_NOT_EXISTOPERATOR_GREATER_THANOPERATOR_LESS_THAN
      • valuesrepeated string

        Values to match. Empty for EXISTS and DOES_NOT_EXIST; exactly one entry for GREATER_THAN and LESS_THAN.

    • placement_groupstring

      Group this workload belongs to, scoped to the project. Workloads sharing a group are spread out or packed together according to policy.

    • PLACEMENT_POLICY_PACKPLACEMENT_POLICY_SPREADPLACEMENT_POLICY_STRICT_SPREAD_NODEPLACEMENT_POLICY_STRICT_SPREAD_ZONE
    • capacity_classstring

      Class of capacity to draw from. Leave empty to let Plany choose, which is right for almost every workload.

    • disallow_preemptiblebool

      Refuse to place onto pre-emptible (spot) capacity. Spot is materially cheaper and fine for a dev server, but wrong for a ranked match in progress.

    • nodestring

      Pin to one node by resource name. Bypasses scoring entirely; intended for debugging and for rescheduling a VM back onto the node holding its local disk.

  • schedulingSchedulingSpec
    Show child attributes
    • ON_HOST_MAINTENANCE_MIGRATEON_HOST_MAINTENANCE_TERMINATE
    • RESTART_POLICY_NEVERRESTART_POLICY_ALWAYSRESTART_POLICY_ON_FAILURE
    • preemptiblebool

      Run as spot: on spare capacity, at the spot rate, reclaimable with two minutes' notice when an on-demand workload needs the room.

    • preemption_noticeDuration

      Warning given before a spot reclaim, readable at /metadata/spot/instance-action on the metadata service. The notice is always two minutes; leave this unset.

    • max_run_durationDuration

      Stop the instance automatically once it has run this long. Zero means no limit. This is the guard rail that stops a forgotten dev server draining a hobby account's credit overnight.

    • termination_grace_periodDuration

      Time between the shutdown signal and a forced stop, so a game server can save its world. Zero uses the default of thirty seconds.

    • preemptible_fallbackbool

      With preemptible: place as an ordinary on-demand workload when no spare capacity fits, rather than waiting for some. The allocation says which happened, and it is what the instance is billed at.

ResourceRequirements
{
"cpu": {
"vcpus": 0,
"reserved_millis": "0",
"limit_millis": "0",
"architecture": "CPU_ARCHITECTURE_X86_64",
"required_features": [
""
],
"dedicated_cores": false,
"isolate_smt_siblings": false
},
"memory": {
"size_bytes": "0",
"reserved_bytes": "0",
"balloon_enabled": false,
"hugepages": false,
"hotplug_max_bytes": "0",
"shared": false
},
"disks": [
{
"disk_id": "my-disk",
"source": {
"image": ""
},
"size_bytes": "0",
"type": "DISK_TYPE_LOCAL_NVME",
"read_only": false,
"boot": false,
"delete_on_instance_delete": false,
"io_limits": {
"bandwidth_bytes_per_second": "0",
"bandwidth_burst_bytes": "0",
"iops": "0",
"iops_burst": "0"
},
"direct_io": false
}
],
"network_interfaces": [
{
"interface_id": "my-interface",
"network": "",
"private_ipv4": "",
"public_address_mode": "PUBLIC_ADDRESS_MODE_NONE",
"tier": "NETWORK_TIER_STANDARD",
"rate_limits": {
"ingress_bits_per_second": "0",
"egress_bits_per_second": "0",
"ingress_burst_bits": "0",
"egress_burst_bits": "0",
"ingress_packets_per_second": "0",
"egress_packets_per_second": "0"
},
"mac_address": "",
"multi_queue": false,
"tags": [
""
],
"deny_inbound": false,
"no_default_route": false
}
],
"placement": {
"zones": [
""
],
"required_node_selectors": [
{
"key": "",
"operator": "OPERATOR_IN",
"values": [
""
]
}
],
"preferred_node_selectors": [
{
"key": "",
"operator": "OPERATOR_IN",
"values": [
""
]
}
],
"placement_group": "",
"policy": "PLACEMENT_POLICY_PACK",
"capacity_class": "",
"disallow_preemptible": false,
"node": ""
},
"scheduling": {
"on_host_maintenance": "ON_HOST_MAINTENANCE_MIGRATE",
"restart_policy": "RESTART_POLICY_NEVER",
"preemptible": false,
"preemption_notice": "300s",
"max_run_duration": "300s",
"termination_grace_period": "300s",
"preemptible_fallback": false
}
}

Enums

Confidence

Confidence says whether an event can be acted on.

ValueDescription
CONFIDENCE_UNSPECIFIED
CONFIDENCE_CONFIRMEDFrom a promoted template. Safe to bill and to act on.
CONFIDENCE_PROVISIONALFrom a template still being shadowed. Observe, do not act.

Stream

Stream identifies where a line came from.

ValueDescription
STREAM_UNSPECIFIED
STREAM_STDOUTThe server's normal output.
STREAM_STDERRIts error output.
STREAM_AGENTThe agent's own commentary — install progress, launch, shutdown. Interleaved with the server's output on purpose: "the server died" and "the agent asked it to" are much easier to correlate in one stream.