Kubernetes vs serverless on Google Cloud in 2023

Kubernetes vs serverless on Google Cloud in 2023
By Marco Lopes · Published May 9, 2023 · Cloud & DevOps
At Kordspace, we build software across AI, Web3, hardware and design, working as a remote collaborative studio. Google Cloud is our preferred cloud platform, although we also work with AWS and Azure. Across those projects, one infrastructure question keeps coming up: should we use Kubernetes or go serverless?
Our answer starts with the workload, not the platform. Kubernetes offers control and a broad ecosystem. Serverless removes much of the infrastructure work that can slow down a small team. Neither automatically makes an application cheaper, faster or more reliable.
As of May 2023, Google Cloud gives us several strong options. Here is how we evaluate them, and where we draw the line between useful flexibility and unnecessary complexity.
What we are actually comparing
On Google Cloud, Kubernetes usually means Google Kubernetes Engine (GKE). Google manages the Kubernetes control plane, while our responsibilities depend partly on the operating mode we choose.
With GKE Standard, we configure node pools and retain substantial control over the machines running our workloads. With GKE Autopilot, Google manages more of the underlying infrastructure, including node provisioning. We still work with Kubernetes resources, deployment patterns and policies.
For serverless, our main comparison is Cloud Run: a managed platform that runs containerized applications without requiring us to operate a cluster. Cloud Run services suit HTTP applications and event-driven consumers; Cloud Run jobs support containerized work that runs to completion.
Cloud Functions, including its second generation, is another option for focused, event-driven handlers. We generally prefer Cloud Run when we want an application packaged as a container, and consider functions when the unit of work is naturally a small handler.
These categories overlap. Autopilot reduces infrastructure administration, while Cloud Run still leaves application architecture, security and observability in our hands.
Our default: start with Cloud Run when it fits
For a new web application, API, webhook receiver or internal service, we usually evaluate Cloud Run first.
We can build a container, publish it to Artifact Registry and deploy it without designing a cluster. That keeps early engineering effort focused on product behavior rather than node sizing, pod placement or ingress configuration.
Cloud Run can scale services down to zero when unused, which is attractive for development environments and intermittent production workloads. Minimum instances let us keep capacity warm when latency matters, but they introduce a baseline cost. Serverless does not mean paying nothing between bursts under every configuration.
The strongest fit is a stateless application that starts reasonably quickly, accepts requests or supported events, and stores durable data elsewhere. A conventional API backed by Cloud SQL or Firestore is a good candidate.
We would not choose Kubernetes merely because the application has several services. Service count alone does not justify a cluster.
When Kubernetes earns its complexity
We lean toward GKE when requirements call for capabilities that Cloud Run does not provide, rather than because Kubernetes feels more production-ready.
Examples include specialized scheduling, GPU-backed workloads, Kubernetes operators, advanced networking, privileged workloads where supported, or processes that need a different execution model from request-driven services and run-to-completion jobs.
For AI projects, the difference between calling a managed model API and hosting a model ourselves is significant. An application calling an external inference endpoint may fit Cloud Run perfectly. Hosting inference that requires GPU resources pushes us toward another compute option, potentially GKE.
For Web3 work, an API that reads blockchain data is different from operating a full node with persistent storage, synchronization requirements and substantial resource needs. We should not deploy both using the same assumptions.
Kubernetes is also valuable when we already operate a mature platform with reusable deployment templates, monitoring and on-call ownership. Existing operational capability changes the calculation.
Autopilot or Standard is a separate decision
Choosing Kubernetes does not automatically mean choosing maximum infrastructure control.
We consider Autopilot when we want Kubernetes APIs and tooling without taking on routine node management. It can be a useful middle ground for teams that need orchestration flexibility but do not want infrastructure administration to dominate delivery.
However, Autopilot has workload restrictions and resource rules. We check compatibility before adopting it, especially for software requiring elevated privileges, unusual host access or tightly controlled node configurations.
Standard makes sense when those controls are genuinely necessary. It also gives us more ways to misconfigure capacity, security and upgrades.
Our practical rule is to write down the requirement that justifies each additional layer of control. If we cannot name it, we probably do not need it yet.
Compare total cost, not just compute prices
A useful cost comparison includes compute, databases, networking, load balancing, logging, build pipelines and engineering time.
Cloud Run is often attractive for variable or low-volume traffic because capacity follows demand. But consistently busy workloads deserve a closer comparison. Concurrency, CPU allocation, memory settings and minimum instances can materially affect the bill.
GKE can make sense for sustained workloads when we use capacity efficiently. Underused nodes, overly generous resource requests and duplicated environments can erase that advantage. Autopilot has a different billing model from Standard, so we model them separately rather than treating all GKE usage as identical.
We also include the cost of maintaining manifests, investigating scheduling problems, testing upgrades and responding to incidents. Those tasks may be worthwhile, but they are not free.
Before committing, we run a representative workload and inspect actual consumption. Pricing calculators help establish scenarios; they cannot tell us how our application behaves.
Scaling needs application-level safeguards
Autoscaling does not make downstream systems infinitely scalable.
A Cloud Run service can add instances quickly enough to overwhelm a database connection limit or third-party API. We set sensible maximum instance counts, tune request concurrency and use connection pools. Where supported and appropriate, we add rate limits and queue work instead of forwarding every burst immediately.
Concurrency deserves testing. A lightweight asynchronous API and a CPU-heavy image processor need different settings. Higher concurrency may improve utilization, but it can also increase latency and memory pressure.
GKE introduces its own coordination problem: scaling pods and obtaining node capacity are separate steps. We define resource requests carefully and test how the horizontal pod autoscaler and cluster capacity respond together.
For either platform, our load test includes spikes, downstream slowdown and recovery, not just a smooth increase in successful requests.
Background work and persistent data need deliberate design
We do not assume that work started during an HTTP request will reliably finish after the response returns. Cloud Run's default request-based CPU allocation is especially relevant here. Other CPU configurations are available, but instance lifecycle and interruption still matter.
For asynchronous work, we prefer explicit mechanisms such as Cloud Tasks, Pub/Sub or Cloud Run jobs, depending on delivery and execution requirements. Eventarc can connect supported events to services. We design consumers for retries and duplicate delivery rather than assuming exactly-once application behavior.
On GKE, Deployments, Jobs and CronJobs cover different process lifecycles. Choosing the right controller is part of making background processing reliable.
For durable state, our default is still a managed data service. Cloud SQL, Firestore and Cloud Storage address different needs; none is interchangeable with another. Kubernetes supports persistent volumes and StatefulSets, but running a database ourselves means owning backups, recovery, upgrades and availability.
We also check execution limits, temporary storage behavior and startup requirements before choosing a platform.
Networking and security can change the answer
We establish trust boundaries before deciding how convenient deployment should be.
For Cloud Run, we consider ingress restrictions, authenticated invocation and dedicated service accounts with narrowly scoped IAM permissions. When private network access is needed, we evaluate Serverless VPC Access and include its configuration and cost in the design.
On GKE, we consider private cluster configurations, network policies, workload identity, secrets access and the exposure of services through ingress or load balancers. More configuration options mean more decisions to review, not automatic security.
In both cases, we keep credentials out of container images, use Secret Manager where appropriate, and separate deployment permissions from runtime permissions. We also pay attention to image dependencies and provenance.
Managed infrastructure reduces some responsibilities. It does not remove our responsibility for application vulnerabilities, excessive permissions or accidentally public endpoints.
Reliability starts with objectives and ownership
We define acceptable latency, availability and recovery time before choosing a deployment topology.
Cloud Run reduces much of the platform maintenance burden, but we still need health-aware releases, useful logs, metrics and alerts. GKE adds cluster and workload concerns that require explicit ownership. A managed control plane does not make every application highly available.
We do not confuse a regional deployment with a complete disaster recovery strategy. Multi-region designs require traffic routing, data replication decisions and tested recovery procedures on either platform.
As a remote studio, we favor repeatable infrastructure definitions, documented runbooks and deployment pipelines that do not depend on one person's laptop. Terraform, Cloud Build and Artifact Registry can support that workflow across both options.
We want every alert to lead to an action, and every critical recovery procedure to be something we have tested.
Portability matters, but we keep it proportionate
Kubernetes provides a common orchestration API across Google Cloud, AWS, Azure and other environments. That is useful when there is a real portability requirement.
It does not make an application cloud-independent. Databases, identity systems, networking, storage classes and managed integrations still create migration work.
Cloud Run also uses container images, so application code can remain relatively portable even when deployment configuration is platform-specific. We preserve that flexibility through clean interfaces, externalized configuration and standard protocols where practical.
We avoid building a multi-cloud platform just to keep a hypothetical future option open. A documented migration path often provides better value than paying the operational cost of multiple platforms from day one.
Our short decision checklist
Before choosing, we ask:
- Execution: Does the workload fit requests, events or run-to-completion jobs?
- Resources: Do we need GPUs, host access or specialized scheduling?
- Demand: Is traffic intermittent, unpredictable or consistently high?
- Dependencies: Can databases and external services handle autoscaling bursts?
- Operations: Who owns upgrades, incidents, security reviews and recovery?
- Evidence: Have we tested startup time, concurrency, failure behavior and cost?
If Cloud Run meets the requirements, we usually start there. If a clear requirement points to Kubernetes, we evaluate Autopilot before taking on Standard's additional responsibilities.
A hybrid architecture is also valid: we might run a public API on Cloud Run and specialized processing on GKE. We choose that split only when its benefits outweigh the extra integration and operational work.
Choose the smallest platform that meets the need
In May 2023, our preference is not serverless at all costs or Kubernetes everywhere. We want enough infrastructure capability to deliver the product reliably, without creating a platform project that the product does not need.
If we can help turn these trade-offs into a practical architecture, start a project with Kordspace. For more about how we work across software, AI, Web3, hardware and design, explore our related services pages.
Conversation (0)
No comments yet. Start the conversation.
Join the conversation
Create a free member account to comment.