On this page
article
Google Cloud Functions Best Practices
Optimize GCP Cloud Functions — cold starts, memory, concurrency, secrets, monitoring, and cost control.
Production Cloud Functions require attention to performance, reliability, and cost — especially at scale.
Choose Gen 2 Functions
Always use 2nd gen functions for:
- Better concurrency (up to 1000 requests per instance)
- Longer timeouts (up to 60 minutes)
- Larger instance sizes (up to 16 GB RAM, 8 vCPUs)
- CloudEvent native triggers
- Traffic splitting for deployments
gcloud functions deploy my-func --gen2 ...
Minimize Cold Starts
# Initialize clients OUTSIDE the handler
from google.cloud import storage, firestore
storage_client = storage.Client()
db = firestore.Client()
@functions_framework.http
def handler(request):
# Reuses warm clients
bucket = storage_client.bucket("my-bucket")
...
Keep deployment packages lean:
# requirements.txt — only what you need
functions-framework==3.*
google-cloud-storage==2.*
# Don't pin google-cloud-core separately
Configure Concurrency
Gen 2 functions handle multiple requests per instance:
gcloud functions deploy my-func \
--gen2 \
--concurrency=80 \
--min-instances=1 \
--max-instances=100
| Setting | Use Case |
|---|---|
min-instances=1 |
Eliminate cold starts for APIs |
max-instances=10 |
Cost cap for unpredictable traffic |
concurrency=1 |
CPU-bound tasks (image processing) |
concurrency=80 |
I/O-bound API handlers |
Secrets Management
Never hardcode credentials:
from google.cloud import secretmanager
def get_secret(secret_id, project_id="my-project"):
client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_id}/secrets/{secret_id}/versions/latest"
response = client.access_secret_version(request={"name": name})
return response.payload.data.decode("utf-8")
API_KEY = get_secret("external-api-key")
Or mount secrets as environment variables in deployment:
gcloud functions deploy my-func \
--set-secrets="API_KEY=external-api-key:latest"
Structured Logging
import json
import logging
logger = logging.getLogger(__name__)
@functions_framework.http
def handler(request):
logger.info(json.dumps({
"severity": "INFO",
"message": "Request received",
"method": request.method,
"path": request.path,
}))
Cloud Logging automatically captures stdout/stderr from functions.
Monitoring & Alerting
Key metrics in Cloud Monitoring:
cloudfunctions.googleapis.com/function/execution_countcloudfunctions.googleapis.com/function/execution_timescloudfunctions.googleapis.com/function/active_instances- Error rate from Cloud Logging
Create alerts for error rate > 1% or p99 latency > 5s.
VPC Connector (Private Resources)
Access resources in a private VPC (Cloud SQL, Redis):
gcloud functions deploy my-func \
--gen2 \
--vpc-connector=projects/PROJECT/locations/REGION/connectors/my-connector \
--egress-settings=private-ranges-only
Cost Optimization
- Right-size memory — more memory = more CPU = potentially faster = cheaper
- Set max instances — prevent runaway costs
- Use min-instances sparingly — they run 24/7
- Batch Pub/Sub messages — process multiple per invocation
- Use Cloud Run for sustained high traffic (often cheaper)
Security Checklist
- Use least-privilege service accounts
- Secrets in Secret Manager, not env vars in source
- Validate all input in HTTP handlers
- Use
--no-allow-unauthenticatedfor internal functions - Enable VPC Service Controls for sensitive data
- Keep runtime updated (Python 3.12)
Related Chapters
These practices keep Cloud Functions reliable and cost-effective in production.