Migrating your App Engine app from Go 1.9 to Go 1.11

Learn how to migrate your existing App Engine app from the Go 1.9 runtime to the new Go 1.11 runtime of the App Engine standard environment.

Continuing to use the App Engine Go SDK

You can use App Engine APIs with the Go 1.11 runtime. However, we recommend you migrate to the Google Cloud Client Libraries which will make your app portable to any Google Cloud compute service.

For apps requiring the appengine package, you can use the publicly available google.golang.org/appengine package instead:

  1. Change your existing import "appengine" statements to:

    import "google.golang.org/appengine"
  2. Upgrade the google.golang.org/appengine package by running the following command:

    If you're using GOPATH:

    go get -u google.golang.org/appengine

    Alternatively, if you're using Go Modules:

    go get google.golang.org/appengine@'>=v1.2.0'

Changes to the App Engine Go 1.11 runtime

You might have to make some changes to your existing App Engine Go 1.9 app and your deployment process in order to use the App Engine Go 1.11 runtime. The key differences in the new runtime are outlined below:

Changes to the app.yaml file

The behavior of some elements in the app.yaml configuration file has been modified:

Element Change type Description
api_version Deprecated
runtime Modified Change the runtime element to specify runtime: go111
application_readable Deprecated
builtins Deprecated
includes Deprecated
login Deprecated The Go 1.11 runtime supports login, but it will not be supported in future Go runtimes. You should use alternative methods to authenticate users.
libraries Deprecated
threadsafe Deprecated All applications are presumed to be threadsafe, meaning an instance can handle multiple requests at the same time. If your application isn't threadsafe, set max_concurrent_requests to 1. Note that this may significantly increase your costs.
skip_files Deprecated Instead create a .gcloudignore file in the root directory where your app.yaml file is located. For more information, see the .gcloudignore reference.

For more information, see the app.yaml reference.

Creating a main package

Your service must include a package main statement in at least one source file.

Writing a main package

If your service doesn't already contain a main package, add the package main statement and write a main() function. At a minimum, the main() function should:

  • Read the PORT environment variable and call the http.ListenAndServe() function:

    port := os.Getenv("PORT")
    if port == "" {
    	port = "8080"
    	log.Printf("Defaulting to port %s", port)
    log.Printf("Listening on port %s", port)
    if err := http.ListenAndServe(":"+port, nil); err != nil {
  • Or, if your service is using the google.golang.org/appengine package, include a call to appengine.Main().

Registering your HTTP handlers

You can register your HTTP handlers by choosing one of the following options:

  • The preferred method is to manually move all http.HandleFunc() calls from your packages to your main() function in your main package.
  • Alternatively, import your application's packages into your main package, ensuring each init() function that contains calls to http.HandleFunc() gets run on startup.

    You can find all packages which use the http.HandleFunc() call with the following bash script, and copy the output into your main package's import block:

    gp=$(go env GOPATH) && p=$(pwd) && pkg=${p#"$gp/src/"} && find . -name "*.go" | xargs grep "http.HandleFunc" --files-with-matches | grep -v vendor/ | grep -v '/main.go' | sed "s#\./\(.*\)/[^/]\+\.go#\t_ \"$pkg/\1\"#" | sort | uniq

Structuring your files

Go requires that each package is in its own directory, so if you currently have a file structure similar to the following:

  • myapp/
    • app.yaml
    • bar.go
    • foo.go

You need to change it so that your main package is in a separate directory with your app.yaml file. Your final file structure should look like the following:

  • myapp/
    • bar.go
    • foo.go
    • web/
      • app.yaml
      • main.go

Moving files to your GOPATH

Find your GOPATH by using the following command:

go env GOPATH

Move all relevant files and imports to your GOPATH. If using relative imports, such as import ./guestbook, update your imports to use the full path: import github.com/example/myapp/guestbook.

Migrating from the App Engine Go SDK (Optional)

We strongly recommend using the Google Cloud client library or third party libraries instead of the legacy App Engine-specific APIs.

Concurrency settings

The Go 1.11 runtime ignores the threadsafe value in your project's app.yaml file. You can specify concurrency settings using the automatic_scaling: max_concurrent_requests setting in your app.yaml file.

The Go 1.9 runtime has a known issue of ignoring the max_concurrent_requests setting. The Go 1.11 and newer runtimes respect the value of the max_concurrent_requests setting in your project's app.yaml file.

If you set the value of max_concurrent_requests to less than 10, it possible your app will require more instances. We recommend you set the value of max_concurrent_requests to 10 or higher.