ADK deployment — Agent Engine, Cloud Run, GKE
Three paths from local ADK agent to production. Agent Engine for fastest, Cloud Run for portability, GKE for full control. The trade-offs, with commands.
What you'll learn
- The three deployment targets ADK supports and what they cost in effort
- Agent Engine — managed Vertex AI service, push code, get an endpoint
- Cloud Run — your container, Google's serverless runtime
- GKE — when you need VPC, sidecars, or custom networking
Before you start
You’ve built an ADK agent locally with adk web. Now you need it
serving real users. ADK deliberately separates agent definition from
deployment: the same LlmAgent code runs unchanged whether it’s on
your laptop, on Cloud Run, or on Agent Engine — the deploy target is
a configuration choice, not a code change. This lesson is a tour of
the three targets — what each one is good for, what each one costs,
and the actual commands.
The three paths
| Target | Effort | Control | When to pick |
|---|---|---|---|
| Vertex AI Agent Engine | Lowest | Lowest | You want an endpoint, fast, and don’t need custom infra |
| Cloud Run | Medium | Medium | You want your own container, autoscaling, multi-cloud portability |
| GKE | Highest | Highest | You need VPC, sidecars, custom networking, or large scale |
A useful rule of thumb: start at Agent Engine. Move to Cloud Run when you need a custom container or a non-Vertex region. Move to GKE only when Cloud Run’s constraints become real blockers.
Option 1 — Agent Engine
Vertex AI Agent Engine is Google’s managed runtime for ADK agents. You push your agent module, Google provisions the infrastructure, and you get a stable endpoint. Sessions, scaling, and observability are handled.
# From the directory containing your agent module:
adk deploy agent_engine my_agent \
--project=my-gcp-project \
--region=us-central1 \
--display-name="research-agent"
What happens under the hood:
- ADK packages your agent (and its requirements) as a deployable bundle.
- Vertex AI provisions a managed endpoint with autoscaling and session storage.
- You get back a resource name like
projects/.../reasoningEngines/123— that’s your endpoint.
The API surface is simple — your service calls
reasoning_engines.query(input=...) and gets back the agent’s
response. No container, no Dockerfile, no Kubernetes.
The trade-offs. Agent Engine is opinionated: Vertex AI region selection, managed session storage, Google’s choice of autoscaling behavior. If those match your needs, you save days of infra work. If they don’t (e.g., you need a specific VPC, a non-Vertex region, or a sidecar for an internal proxy), you’ll outgrow it.
Option 2 — Cloud Run
Cloud Run gives you a serverless container runtime. You provide a Docker image; Google scales it from zero. ADK provides a deploy shortcut that builds and pushes the container for you.
adk deploy cloud_run my_agent \
--project=my-gcp-project \
--region=us-central1 \
--service-name=research-agent \
--port=8080
What you get vs. Agent Engine:
- Your own container. You control the Python version, base image, system dependencies, sidecars (e.g., for connecting to internal services).
- Cold starts. Cloud Run scales to zero, so first requests after idle pay a cold-start tax. For agents this can be 2-5 seconds — meaningful if you have spiky traffic. Min-instances mitigates it for a cost.
- Standard Cloud Run features. Custom domains, IAM, VPC connector for private resources, Cloud SQL Proxy sidecar, etc.
The agent runs as a web service. ADK scaffolds the server with a
POST /run endpoint (and a streaming variant). Your callers — a web
app, another service — hit the endpoint with the user message and
get back the agent’s response.
# Pseudocode of what ADK scaffolds for Cloud Run:
# from fastapi import FastAPI
# from google.adk.runners import Runner
# from my_agent import root_agent
#
# app = FastAPI()
# runner = Runner(agent=root_agent, ...)
#
# @app.post("/run")
# async def run(req: RunRequest):
# events = runner.run_async(user_id=req.user_id, ...)
# return [e async for e in events]
You don’t usually edit this — ADK regenerates it on each deploy. But knowing it’s a normal FastAPI service helps when you need to debug.
Option 3 — GKE
GKE (Google Kubernetes Engine) is the heavy-machinery option. You operate a cluster; you decide everything. ADK doesn’t deeply integrate here — you containerize your agent the normal way and deploy as a standard Kubernetes Deployment + Service.
# Build and push the container:
docker build -t gcr.io/my-project/research-agent:v1 .
docker push gcr.io/my-project/research-agent:v1
# Deploy with kubectl (or Helm, or ArgoCD, or whatever you use):
kubectl apply -f deployment.yaml
When GKE makes sense:
- You already operate GKE clusters and want one platform for all services. Hot-loading agents into your existing cluster beats spinning up a parallel deployment story.
- VPC and networking are restrictive. Air-gapped environments, custom service meshes, sidecars that must run alongside the agent.
- Scale is large. Tens of thousands of QPS, custom autoscalers, GPU-backed nodes for local model inference alongside the agent.
For most agent workloads, GKE is overkill. The honest answer is that GKE is the right call when you have Kubernetes-shaped problems — which is fewer teams than you’d think.
Sessions and state across deploys
Local dev uses InMemorySessionService. Production needs a persistent
backend so conversations survive restarts and scale-outs.
- Agent Engine. Managed session storage is included; you don’t configure it.
- Cloud Run / GKE. Wire in
VertexAiSessionService(managed Vertex sessions) or a custom backend on Cloud Firestore / Memorystore. The session service is just a pluggable interface; pick the one that matches your infra.
The decision tree below answers it: with no custom-container or cluster needs, Agent Engine is the call. The first thing that moves the answer is needing your own container — a sidecar, a system dependency, a non-Vertex region — which lifts you to Cloud Run.
Picking between them — a decision tree
The honest pattern in the field: most teams ship on Agent Engine, some migrate to Cloud Run for portability or custom container needs, a small minority run on GKE because they already do.
In one breath
- ADK separates agent definition from deployment — the same
LlmAgentcode runs unchanged on your laptop, Cloud Run, or Agent Engine; the target is a config choice. - Three targets, rising effort and control: Agent Engine (managed Vertex runtime — push code, get an endpoint), Cloud Run (your container, serverless, pays cold starts), GKE (full control, you operate the cluster).
- Start at Agent Engine; move to Cloud Run when you need a custom container or a non-Vertex region; reach for GKE only for real Kubernetes-shaped needs (VPC, sidecars, very large scale).
- Swap
InMemorySessionServicefor a persistent backend (Vertex sessions, Firestore, Memorystore) before production — in-memory state vanishes on restart or scale-out, and the agent “randomly forgets.” - The deploy target rarely dominates quality, cost, or latency — tokens, model, and prompt do. Pick the simplest deploy that works and spend your effort on the agent.
Quick check
Quick check
Next
That closes the ADK series. You’ve covered the agent core, tools, workflows, and deployment. Up next in the agentic-ai track: evals — how to actually measure whether an agent is good, and how to keep it good as you change prompts and models.
Practice this in an interview
All questionsKey risks include prompt injection, especially indirect injection via tool or retrieval outputs, hijacking the agent, excessive tool permissions enabling damaging actions, data exfiltration, confused-deputy privilege escalation, and unbounded loops driving cost or harm. Mitigations include least-privilege tools, sandboxing, input and output guardrails, human-in-the-loop approval for sensitive actions, and audit logging.
ReAct interleaves reasoning traces with actions step by step, deciding the next tool call based on the latest observation. Plan-and-Execute first drafts a full multi-step plan and then executes it, which is more efficient and predictable for complex tasks but less adaptive, while Reflexion adds a self-reflection step where the agent critiques past failures and retries with that feedback.
Distributed Data Parallel (DDP) replicates the full model on every GPU and synchronizes gradients each step, which is simple but requires the whole model to fit on one GPU. Fully Sharded Data Parallel (FSDP) shards parameters, gradients, and optimizer states across GPUs and gathers them on demand, drastically cutting per-GPU memory so you can train much larger models at the cost of extra communication.
An agent is an LLM placed in a loop where it reasons, chooses and calls tools or actions, observes the results, and repeats until a goal is met, rather than producing one response and stopping. The key differences are autonomy, tool use, memory and state, and multi-step control flow driven by the model's own decisions.