CloudBrum
CloudBrum · Cloud decision-support platform
Google Cloud App modernization

Google App EngineLast reviewedReading time~12 minLevelBeginner to advanced

Google Cloud · App modernization · Platform for web apps

Google’s original platform for web apps: you write the code, it runs the servers. You describe the app in an app.yaml file, deploy with one command, and App Engine runs it on instances it creates, patches and scales. There are two environments, and the choice shapes everything else. The standard environment runs your code in a sandbox, starts in seconds and can scale to zero. The flexible environment runs a Docker container on virtual machines, supports any language, and always keeps at least one instance. A project gets one App Engine app, and its region can’t be changed afterwards, so pick the region on purpose.

On this page (17 sections)

    Mind map: Google App Engine at a glance

    Google App Engine mind map Google App Engine at a glance: Environments: Standard (sandbox), Flexible (Docker), Choose per service; Structure: One app per project, Services, Versions; Configuration: app.yaml, dispatch.yaml, Env variables; Scaling: Automatic, Basic and manual, Scale to zero; Traffic: Traffic splitting, Gradual migration, Rollback; Neighbours: Cloud Tasks, Cloud Scheduler, Firestore; Security: Service account, Firewall rules, IAP; Pricing: Instance hours, Free daily quota, vCPU and memory. Google App Engine at a glance A platform for web apps on Google Cloud: the main building blocks and decisions CloudBrum Cloud decision-support platform CloudBrum Standard (sandbox) Flexible (Docker) Choose per service Environments One app per project Services Versions Structure app.yaml dispatch.yaml Env variables Configuration Automatic Basic and manual Scale to zero Scaling Traffic splitting Gradual migration Rollback Traffic Cloud Tasks Cloud Scheduler Firestore Neighbours Service account Firewall rules IAP Security Instance hours Free daily quota vCPU and memory Pricing App Engine17-point analysis CloudBrum· 17-point cloud service analysis cloudbrum.com
    CloudBrum App Engine at a glance · 17-point analysis Environments Standard (sandbox) Flexible (Docker) Choose per service Structure One app per project Services Versions Configuration app.yaml dispatch.yaml Env variables Scaling Automatic Basic and manual Scale to zero Traffic Traffic splitting Gradual migration Rollback Neighbours Cloud Tasks Cloud Scheduler Firestore Security Service account Firewall rules IAP Pricing Instance hours Free daily quota vCPU and memory CloudBrum · cloudbrum.com

    Free to share. The downloaded image includes the CloudBrum link.

    Key features (summary)

    • Deploy with one commandDescribe the runtime, the entry point and the scaling in app.yaml, run gcloud app deploy, and App Engine builds, uploads and starts the app. There are no servers or load balancers to create.
    • A sandboxed standard environmentThe standard environment runs your code on supported runtimes such as Python, Java, Go, Node.js, PHP and Ruby in a sandbox. Instances start in seconds, and an idle app can drop to zero instances.
    • Flexible when you need DockerThe flexible environment runs your container on Compute Engine virtual machines, so any language or library works. In return it’s slower to start and deploy, and it always keeps at least one instance.
    • Services and versionsOne app is split into services, such as a web front end and an API, and every deployment creates a version. Several versions can run at once.
    • Traffic splittingSend a share of requests to a new version by IP address, cookie or at random, watch it, and shift the rest, or roll back by moving the split.
    • Scaling you describeAutomatic scaling adds and removes instances based on CPU, throughput and latency targets you set. Basic and manual scaling give you fixed or request-driven instances for long-running work.
    • Access controlsA firewall in front of the app allows or blocks IP ranges, Identity-Aware Proxy puts sign-in in front of it, and a service account decides what the code may do in Google Cloud.
    • Friendly with other Google servicesCloud Tasks queues background work, Cloud Scheduler runs cron jobs, Firestore stores data and Cloud Logging and Error Reporting collect what the app emits.

    Basic concepts

    App Engine application
    The one App Engine app in a project. It’s created once, in a region you can’t change, and holds all the services.
    Service
    A part of the app with its own code and configuration, for example default and api. Services scale and deploy independently.
    Version
    One deployed snapshot of a service. A service can have many versions, and traffic is split between them.
    Instance
    One running copy of a version. App Engine starts and stops instances as load changes.
    Standard environment
    The sandboxed environment for supported runtimes, with fast start-up, scale to zero and a free daily allowance.
    Flexible environment
    The environment that runs a Docker container on Compute Engine VMs, with any runtime and a minimum of one instance.
    app.yaml
    The file that names the runtime, the entry point, the instance class, scaling settings, environment variables and handlers for a service.
    Instance class
    The size of a standard instance, such as F2 for automatic scaling or B2 for basic scaling, which sets memory and CPU.
    Automatic scaling
    Scaling that follows targets for CPU, throughput and latency, with limits on minimum, idle and maximum instances.
    Traffic splitting
    A setting that divides requests among versions by IP address, cookie or randomly, used for canary releases and A/B tests.
    dispatch.yaml
    A routing file that sends requests to services by URL pattern.
    Cloud Tasks and Cloud Scheduler
    The services that replaced the older task queue and cron.yaml features, for background work and scheduled calls.
    Serverless VPC Access
    A connector that lets an app reach resources in your VPC network, such as a private database.
    Identity-Aware Proxy
    A Google service that requires sign-in and an IAM role before a request reaches your app.

    How to create & configure it

    Deploy an app with gcloud

    1. Choose the project and the regionUse a project with billing. The App Engine region is fixed for the life of the project, so choose one near your users and data, such as asia-south1 (Mumbai).
    2. Create the app and the service accountRun gcloud app create with the region. Make a service account for the app with only the roles it needs, and use it instead of the default one.
    3. Write app.yamlName the runtime, the entry point (for example gunicorn for Python), the instance class, the scaling limits, environment variables and HTTPS-only handlers.
    4. Connect it to your network if neededIf the app talks to private resources, create a Serverless VPC Access connector and name it in app.yaml, with an egress setting that sends only private ranges through it.
    5. Deploy without promotingDeploy with --no-promote and a clear version name. The new version runs, but traffic stays on the old one.
    6. Test and split the trafficOpen the version’s own URL, then send a small share of requests to it with set-traffic. Watch errors and latency before moving the rest.
    7. Add schedules and a firewallCreate Cloud Scheduler jobs that call your handlers, and set firewall rules so that only the sources you expect can reach the app.
    8. Protect the front doorTurn on Identity-Aware Proxy for internal apps, or put a load balancer with Cloud Armor in front of public ones.
    9. Keep the version list tidyDelete old versions that no longer receive traffic. They cost nothing while stopped, but the list and the version limit grow.

    Tip: for a first deployment, gcloud app deploy from your project folder is enough. For anything shared, keep app.yaml in Git and the project settings in Terraform (see the code references). Also look at Cloud Run before you start, since many teams now begin new web services there.

    Common issues after configuration

    SymptomLikely causeWhat to check / fix
    Error 500 Server Error right after deploymentThe app crashed at start-up, the entry point is wrong, or a dependency is missingRead the logs in Cloud Logging, check the entrypoint in app.yaml and the requirements.txt or package.json, and test the same command locally.
    The app is not listening on the port or health checks fail (flexible)The container doesn’t listen on 8080, or it starts too slowly for the health checkListen on $PORT (8080 by default), tune the readiness and liveness checks, and raise the start-up time allowed.
    Permission denied calling Google APIs from the appThe app runs as a service account without the needed roleCheck the service account in app.yaml or the app settings, grant the role and wait a minute for IAM to catch up.
    Requests are slow after a quiet periodThe standard environment scaled to zero, so a request waits for a new instanceSet min_idle_instances to a small number, keep the app’s start-up work light and use warmup requests.
    The bill grew although traffic did notIdle instances, a high minimum or flexible instances that can’t scale to zero keep billingReview min_instances and min_idle_instances, use standard where it fits, and stop versions you don’t use.
    DeadlineExceededError or a 504 on long requestsThe request ran past its deadline, which depends on the scaling type and runtimeKeep requests short, move the work to Cloud Tasks or a background job, and use basic or manual scaling only for work that really needs a longer deadline.
    Traffic split settings are rejectedThe split must add up to 1.0, and the versions must be servingCheck that fractions sum to one, that the versions exist and that you picked a valid --split-by value.
    Can’t reach a private databaseNo VPC connector, or its egress setting doesn’t send the traffic into the VPCCreate a Serverless VPC Access connector in the same region, name it in app.yaml and allow the connector’s range in the firewall.
    Too many versions error when deployingApp Engine limits the number of versions per appList versions, delete the ones that aren’t receiving traffic and consider a cleanup step in your pipeline.
    gcloud app create fails because the app already existsA project can only have one App Engine app, and it was created earlierUse the existing app. Its region can’t be changed, so a different region means a new project.
    Cron jobs don’t runThe scheduler job has the wrong URL or service, or the handler requires a loginCheck the job’s target, the service and the HTTP method, and allow the scheduler’s requests in your handler or IAP settings.

    Use cases: when and where to use it

    Good fit

    • Web apps and APIs in a supported runtime where you want to deploy with app.yaml and no infrastructure
    • Apps with spiky or low traffic, which can scale to zero on the standard environment
    • Back ends for mobile and web apps that use Firestore, Cloud Tasks and other Google services
    • Existing App Engine apps that your team already knows and runs
    • Internal tools behind Identity-Aware Proxy
    • Apps made of a few services that you deploy and split traffic for separately

    Consider something else

    Pros: why consider it?

    Why teams choose it

    • Deploy with one command and no infrastructure to design
    • Scale to zero and a free daily allowance on the standard environment
    • Services, versions and traffic splitting built in
    • Tight links with Cloud Tasks, Cloud Scheduler, Firestore and logging
    • IAP and firewall rules in front of the app
    • Flexible environment for Docker when the sandbox is too limiting

    Trade-offs to weigh

    • One app per project, and the region can never change
    • The standard sandbox limits runtimes and system access, and custom Docker images aren’t supported there
    • Flexible always runs at least one instance and starts and deploys slowly
    • Less control than Cloud Run or Kubernetes over networking and scheduling
    • Many teams now prefer Cloud Run for new services, so examples and community energy lean that way
    • Some older bundled services are gone or replaced, which matters when you read old tutorials

    Common threats, vulnerabilities & risks

    RiskSeverityWhy it mattersMitigation
    Running as the default App Engine service accountHighThat account often has broad project rights, which a compromised app inherits.Create a dedicated service account with minimal roles and name it in app.yaml.
    A public app with no protectionHighAnyone can hit the app, including scanners and abusive clients.Use firewall rules, IAP for internal apps, and a load balancer with Cloud Armor for public ones.
    Choosing the wrong regionHighThe region is permanent for the project, so a mistake means a new project and a migration.Decide on the region with data location and latency in mind before creating the app.
    Secrets in app.yaml or GitMediumEnvironment variables in the file are visible to anyone with access to the repository.Read secrets from Secret Manager at start-up, using the service account.
    No maximum instance settingMediumA spike or a bug can scale instances, and the bill, and overload the database behind them.Set max_instances, and use connection pooling for the database.
    Flexible environment kept for simple appsMediumYou pay for always-on virtual machines and slower deploys when standard would do.Use standard where the runtime fits, or move the container to Cloud Run.
    Old versions piling upLow–MedThe version list grows and the limit is reached at an inconvenient time.Delete versions with no traffic in your pipeline.
    Outdated runtimeLow–MedRetired runtimes lose security fixes and may stop deploying.Track runtime support dates and upgrade on a version with no traffic first.
    Dependence on legacy bundled servicesLow–MedOld code that uses removed or replaced APIs breaks when the runtime changes.Move to Cloud Tasks, Cloud Scheduler, Firestore and Memorystore as part of the upgrade.

    Performance optimisation

    • Pick the instance class from measurements: a bigger class gives more CPU and memory per instance, and handles more concurrent requests.
    • Set min_idle_instances to a small number for user-facing services, so a quiet period doesn’t mean a cold start for the next visitor.
    • Tune target_cpu_utilization and max_concurrent_requests by load testing. Lower targets scale earlier at higher cost.
    • Keep start-up work light: lazy initialisation, small dependency sets and warmup handlers.
    • Serve static files through App Engine’s static handlers or Cloud CDN and keep instances for dynamic work.
    • Keep the app and its data in the same region, and use connection pooling for databases.
    • Move slow and background work to Cloud Tasks, which has retries and rate limits, instead of making users wait.
    • Check latency percentiles in Cloud Monitoring and Trace after each deployment, not just averages.

    Reduce monthly cost

    FinOps is the habit of managing cloud spend together with engineering. These are the FinOps checks that matter most for Google App Engine.

    • Know your meter: instance hours by class on the standard environment, and vCPU, memory and disk on flexible.
    • Use the free daily allowance of standard instance hours for small apps and test services. Sources disagree on the exact hours, so read Google’s page.
    • Let services scale to zero where a cold start is acceptable, and keep idle instances only where users would notice.
    • Set max_instances so a spike or a bug can’t scale the bill without limit.
    • Choose the smallest instance class that handles your concurrency, and raise concurrency where the code allows.
    • Prefer standard over flexible where the runtime fits, since flexible always bills for at least one instance.
    • Stop or delete old versions and unused services, and remember that flexible versions bill while running.
    • Watch data egress, Firestore operations and logging, which can grow faster than instance hours.
    • Use committed use discounts where they apply to flexible’s underlying resources.
    • Label the project by team, export billing to BigQuery and set budget alerts.

    Instance prices, the free daily allowance and flexible rates come from Google's pricing page and secondary sources as we read them in October 2026, and they differ by region and change over time. Check the live page before you plan around them (see Pricing).

    Security optimisation

    • Run the app as a dedicated service account with minimal roles, never the default one.
    • Use IAP for internal apps, so a Google sign-in and an IAM role are needed to reach them.
    • Set firewall rules that allow only expected source ranges, and put a load balancer with Cloud Armor in front of public apps.
    • Serve everything over HTTPS with secure: always handlers, and use Google-managed certificates for custom domains.
    • Keep secrets in Secret Manager and read them at start-up, and keep them out of app.yaml and Git.
    • Use a Serverless VPC Access connector or Direct VPC egress with firewall rules for private resources, and send only private ranges through it.
    • Validate input and authentication inside the app as well, since the platform can’t know your business rules.
    • Turn on Cloud Audit Logs and alert on IAM changes for the project and on unusual error rates.
    • Control who can deploy and delete versions with IAM roles such as App Engine Deployer, and keep App Engine Admin for few people.
    • Scan dependencies in your pipeline, and upgrade runtimes before they reach end of support.

    Governance & compliance

    Guardrails

    • Labels on the project and its resources (owner, environment, cost centre) enforced through Terraform modules and organisation policy
    • An organisation policy that restricts allowed locations, so the permanent App Engine region is chosen from an approved list
    • A shared Terraform module for App Engine apps, with a dedicated service account, firewall rules and IAP already set
    • A list of approved runtimes with a support end date for each, and an owner for every service that still runs on an old one

    Continuous checks (organisation policy and Security Command Center)

    • The gcp.resourceLocations constraint, which limits where an App Engine region may be chosen
    • A Security Command Center finding for services reachable from the whole internet
    • A check for App Engine versions that run as the default service account
    • A check for handlers that allow HTTP instead of secure: always
    • An alert on the number of versions per service nearing the limit

    Cloud Audit Logs record who deployed, changed or deleted versions and services, organisation policy limits where and how projects may be created, Security Command Center reports findings, and the Compliance resource center holds Google’s certificates. Google runs the platform, the instances and the scaling, while you own the code, the service account, the firewall and IAP settings, the region choice and the runtime upgrades.

    Reduce carbon footprint

    • Scale to zero for apps that are idle much of the day.
    • Right-size the instance class and raise concurrency where the code allows.
    • Prefer the standard environment, which uses no always-on virtual machine.
    • Delete unused versions, services and test projects.
    • Choose a region with a high carbon-free energy share when data rules allow. Google publishes the percentage for each region, and the App Engine region can’t be changed later.
    • Cache and compress responses, so fewer requests reach instances.
    • Cloud Carbon Footprint in the console estimates emissions per project and service. Check what it shows for App Engine before you quote a figure.

    Pricing

    Purchase options

    Standard environment Per instance-hour

    Billed by instance class while instances run, with a free daily allowance of instance hours. An app that scales to zero pays nothing for idle time.

    Flexible environment Per vCPU, GB of memory and disk

    Billed for the resources of the virtual machines that run your containers, for as long as they run, with at least one instance always up.

    Free quota Per day

    Standard has a free daily allowance. Sources give different numbers of free instance hours by class, so check Google’s page.

    Everything around it Varies

    Network egress, Firestore or Datastore operations and storage, Cloud Tasks, logging and monitoring, Memorystore and load balancers or Cloud Armor in front.

    What you actually pay for

    • Instance hours of the standard environment, minus the daily free allowance
    • vCPU, memory and disk of flexible instances while they run
    • Data stored and operations in Firestore or Datastore
    • Network egress, logging and monitoring
    • Load balancers, Cloud Armor, VPC connectors and any other service in front of or behind the app

    Rates differ by region and instance class and can change. See the official App Engine pricing page, the Google Cloud Pricing Calculator and Google's comparison of the standard and flexible environments.

    Important code references

    The orders-api app in the App Engine standard environment: a dedicated service account, automatic scaling with one idle instance, HTTPS-only handlers, a VPC connector for private traffic, a firewall and a nightly Cloud Scheduler job. The gcloud tab deploys a new version without traffic and splits 10% of requests to it. Terraform builds the app and a version. The Python tab deletes old versions that get no traffic, and the C# tab lists versions with their traffic share. Replace the project, bucket and connector with your own. The region can’t be changed once the app exists, so check it before you run the first command.

    # Placeholders: replace the project, bucket and connector range with your own.
    PROJECT=my-orders-project
    REGION=asia-south1
    BUCKET=orders-receipts-example
    SA=orders-api@$PROJECT.iam.gserviceaccount.com
    
    gcloud config set project $PROJECT
    gcloud services enable appengine.googleapis.com cloudbuild.googleapis.com vpcaccess.googleapis.com cloudscheduler.googleapis.com
    
    # One narrow service account for the app. The region you pick here is permanent for the project.
    gcloud iam service-accounts create orders-api --display-name="orders-api"
    gcloud storage buckets add-iam-policy-binding gs://$BUCKET --member="serviceAccount:$SA" --role=roles/storage.objectCreator
    gcloud app create --region=$REGION --service-account=$SA
    
    # A connector so the app can reach private addresses in the VPC.
    gcloud compute networks vpc-access connectors create orders-conn --region=$REGION --network=orders-net --range=10.8.0.0/28
    
    cat > app.yaml <<EOF
    runtime: python313
    entrypoint: gunicorn -b :\$PORT -w 2 main:app
    instance_class: F2
    service_account: $SA
    env_variables:
      RECEIPT_BUCKET: "$BUCKET"
    automatic_scaling:
      min_idle_instances: 1
      max_instances: 10
      target_cpu_utilization: 0.65
      max_concurrent_requests: 40
    vpc_access_connector:
      name: projects/$PROJECT/locations/$REGION/connectors/orders-conn
      egress_setting: private-ranges-only
    handlers:
      - url: /.*
        script: auto
        secure: always
    EOF
    
    # Deploy the new version without sending it any traffic, then send it 10 percent of requests.
    gcloud app deploy app.yaml --version=v150 --no-promote --quiet
    gcloud app services set-traffic default --splits=v142=0.9,v150=0.1 --split-by=random --quiet
    gcloud app versions list --service=default --sort-by=~version.createTime --limit=5
    
    # Only the office may reach the app. The default rule is the last one that is checked.
    gcloud app firewall-rules create 100 --action=allow --source-range=203.0.113.0/24 --description="office"
    gcloud app firewall-rules update default --action=deny
    
    # A nightly call to /tasks/reconcile.
    gcloud scheduler jobs create app-engine orders-nightly --location=$REGION --schedule="30 20 * * *" --time-zone="UTC" \
      --service=default --relative-url=/tasks/reconcile --http-method=POST
    # Placeholders: pass in your project and the object in Cloud Storage that holds the zipped app.
    variable "project_id" {
      type = string
    }
    
    variable "location_id" {
      type    = string
      default = "asia-south1"
    }
    
    variable "source_bucket" {
      type = string
    }
    
    variable "source_object" {
      type    = string
      default = "orders-api-1.5.0.zip"
    }
    
    variable "receipt_bucket" {
      type    = string
      default = "orders-receipts-example"
    }
    
    resource "google_service_account" "orders_api" {
      account_id   = "orders-api"
      display_name = "orders-api"
    }
    
    resource "google_storage_bucket_iam_member" "receipts" {
      bucket = var.receipt_bucket
      role   = "roles/storage.objectCreator"
      member = "serviceAccount:${google_service_account.orders_api.email}"
    }
    
    # The App Engine app: one per project, and the location cannot be changed after this.
    resource "google_app_engine_application" "app" {
      project     = var.project_id
      location_id = var.location_id
    }
    
    resource "google_app_engine_standard_app_version" "v150" {
      version_id = "v150"
      service    = "default"
      runtime    = "python313"
    
      entrypoint {
        shell = "gunicorn -b :$PORT -w 2 main:app"
      }
    
      deployment {
        zip {
          source_url = "https://storage.googleapis.com/${var.source_bucket}/${var.source_object}"
        }
      }
    
      instance_class  = "F2"
      service_account = google_service_account.orders_api.email
    
      env_variables = {
        RECEIPT_BUCKET = var.receipt_bucket
      }
    
      automatic_scaling {
        max_concurrent_requests = 40
        min_idle_instances      = 1
    
        standard_scheduler_settings {
          target_cpu_utilization = 0.65
          max_instances          = 10
        }
      }
    
      handlers {
        url_regex      = "/.*"
        security_level = "SECURE_ALWAYS"
    
        script {
          script_path = "auto"
        }
      }
    
      # keep the version after a destroy of this resource, and don't stop the service with it
      noop_on_destroy           = true
      delete_service_on_destroy = false
    
      depends_on = [google_app_engine_application.app]
    }
    
    # 90 percent of requests stay on the old version, 10 percent go to the new one.
    resource "google_app_engine_service_split_traffic" "default" {
      service         = "default"
      migrate_traffic = false
    
      split {
        shard_by = "RANDOM"
        allocations = {
          "v142" = 0.9
          "v150" = 0.1
        }
      }
    
      depends_on = [google_app_engine_standard_app_version.v150]
    }
    
    resource "google_app_engine_firewall_rule" "office" {
      project      = var.project_id
      priority     = 100
      action       = "ALLOW"
      source_range = "203.0.113.0/24"
      description  = "office"
    
      depends_on = [google_app_engine_application.app]
    }
    # Deletes old versions of a service that receive no traffic, keeping the newest few for a quick rollback.
    # pip install google-cloud-appengine-admin   (uses Application Default Credentials)
    import sys
    
    from google.cloud import appengine_admin_v1
    
    
    def old_versions(project, service="default", keep=3):
        services = appengine_admin_v1.ServicesClient()
        versions = appengine_admin_v1.VersionsClient()
    
        split = services.get_service(name="apps/%s/services/%s" % (project, service)).split
        serving = {v for v, share in split.allocations.items() if share > 0}
    
        parent = "apps/%s/services/%s" % (project, service)
        every = sorted(versions.list_versions(parent=parent), key=lambda v: v.create_time, reverse=True)
        newest = {v.id for v in every[:keep]}
        return [v for v in every if v.id not in serving and v.id not in newest]
    
    
    if __name__ == "__main__":
        project = sys.argv[1]
        dry_run = "--delete" not in sys.argv
        versions = appengine_admin_v1.VersionsClient()
        for v in old_versions(project):
            print(("would delete" if dry_run else "deleting"), v.name)
            if not dry_run:
                versions.delete_version(name=v.name).result()
    // dotnet add package Google.Cloud.AppEngine.V1
    // Lists the services of an App Engine app, their traffic split and the versions of each, newest first.
    // Uses Application Default Credentials (gcloud auth application-default login, or the service account on the machine).
    using Google.Cloud.AppEngine.V1;
    
    string project = args.Length > 0 ? args[0] : throw new ArgumentException("Usage: versions <project>");
    
    ServicesClient services = await ServicesClient.CreateAsync();
    VersionsClient versions = await VersionsClient.CreateAsync();
    
    await foreach (Service service in services.ListServicesAsync(new ListServicesRequest { Parent = $"apps/{project}" }))
    {
        string id = service.Id;
        var split = string.Join(", ", service.Split.Allocations.Select(a => $"{a.Key}={a.Value:P0}"));
        Console.WriteLine($"{id}  traffic: {(split.Length == 0 ? "none" : split)}");
    
        var list = new List<Google.Cloud.AppEngine.V1.Version>();
        await foreach (var v in versions.ListVersionsAsync(new ListVersionsRequest { Parent = $"apps/{project}/services/{id}" }))
            list.Add(v);
    
        foreach (var v in list.OrderByDescending(v => v.CreateTime.ToDateTime()))
        {
            bool serving = service.Split.Allocations.TryGetValue(v.Id, out var share) && share > 0;
            Console.WriteLine($"    {v.Id,-10} {v.ServingStatus,-8} runtime={v.Runtime,-10} {(serving ? "gets traffic" : "idle")}");
        }
    }

    Best videos to explore

    Videos picked for this service. Each one is labelled with its source, opens on YouTube if you prefer, and loads only when you press play.

    App Engine in a minuteOfficial · Google Cloud · Beginner · Watch on YouTube
    Ep. 13 Google App Engine Tutorial For BeginnersCommunity video · Beginner · Watch on YouTube
    App Engine Tutorial: Google Cloud Platform as a Service (PaaS) for BeginnersCommunity video · Beginner · Watch on YouTube
    Deploy Python Application on Google App Engine StandardCommunity video · Intermediate · Watch on YouTube

    Interview questions

    BasicWhat is Google App Engine?

    It’s Google Cloud’s fully managed platform for web applications. You describe your app in an app.yaml file and deploy with one command, and App Engine runs it on instances it creates, patches and scales. It comes in a standard environment (sandboxed runtimes) and a flexible environment (Docker containers).

    BasicWhat is the difference between the standard and flexible environments?

    Standard runs your code on supported runtimes in a sandbox, starts instances in seconds, can scale to zero and has a free daily allowance, but doesn’t accept custom Docker images. Flexible runs your Docker container on Compute Engine VMs, supports any language and library, but starts and deploys in minutes, always keeps at least one instance and bills for vCPU, memory and disk.

    BasicCan I change the region of an App Engine app?

    No. A project can have only one App Engine app, and its region is fixed when you create it. If you chose the wrong one, you need a new project. Decide on the region with data location rules and latency in mind before running gcloud app create.

    IntermediateHow do services and versions work together?

    An app is made of services, such as a web front end and an API, and each deployment of a service creates a version. Several versions can run at once, and you split traffic between them by IP address, cookie or randomly. That’s how you run a canary release or roll back.

    IntermediateHow do you release a new version of an App Engine service safely?

    Deploy with --no-promote so the new version gets no traffic, test it on its own URL, then use set-traffic to send a small share of requests, watch errors and latency, and move the rest in steps. Keep the old version for a quick rollback, and delete it once you’re confident.

    IntermediateWhy are requests slow after a quiet period on the standard environment?

    The app scaled to zero, so a request has to wait for a new instance to start. Set min_idle_instances for user-facing services, keep start-up work light and use warmup requests. The trade-off is that idle instances cost money.

    AdvancedHow would you choose between App Engine and Cloud Run for a new web service?

    Cloud Run takes any container, scales to zero, has long request timeouts and flexible billing, so it suits many new services. App Engine standard suits teams that like the app.yaml model, the built-in services and versions and traffic splitting, and apps already written for it. For existing App Engine apps, moving is optional and should be planned, not forced.

    AdvancedHow do you give an App Engine app access to private resources safely?

    Use a Serverless VPC Access connector (or Direct VPC egress where available), name it in app.yaml, send only private ranges through it with the egress setting, and allow the connector’s range in the firewall of the database. Run the app as its own service account with minimal roles, and pool database connections so a scale-out doesn’t exhaust them.

    AdvancedHow would you replace the old task queue and cron features in a legacy App Engine app?

    Use Cloud Tasks for background work, with an HTTP target in your app that handles each task and returns success or failure for retries, and Cloud Scheduler for cron jobs, calling an App Engine handler with the right service and URL. Secure the handlers so that only those callers can reach them, for example with IAP or a header check.

    AdvancedWhat would you do about an App Engine app that runs on an old runtime?

    Check the runtime’s support dates, test the newer runtime on a new version that receives no traffic, replace removed bundled APIs with Cloud Tasks, Cloud Scheduler, Firestore and Memorystore, and then migrate traffic in steps. Use the version limit and traffic splitting to keep a fast path back.

    Similar or alternative services on other clouds

    CapabilityAWSAzureGoogle Cloud
    ServiceAWS Elastic BeanstalkAzure App ServiceGoogle App Engine
    Deploy unitZip, WAR or Docker setupZip, container or source from GitSource code plus app.yaml, or a Docker image on flexible
    Scale to zeroNoNoYes on the standard environment
    What you pay forThe resources it creates, nothing for the serviceThe plan, per instance-hourInstance hours, with a free daily allowance on standard
    Release strategyDeployment policies and CNAME swapDeployment slots and swapVersions with traffic splitting
    MicroservicesSeveral environments per applicationSeveral apps on a planServices inside one app
    Region choiceChosen per environmentChosen per planOne region per project, permanent
    DirectionActive, old platform branches retireActiveActive, many new services start on Cloud Run

    If you want containers that scale to zero without the App Engine model, look at Cloud Run. For small event-driven functions use Cloud Run functions, and for Kubernetes use Google Kubernetes Engine. App Engine apps usually keep relational data in Cloud SQL and files in Cloud Storage.

    Did you find this article helpful?

    Your answer helps us improve this page for the next reader.

    Sources and further reading

    CloudBrum wrote this page in its own words, using the provider’s public documentation listed below as the reference. Features, limits, names and prices change, so confirm anything that matters on the provider’s own pages before you decide.