The app.yaml configuration file reference — all settings, common patterns, and best practices for configuring your App Engine services.
What is app.yaml?
app.yaml is the primary configuration file for every App Engine service. It defines how your application runs: the runtime, scaling behavior, environment variables, URL routing, and more. Every service must have one.
At minimum, it needs a runtime:
runtime: python312Everything else is optional, but most services need more configuration than this.
Standard Environment Settings
Required fields
runtime: python312 # Required. The language runtime version.Service and instance
# Service name (omit for 'default' service)
service: my-service
# Instance class (hardware allocation)
instance_class: F2 # F1 (default), F2, F4, F4_1G for automatic scaling
# B1, B2, B4, B8 for basic/manual scalingScaling configuration
Choose one of three scaling types:
Automatic scaling (default):
automatic_scaling:
min_instances: 0 # Scale to zero when idle
max_instances: 10 # Maximum instances
target_cpu_utilization: 0.6 # Scale up at 60% CPU
target_throughput_utilization: 0.6
max_concurrent_requests: 100
min_pending_latency: 30ms
max_pending_latency: automatic
min_idle_instances: 0
max_idle_instances: automaticBasic scaling:
instance_class: B2
basic_scaling:
max_instances: 5
idle_timeout: 10mManual scaling:
instance_class: B2
manual_scaling:
instances: 3Environment variables
env_variables:
NODE_ENV: "production"
DATABASE_URL: "postgres://user:pass@host:5432/db"
API_KEY: "your-api-key"Warning: Do not put secrets in
env_variables. Anyone with access to your source code or the App Engine console can read them. Use Secret Manager for sensitive values.
URL handlers
Handlers define how App Engine routes incoming requests:
handlers:
# Serve static files from /static directory
- url: /static
static_dir: static
expiration: "30d"
http_headers:
Cache-Control: "public, max-age=2592000"
# Serve a specific static file
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
# Pattern-match static files
- url: /(.*\.(gif|png|jpg|css|js))$
static_files: static/\1
upload: static/.*\.(gif|png|jpg|css|js)$
# Route everything else to your application
- url: /.*
script: auto
secure: always # Force HTTPS
login: admin # Require admin authenticationHandler settings
| Setting | Values | Description |
|---|---|---|
url | Regex pattern | URL pattern to match |
static_dir | Directory path | Serve all files in this directory |
static_files | File path | Serve a specific file |
upload | Regex pattern | Which files to upload with deployment |
script: auto | auto | Route to your application code |
secure | always, optional, never | HTTPS enforcement |
login | admin, required, optional | Authentication requirement |
expiration | Duration string | Cache expiration for static files |
http_headers | Key-value map | Custom HTTP headers for responses |
Error handlers
error_handlers:
- error_code: over_quota
file: over_quota.html
- error_code: dos_api_denial
file: dos_deny.html
- error_code: timeout
file: timeout.htmlInbound services
inbound_services:
- warmup # Enable warmup requests for pre-loadingFlexible Environment Settings
The Flexible environment uses env: flex and has additional configuration options:
runtime: python
env: flex # Required for flexible
# OR use custom runtime
# runtime: custom
# env: flex
# Resource allocation
resources:
cpu: 2
memory_gb: 4
disk_size_gb: 20
# VPC networking
network:
name: my-vpc
subnetwork_name: my-subnet
instance_ip_mode: INTERNAL
# Custom entrypoint
entrypoint: gunicorn -b :$PORT main:app
# Automatic scaling (flex)
automatic_scaling:
min_num_instances: 1
max_num_instances: 10
cpu_utilization:
target_utilization: 0.65
cool_down_period_sec: 120
# Manual scaling (flex)
# manual_scaling:
# instances: 3
# Health checks
liveness_check:
path: "/liveness"
check_interval_sec: 30
timeout_sec: 4
failure_threshold: 4
success_threshold: 2
readiness_check:
path: "/readiness"
check_interval_sec: 5
timeout_sec: 4
failure_threshold: 2
success_threshold: 2
app_start_timeout_sec: 300Flexible-only settings
| Setting | Description |
|---|---|
env: flex | Marks this as a Flexible environment config |
resources.cpu | Number of vCPUs (1, 2, 4, 8, etc.) |
resources.memory_gb | Memory in GB |
resources.disk_size_gb | Persistent disk size |
network | VPC network configuration |
entrypoint | Custom start command |
liveness_check | Health check for instance restart |
readiness_check | Health check for traffic routing |
beta_settings | Advanced features (e.g., Cloud SQL connection) |
Cloud SQL connection (Flexible)
beta_settings:
cloud_sql_instances: my-project:us-central1:my-instanceCommon Configurations
Minimal Python app
runtime: python312That’s it. App Engine uses sensible defaults for everything else.
Static website
runtime: python312
handlers:
- url: /
static_files: index.html
upload: index.html
- url: /(.*)
static_files: \1
upload: (.*)Node.js API with environment variables
runtime: nodejs20
instance_class: F2
env_variables:
NODE_ENV: "production"
automatic_scaling:
min_instances: 0
max_instances: 5Python app with Cloud SQL
runtime: python312
instance_class: F4
env_variables:
DB_HOST: "/cloudsql/my-project:us-central1:my-instance"
automatic_scaling:
min_instances: 1
max_instances: 10Java app with manual scaling
runtime: java21
instance_class: B4
manual_scaling:
instances: 2Flexible custom runtime
runtime: custom
env: flex
resources:
cpu: 2
memory_gb: 4
automatic_scaling:
min_num_instances: 1
max_num_instances: 5Best Practices
| Practice | Why |
|---|---|
Use secure: always | Force HTTPS on all requests |
| Use Secret Manager for secrets | env_variables are visible in the console |
Add app.yaml to .gitignore if it contains secrets | Prevents accidental credential exposure |
Set appropriate instance_class | Match instance size to your memory/CPU needs |
Use min_instances: 0 for cost savings | Scales to zero when there’s no traffic |
Use min_instances: 1 to avoid cold starts | Keeps one instance warm for low-latency responses |
| Enable warmup requests | Pre-load your app before real traffic arrives |
Set max_instances to cap costs | Prevents runaway scaling from unexpected traffic spikes |
| Use different services for different environments | Separate staging and production via service names |
Tip: Use separate GCP projects for staging and production (rather than different services) for better isolation. Services within the same project share quotas and billing.
TL;DR
app.yamlis the required configuration file for every App Engine service.- Minimum config: just
runtime: python312. Everything else has defaults. - Key sections: runtime, service, instance_class, scaling, env_variables, handlers.
- Standard uses F-class (auto scaling) or B-class (basic/manual) instances.
- Flexible adds
env: flex, resources, network, and health checks. - Never put secrets in
env_variables— use Secret Manager. - Always set
secure: alwaysto enforce HTTPS.
Resources
app.yaml Reference (Standard) Complete configuration reference for the Standard environment.
app.yaml Reference (Flexible) Complete configuration reference for the Flexible environment.
Secret Manager Documentation Secure storage for API keys, passwords, and certificates.
Scaling Options Detailed guide to automatic, basic, and manual scaling configuration.
Standard vs Flexible Environment differences that affect app.yaml settings.