Managing App Engine services and versions — how to deploy new versions without downtime, migrate traffic, and keep your application running smoothly.
Services and Versions
Every App Engine application is built on two concepts:
- Service: A logical component of your application (e.g.,
default,api,worker). Each service has its ownapp.yaml, runtime, and scaling configuration. - Version: A specific deployment of a service. Multiple versions can coexist, and you control which versions receive traffic.
Application
├── Service: default
│ ├── Version: v1 (traffic: 0%)
│ ├── Version: v2 (traffic: 90%)
│ └── Version: v3 (traffic: 10%)
├── Service: api
│ └── Version: v1 (traffic: 100%)
└── Service: worker
└── Version: v1 (traffic: 100%)Key Insight: The service/version model is what makes zero-downtime deployments and traffic splitting possible. You deploy a new version alongside the old one, then shift traffic when ready.
Zero-Downtime Deployment
Deploying a new version does not affect the currently serving version. Traffic only moves when you explicitly tell it to.
The workflow
flowchart LR A["Deploy v2<br/>(--no-promote)"] --> B["Test v2<br/>via direct URL"] B --> C["Migrate traffic<br/>v1 → v2"] C --> D["Delete v1"]
Step 1: Deploy without promoting
gcloud app deploy --no-promote --version v2This creates version v2 but sends no traffic to it. Version v1 continues serving all requests.
Step 2: Test the new version
Access the new version directly via its URL:
https://v2-dot-default-dot-my-project.uc.r.appspot.comTest functionality, check logs, verify performance.
Step 3: Migrate traffic
When you’re confident the new version works:
# Immediate: all traffic to v2
gcloud app services set-traffic default --splits v2=1
# Gradual: 10% to v2, 90% to v1
gcloud app services set-traffic default --splits v1=0.9,v2=0.1 --split-by cookieStep 4: Clean up
# Delete the old version
gcloud app versions delete v1 --service=defaultTip: Always deploy with
--no-promotefor production services. Test the new version via its direct URL before migrating traffic. This is the safest deployment pattern.
Version Management Commands
# List all versions across all services
gcloud app versions list
# List versions for a specific service
gcloud app versions list --service=default
# Stop a version (stops all its instances)
gcloud app versions stop v1 --service=default
# Start a stopped version
gcloud app versions start v1 --service=default
# Delete a version permanently
gcloud app versions delete v1 --service=default
# View logs for a specific version
gcloud app logs tail --version=v2Version states
| State | Description | Instances | Billed |
|---|---|---|---|
| Serving | Receiving traffic | Running | Yes |
| Stopped | Not receiving traffic | Not running | No |
| Deleted | Permanently removed | None | No |
Warning: Stopped versions still exist in your project and consume a small amount of storage. Delete old versions you no longer need.
Service Management Commands
# List all services
gcloud app services list
# View service details
gcloud app services describe default
# Delete a service (cannot delete 'default')
gcloud app services delete api
# Set traffic for a service
gcloud app services set-traffic default --splits v2=1
# Browse the app in your browser
gcloud app browse
# Browse a specific service
gcloud app browse --service=apiTraffic Migration Strategies
Immediate migration
Route all traffic to the new version at once:
gcloud app services set-traffic default --splits v2=1Fast and simple. Best when you’re confident the new version works correctly.
Gradual migration
Shift traffic incrementally:
# Start with 5%
gcloud app services set-traffic default --splits v1=0.95,v2=0.05 --split-by cookie
# Monitor, then increase to 25%
gcloud app services set-traffic default --splits v1=0.75,v2=0.25 --split-by cookie
# Then 50%, then 100%
gcloud app services set-traffic default --splits v1=0.5,v2=0.5 --split-by cookie
gcloud app services set-traffic default --splits v2=1Best for production deployments where you want to catch issues early.
Rollback
If something goes wrong, route traffic back to the old version instantly:
gcloud app services set-traffic default --splits v1=1As long as the old version still exists and hasn’t been deleted, rollback is instant.
Note: Don’t delete the old version until you’re confident the new one is stable. Keep it around for at least a few hours after migration.
Deployment Best Practices
| Practice | Why |
|---|---|
Deploy with --no-promote | Prevents untested code from serving live traffic |
| Test via direct version URL | Verify functionality before traffic migration |
| Use traffic splitting for rollouts | Catch issues with a small percentage of traffic first |
| Keep old versions until stable | Enables instant rollback |
| Delete old versions regularly | Avoids storage costs and clutter |
| Use consistent version naming | --version vYYYYMMDDn or semantic versions |
| Monitor after migration | Check logs, error rates, latency for the new version |
| Deploy during low-traffic periods | Reduces risk during the transition |
Version Naming
By default, App Engine auto-generates version IDs based on the timestamp (e.g., 20240501t120000). You can specify your own:
# Semantic versioning
gcloud app deploy --version v2.1.0
# Date-based
gcloud app deploy --version 20260521
# Feature-based
gcloud app deploy --version new-checkoutTip: Use meaningful version names that make it easy to identify what’s deployed. Date-based or semantic versions work well.
Limits
| Limit | Value |
|---|---|
| Maximum services per application | 5 (free app), 210 (paid app) |
| Maximum versions per application | 15 (free app), 210 (paid app) |
| Maximum dispatch rules | 20 |
| Version ID length | 1-63 characters |
| Service name length | 1-63 characters, lowercase, hyphens allowed |
Note: Standard and Flexible versions share these limits within the same App Engine application.
TL;DR
- Deploy new versions with
--no-promoteto avoid sending traffic to untested code. - Test new versions via their direct URL before migrating traffic.
- Use gradual traffic migration for production deployments.
- Rollback is instant — just route traffic back to the old version.
- Delete old versions to save storage, but keep them around until the new version is verified.
- The
defaultservice must always exist and cannot be deleted. - Service and version limits depend on billing: 5 services / 15 versions for free apps, 210 services / 210 versions for paid apps.
Resources
Deploying an App Official guide to deploying and managing versions.
Splitting Traffic Traffic splitting and migration between versions.
gcloud app deploy Reference Command reference for the deploy command.
Traffic Splitting Detailed guide to traffic splitting strategies.
Core Components Architecture overview of services, versions, and instances.