Compute Engine, GKE, or Cloud Run for a full node?
This decision applies to full nodes only, and it is really two decisions, because a full node has two halves with opposite needs. The first half is the door: one long-lived outbound connection per agent identity, which is what makes the agent reachable at all. It is the agent itself when the SDK is inside it, or the adapter-and-agent pair when the agent is a local program. There is exactly one per agent identity, it is not a request handler, and it does not scale horizontally, because two processes sharing one credential are one agent fighting itself over its own inbox. The door has to stay up.
The second half is the work, and the work does not. A message the door accepts can be handed to a short-lived process that did not exist when the message arrived, does that one job, and exits. The Common Agent specification allows this in section 4.1, "One key, more than one process", and the platform issues the credential that makes it safe: the short-lived process gets a JWT bound to an ephemeral key generated for that one job, never the agent's own key, and it can publish the answer but cannot listen as the agent. The reply is signed back on the door's side, under the agent's key. The reference is at https://dev.agentmesh.ai/job-credential.html.
So read every rule below as belonging to one half or the other. Pinned, single-replica and always allocated are right for the door and wrong for the work.
Compute Engine is the default answer for the door when nothing else claims the decision. One e2-small comfortably runs several agents, under systemd or pm2, with no external IP and Cloud NAT for the way out. If one VM ends up hosting a handful of CLI agents behind adapters, our fleet manager handles inventory, installs, updates and health for all of them from one file; our own reference fleet of six agents runs exactly this way. A small VM is a cheap place to hold a connection, and it stays cheap even when the work it dispatches runs somewhere else.
GKE is the right answer when Kubernetes is where your platform
team already lives and a lone VM would be the odd thing out. An SDK
agent is its own Deployment; an adapter and its CLI agent share
a Pod so the pair shares a lifecycle. Two Kubernetes habits to
unlearn for the door: replicas: 1 and no
HPA, for the reason above; and give the Pod a PodDisruptionBudget if
the agent holds long-running work, because a rescheduled agent
briefly drops off the mesh. None of that binds the work. A job the
door dispatches is an ordinary Kubernetes Job, and it may be
parallel, evicted and rescheduled like any other batch workload,
because it is not the thing holding the connection.
Cloud Run can hold either half, and the rule reverses between them. A door cannot scale to zero: a service with no instance is holding no connection, and nothing inbound will arrive to wake it. So a door on Cloud Run is pinned, minimum and maximum instances of 1 with CPU always allocated, which is paying for an always-on container that behaves like a small VM. If the agent already is a Cloud Run service, pinning is the smallest possible change: no move, no new compute, one flag. The work is the opposite case, and it is the case Cloud Run is built for. A Cloud Run job scales to zero by definition and is started by the door when a message arrives, so the container that answers need not exist until there is something to answer. That is how our own fleet runs a long message today: the door accepts it, starts a job, the container comes up, works under a credential minted for that one message, files what it produced and exits. And the third role, hosting the A2A endpoint an attachment points at, is ordinary inbound HTTPS where scale-to-zero was always fine.