English ▼
Skip to page content Skip to main navigation
e.g. "templates" or "datastore"

# Go Runtime Environment

App Engine builds and executes Go application code using a safe "sandboxed" environment. Your app receives web requests, performs work, and sends responses by interacting with this environment.

- Selecting the Go Runtime
- Requests and Domains
- Requests and HTTP
- Request Headers
- Responses
- The Request Timer
- The Sandbox
- Logging
- The Environment
- Limits

## Selecting the Go Runtime

App Engine knows to use the Go runtime environment for your application code when you use the tool named `appcfg.py` from the Go SDK with a configuration file named `app.yaml`. You select the Go runtime environment using the following configuration elements:

    runtime: go
    api_version: 3

The first element, `runtime`, selects the Go runtime environment.

The second element, `api_version`, selects which version of the Go runtime environment to use. As of this writing, the most recent version of the Go environment is `3`. The version identifier will be incremented when the App Engine team releases changes to the environment that may not be compatible with existing code. This means you can continue to use the older APIs until you are able to update your app and change the `api_version` setting.

During the Go runtime's "experimental" phase, the App Engine team may change the APIs in backwards-incompatible ways without updating the `api_version`. Please subscribe to the google-appengine-go mailing list to be notified of any significant API changes.

## Requests and Domains

App Engine determines that an incoming request is intended for your application using the domain name of the request. A request whose domain name is `http://your_app_id.appspot.com` is routed to the application whose ID is `your_app_id`. Every application gets an `appspot.com` domain name for free.

`appspot.com` domains also support subdomains of the form `subdomain.your_app_id.appspot.com`, where `subdomain` can be any string allowed in one part of a domain name (not `.`). Requests sent to any subdomain in this way are routed to your application.

You can set up a custom top-level domain using Google Apps. With Google Apps, you assign subdomains of your business's domain to various applications, such as Google Mail or Sites. You can also associate an App Engine application with a subdomain. For convenience, you can set up a Google Apps domain when you register your application ID, or later from the Administrator Console. See Deploying your Application on your Google Apps URL for more information.

Requests for these URLs all go to the version of your application that you have selected as the default version in the Administration Console. Each version of your application also has its own URL, so you can deploy and test a new version before making it the default version. The version-specific URL uses the version identifier from your app's configuration file in addition to the `appspot.com` domain name, in this pattern: `http://version_id.latest.your_app_id.appspot.com` You can also use subdomains with the version-specific URL: `http://subdomain.version_id.latest.your_app_id.appspot.com`

The domain name used for the request is included in the request data passed to the application. If you want your app to respond differently depending on the domain name used to access it (such as to restrict access to certain domains, or redirect to an official domain), you can check the request data (such as the `Host` request header) for the domain from within the application code and respond accordingly.

If your app uses backends, you can address requests to a specific backend and a specific instance with that backend. For more information about backend addressability, please see Properties of Backends.

## Requests and HTTP

The App Engine Go API uses the standard http package as an interface between your Go program and the App Engine servers. When App Engine receives a web request for your application, it invokes the http.Handler associated with the request URL. (The URL must also be specified as a Go handler in the application's `app.yaml` configuration file.)

App Engine uses multiple web servers to run your application, and automatically adjusts the number of servers it is using to handle requests reliably. A given request may be routed to any server, and it may not be the same server that handled a previous request from the same user. Multiple requests may be handled concurrently by a given server.

The following example is a complete Go app that outputs a hard-coded HTML string to the user.

    package hello

    import (
        "fmt"
        "http"
    )

    func init() {
        http.HandleFunc("/", hello)
    }

    func hello(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "<h1>Hello, world</h1>")
    }

## Request Headers

An incoming HTTP request includes the HTTP headers sent by the client. For security purposes, some headers are sanitized or amended by intermediate proxies before they reach the application.

As a service to the app, App Engine adds an additional header: `X-AppEngine-Country` This header's value represents the country from which the request originated, as an ISO 3166-1 alpha-2 country code. App Engine determines this code from the client's IP address.

## Responses

App Engine calls the handler with a `Request` and a `ResponseWriter`, then waits for the handler to write to the `ResponseWriter` and return. When the handler returns, the data in the `ResponseWriter`'s internal buffer is sent to the user.

This is practically the same as when writing normal Go programs that use the http package. The one notable difference is that App Engine does not support streaming data in response to a single request.

If the client sends HTTP headers with the request indicating that the client can accept compressed (gzipped) content, App Engine compresses the response data automatically and attaches the appropriate response headers. It uses both the `Accept-Encoding` and `User-Agent` request headers to determine if the client can reliably receive compressed responses. Custom clients can force content to be compressed by specifying both `Accept-Encoding` and `User-Agent` headers with a value of "gzip".

If you access your site while signed in using an administrator account, App Engine includes per-request statistics in the response headers. The header `X-AppEngine-Estimated-CPM-US-Dollars` represents an estimate of what 1,000 requests similar to this request would cost in US dollars. The header `X-AppEngine-Resource-Usage` represents the resources used by the request, including server-side time as a number of milliseconds.

## The Request Timer

A request handler has a limited amount of time to generate and return a response to a request, typically around 60 seconds. Once the deadline has been reached, the request handler is interrupted.

When a Go request handler exceeds the deadline, its process is terminated and the runtime environment returns an HTTP 500 server error to the client.

While a request can take as long as 60 seconds to respond, App Engine is optimized for applications with short-lived requests, typically those that take a few hundred milliseconds. An efficient app responds quickly for the majority of requests. An app that doesn't will not scale well with App Engine's infrastructure.

## The Sandbox

To allow App Engine to distribute requests for applications across multiple web servers, and to prevent one application from interfering with another, the application runs in a restricted "sandbox" environment. In this environment, the application can execute code, store and query data in the App Engine datastore, use the App Engine mail, URL fetch and users services, and examine the user's web request and prepare the response.

An App Engine application cannot:

- write to the filesystem. Applications must use the App Engine datastore for storing persistent data. Reading from the filesystem is allowed, and all application files uploaded with the application are available.
- open a socket or access another host directly. An application can use the App Engine URL fetch service to make HTTP and HTTPS requests to other hosts on ports 80 and 443, respectively.
- spawn a sub-process or thread. A web request to an application must be handled in a single process within a few seconds. Processes that take a very long time to respond are terminated to avoid overloading the web server.
- make other kinds of system calls.

The Go runtime restricts the use of standard library packages that would violate the sandbox policies. Such functions have been replaced by stubs that return an `os.EPERM` error or removed entirely.

## Logging

The Go API's Context object has `Debugf`,` Infof`,` Warningf`,` Errorf`, and` Criticalf` methods that send log messages to the App Engine web server.

Log data for your application can be viewed and analyzed using the Administration Console, or downloaded using appcfg.py request_logs.

The following example demonstrates an HTTP handler that constructs an `appengine.Context` object from the `*http.Request` and logs the requested URL.

    package hello

    import (
        "appengine"
        "http"
    )

    func init() {
        http.HandleFunc("/", Logger)
    }

    func Logger(w http.ResponseWriter, r *http.Request) {
        c := appengine.NewContext(r)
        c.Infof("Requested URL: %v", r.URL)
    }

## The Environment

The Go runtime provides access to environment information through the `appengine.Context` interface. See the `appengine` package reference for details.

## Quotas

Google App Engine allocates resources to your application automatically as traffic increases to support many simultaneous requests. However, App Engine reserves automatic scaling capacity for applications with low latency, where the application responds to requests in less than one second. Applications with very high latency (over one second per request for many requests) are limited by the system, and require a special exemption in order to have a large number of simultaneous dynamic requests. If your application has a strong need for a high throughput of long-running requests, you can request an exemption from the simultaneous dynamic request limit. The vast majority of applications do not require any exemption.

Applications that are heavily CPU-bound may also incur some additional latency in order to efficiently share resources with other applications on the same servers. Requests for static files are exempt from these latency limits.

Each incoming request to the application counts toward the Requests limit.

Data sent in response to a request counts toward the Outgoing Bandwidth (billable) limit.

Both HTTP and HTTPS (secure) requests count toward the Requests, Incoming Bandwidth (billable), and Outgoing Bandwidth (billable) limits. The Quota Details page of the Admin Console also reports Secure Requests, Secure Incoming Bandwidth, and Secure Outgoing Bandwidth as separate values for informational purposes. Only HTTPS requests count toward these values.

For more information on system-wide safety limits, see Limits, and the "Quota Details" section of the Admin Console.

In addition to system-wide safety limits, the following limits apply specifically to the use of request handlers:

Limit | Amount
--- | ---
request size | 32 megabytes
response size | 32 megabytes
request duration | 60 seconds
maximum total number of files (app files and static files) | 10,000 total 1,000 per directory
maximum size of an application file | 32 megabytes
maximum size of a static file | 32 megabytes
maximum total size of all application and static files | 150 megabytes