# Technical Documentation: golang/oauth2

> ℹ️ **Provenance:** Hybrid Fusion: `golang/oauth2` + `golang/website` · [CodeWiki Reference](https://codewiki.google/github.com/golang/oauth2) · Recency: Active (< 180 days)

## 1. Project Overview & Quickstart (golang/oauth2)

# OAuth2 for Go

[](https://pkg.go.dev/golang.org/x/oauth2)
[](https://travis-ci.org/golang/oauth2)

oauth2 package contains a client implementation for OAuth 2.0 spec.

See pkg.go.dev for further documentation and examples.

* [pkg.go.dev/golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2)
* [pkg.go.dev/golang.org/x/oauth2/google](https://pkg.go.dev/golang.org/x/oauth2/google)

## Policy for new endpoints

We no longer accept new provider-specific packages in this repo if all
they do is add a single endpoint variable. If you just want to add a
single endpoint, add it to the
[pkg.go.dev/golang.org/x/oauth2/endpoints](https://pkg.go.dev/golang.org/x/oauth2/endpoints)
package.

## Report Issues / Send Patches

The main issue tracker for the oauth2 repository is located at
https://github.com/golang/oauth2/issues.

This repository uses Gerrit for code changes. To learn how to submit changes to
this repository, see https://go.dev/doc/contribute.

The git repository is https://go.googlesource.com/oauth2.

Note:

* Excluding trivial changes, all contributions should be connected to an existing issue.
* API changes must go through the [change proposal process](https://go.dev/s/proposal-process) before they can be accepted.
* The code owners are listed at [dev.golang.org/owners](https://dev.golang.org/owners#:~:text=x/oauth2).

## 2. Official Technical Reference & Guides (golang/website)

## File: README.md

# Go website

[](https://pkg.go.dev/golang.org/x/website)

This repo holds content and serving programs for the go.dev and golang.org web sites.

Content is in \_content/ (go.dev) and tour/ (go.dev/tour).
Server code is in cmd/ and internal/.

To run the combined go.dev+golang.org server to preview local content changes, use:

    go run ./cmd/golangorg

The supporting programs cmd/admingolangorg and cmd/googlegolangorg
are the servers for admin.golang.org and google.golang.org.
(They do not use the \_content/ directories.)

Each command directory has its own README.md explaining deployment.

## JS/TS/CSS Formatting

This repository uses [eslint](https://eslint.org/) to format JS and TS files,
and [stylelint](https://stylelint.io/) to format CSS files.

See also:

- [CSS](https://go.dev/wiki/CSSStyleGuide)
- [JavaScript](https://google.github.io/styleguide/jsguide.html)
- [TypeScript](https://google.github.io/styleguide/tsguide.html)

It is encouraged that all JS, TS, and CSS code be run through formatters before
submitting a change. However, it is not a strict requirement enforced by CI.

### Installing npm Dependencies:

1. Install [docker](https://docs.docker.com/get-docker/)
2. Create a .gitignore file at repo root
3. Add .gitignore and node_modules to .gitignore
4. Run `./npm install`

### Run ESlint

    ./npx eslint [options] [file] [dir]

### Run Stylelint

    ./npx stylelint [input] [options]

## TypeScript Support

TypeScript files served from _content are transformed into JavaScript.
Reference .ts files in html templates as module code.

  `<script type="module" src="/ts/filename.ts">`

Write unit tests for TypeScript code using the [jest](https://jestjs.io/)
testing framework.

### Run Jest

    ./npx jest [TestPathPattern]

## Deploying

Each time a CL is reviewed and submitted, the code is deployed to App Engine.
See [cmd/golangorg/README.md](cmd/golangorg/README.md#deploying-to-go_dev-and-golang_org) for details.

## Report Issues / Send Patches

This repository uses Gerrit for code changes. To learn how to submit changes to
this repository, see https://go.dev/doc/contribute.

The git repository is https://go.googlesource.com/website.

The main issue tracker for the website repository is located at
https://go.dev/issues. Prefix your issue with "x/website:" in the
subject line, so it is easy to find.

---

## File: CONTRIBUTING.md

# Contributing to Go

Go is an open source project.

It is the work of hundreds of contributors. We appreciate your help!

## Filing issues

When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions:

1.  What version of Go are you using (`go version`)?
2.  What operating system and processor architecture are you using?
3.  What did you do?
4.  What did you expect to see?
5.  What did you see instead?

General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
The gophers there will answer or ask you to file an issue if you've tripped over a bug.

## Contributing code

Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
before sending patches.

Unless otherwise noted, the Go source files are distributed under
the BSD-style license found in the LICENSE file.

---

## File: package.json

{
  "devDependencies": {
    "@types/jest": "27.4.0",
    "@typescript-eslint/eslint-plugin": "5.9.0",
    "@typescript-eslint/parser": "5.9.0",
    "esbuild": "0.14.11",
    "eslint": "8.6.0",
    "eslint-config-google": "0.14.0",
    "eslint-config-prettier": "8.3.0",
    "eslint-plugin-prettier": "4.0.0",
    "jest": "27.4.7",
    "prettier": "2.5.1",
    "stylelint": "14.2.0",
    "stylelint-config-prettier": "9.0.3",
    "stylelint-config-standard": "24.0.0",
    "stylelint-order": "5.0.0",
    "stylelint-prettier": "2.0.0",
    "typescript": "4.5.4"
  },
  "jest": {
    "extensionsToTreatAsEsm": [
      ".ts"
    ],
    "testEnvironment": "jsdom",
    "transform": {
      "\\.ts$": "<rootDir>/jest-transform.cjs"
    }
  }
}

---

## File: tsconfig.json

{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig.json to read more about this file */
    "target": "es2018",
    "module": "es2020",
    "isolatedModules": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "useUnknownInCatchVariables": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "skipLibCheck": true,
  }
}

---

## File: .eslintrc.yaml

root: true
extends: google
parserOptions:
  ecmaVersion: 2018
rules:
  require-jsdoc: 'off'
  indent: 'off'
  arrow-parens: 'off'
  comma-dangle: ['error', {'functions': 'never'}]
overrides:
  - files:
      - '*.ts'
    parser: '@typescript-eslint/parser'
    env:
      browser: true
    plugins:
      - '@typescript-eslint'
    extends:
      - eslint:recommended
      - plugin:@typescript-eslint/recommended
      - plugin:prettier/recommended
    rules:
      valid-jsdoc:
        - error
        - requireParamType: false
          requireReturnType: false
          requireReturn: false

---

## File: .prettierrc.yaml

arrowParens: avoid
singleQuote: true
bracketSpacing: false
quoteProps: consistent

---

## File: .stylelintrc.yaml

extends:
  - stylelint-config-standard
  - stylelint-prettier/recommended
plugins:
  - stylelint-order
rules:
  color-hex-case: lower
  declaration-property-value-allowed-list:
    '/color/':
      - "/^var\\(--/"
      - 'transparent'
  order/properties-alphabetical-order: true
  unit-disallowed-list:
    - 'px'
  selector-class-pattern: '^[a-zA-Z\-]+$'

---

## File: _content/about.md

---
redirect: https://pkg.go.dev/about
---

---

## File: _content/AUTHORS.md

---
title: "Authors of Go"
layout: article
date: 2022-07-25T10:15:00-04:00
---

The Go project formerly maintained AUTHORS and CONTRIBUTORS files
listing the authors of commits in the Go project repositories.
The source control history is now the authoritative source for
this information.

Go's Gerrit instance can search for changes by specific authors.
For example \[[is:merged author:"Russ Cox"](https://go-review.googlesource.com/q/is:merged+author:%2522Russ+Cox%2522)\].

---

## File: _content/brand.md

---
title: "Brand and Trademark Usage Guidelines"
layout: article
---

The Go trademark and the Go Logo () – collectively, the “Go Trademarks” –
are trademarks of Google and are treated separately from the copyright license
grants contained in the BSD-licensed Go repositories,
as described below.

The Go Gopher mascot was created by Renee French and is licensed
under the
[Creative Commons 4.0 Attribution License](https://creativecommons.org/licenses/by/4.0/).

## Trademark Guidelines {#guidelines}

Any use of the Go Trademarks other than those permitted in these guidelines
must be approved in advance.

In general, we want the word mark “Go” and the Go Logo to be used freely to refer to the Go programming language.

We do not want these trademarks to be used:

 - to refer to any other programming language.
 - in a way that is misleading or may imply association of unrelated projects,
   companies, software, documentation, or other resources with
   the Go programming language project.
 - in ways that confuse the community as to whether the Go programming language
   is open source and free to use.

These guidelines exist to ensure that the Go programming language
can continue to share its releases under open source licenses
while making sure that the Go Trademarks are protected as
meaningful source identifiers in a way that’s consistent with trademark law.

## Use of the Go Trademarks {#use}

### No Authorization Needed

#### Nominative Fair Use

In order to accurately identify the Go programming language
or any compatible applications,
it may be necessary to refer to the language by name (“nominative fair use”).
These are the basic rules for nominative fair use of the Go Trademarks:

- Only use the Go trademark in word mark form, i.e., plain text.
  Do not use the Go Logo or Go as a stylized form without permission.
- Only use the Go trademark as much as is necessary.
  Use should be limited to matter-of-fact statements.
- Do not use the Go trademark in any way that suggests or implies
  affiliation with or endorsement from the community or from Google.

Nominative or descriptive uses in fair use may arise in an educational context
or in books or blogs about the Go programming language and any derivative works.

### Authorized Software Uses of the Go Trademarks

#### Unmodified forks

The Go Trademarks can generally be retained in unaltered versions
of the Go open source programming language (that is, an unmodified fork).
This use must follow the
[“Naming Conventions for Authorized Uses”](#naming)
and may not inaccurately suggest affiliation or endorsement
or mislead as to the source.

#### Substantially unmodified distributions

Substantially unmodified distributions may use the Go Trademarks
if the derivative work complies with the terms of the Go programming language’s
open source license and is made in a good faith attempt to replicate the quality
and substance of the original project.

Examples of modifications that would be considered substantially unmodified include
language translation and localization, bug and security patches,
and necessary interoperability/compatibility modifications.

The Go Trademarks may be used in connection with such substantially unmodified
distributions following the
[“Naming Conventions for Authorized Uses”](#naming).

### Software Uses Requiring Review and Approval for Authorization

#### Substantially modified distributions

Substantially modified distributions require review and approval from
_trademark@golang.org_ before the Go Trademarks can be used.

Substantially modified distributions may include explicit changes
to functionality, interfaces, or features.

If the substantially modified distribution is approved,
the Go Trademarks may be used in connection with such
substantially unmodified distributions following the
[“Naming Conventions for Authorized Uses”](#naming).

### Unauthorized Software Uses of the Go Trademarks

#### Disparaging modifications

Modifications that disparage the Go programming language
or its reputation without qualifying as fair use,
such as the introduction of malicious code,
are not compatible with use of the Go Trademarks.

### Authorized Non-software Uses of the Go Trademarks

#### Use for events and community groups

The Go word mark may be used referentially in events, community groups,
or other gatherings related to the programming language,
but it may not be used in a manner that implies official status or endorsement.

The Go Logo may not be used with events, community groups,
or other gatherings related to the programming language without permission.

Events and community groups must follow the
[“Naming Conventions for Authorized Uses”](#naming).

Events and community groups may be subject to the
Go programming language’s Code of Conduct,
and violations of the Code of Conduct may be deemed incompatible
with use of the Go Trademarks.

#### Swag

The Go Trademarks may be used to produce swag
such as t-shirts, pens, stickers, or hats for both
commercial and non-commercial purposes
in accordance with the
[“Naming Conventions for Authorized Uses”](#naming)
and [“Use of the Go Logo”](#logo).

Swag should never be advertised as “official” swag or
swag endorsed for use or purchase by the Go programming language project.

There are no other restrictions on generating revenue through swag
that use the Go Trademarks.
However, we encourage sellers to consider the ethos of the
open source movement in this decision.
Sellers must truthfully advertise to consumers how much of the selling price,
if any, will be donated to open source or community efforts.

### Unauthorized Non-software Uses of the Go Trademarks

#### Use in domain names and social media accounts

The Go Trademarks should not be used, in whole or part,
as or within any domain names and social media account names or handles
in a manner that implies official status or endorsement.

#### Use in a Company Name, Trade Name, Product Name or Feature Name

The Go Trademarks may not be used as or combined with
all or part of a company name, trade name, product name,
or feature name in a manner that implies official status or endorsement.

## Naming Conventions for Authorized Uses {#naming}

Once a particular use falls within an Authorized Use category as outlined in
[“Use of the Go Trademarks”](#use),
the Go Trademarks can be used subject to the following Naming Conventions.
These Naming Conventions seek to avoid implying sponsorship, approval,
or endorsement, which may result in confusion as to the source of the
underlying goods or services.

### Authorized Naming Conventions {#auth}

- [New Name/Company] managed Go
- [New Name], a fork of Go
- [New Name and/or description of interaction] for Go

### Unauthorized Naming Conventions {#unauth}

Naming Conventions that disparage the Go programming language,
if not permitted as fair use, are unauthorized.
For example, the following are unauthorized Naming Conventions:

- Improved Go
- The Better Go
- Any Naming Convention violating the Go programming language’s Code of Conduct,
  such as use of non-inclusive language.
- Any Naming Convention modifying or altering the Go Trademarks
  in a misleading manner.

### Naming Conventions Requiring Review and Approval for Authorization {#approval}

Any Naming Convention not following the
[“Authorized Naming Conventions”](#auth)
or
[“Unauthorized Naming Conventions”](#unauth)
require review for approval from _trademark@golang.org_.

## Use of the Go Logo {#logo}

In addition to the applicable rules outlined above applying to the Go word mark,
the following rules apply to the use of the Go Logo ().

The Go Logo may never be used in a way:
 - to disparage the Go programming language or its reputation; or
 - that violates the Go programming language’s code of conduct.

The Go Logo may not be used in the following manners without review and approval:
 - used as or incorporated in the logo for a commercial product;
 - modified in any form; or
 - used in close proximity to, within, or encompassing another logo,
   badge, or stylized trademark.

Please use the provided brand assets and further guidance for the
Go Logo and the Gopher mascot as outlined in “[Go's New Brand](/blog/go-brand)”.

## Authorization Non-Transferrable {#non}

Authorization to use the Go Trademarks cannot be inherited
through project dependencies; every use of the Go Trademarks
must comply with the applicable guidelines or have explicit prior written permission.

Authorized Users under these Guidelines may not authorize any third-party use
and may not transfer or sublicense any of the user’s authorizations or
permissions to use the Go Trademarks.

## Go Trademarks Enforcement {#enforce}

Authorized users under these Guidelines may not enforce the Go Trademarks
but should notify _trademark@golang.org_ of any suspected, alleged,
or actual misuse, misappropriation, infringement,
or other violation of the Go Trademarks.

## Guideline Version {#version}

These Trademark Guidelines are version 1.0 and may be followed by
subsequent versions.
These Guidelines may be edited for clarity; the major version will be increased
when changes introduce new requirements, define new criteria, or otherwise
present a backwards incompatible change.

## Contact Us {#contact}

Please do not hesitate to contact us at _trademark@golang.org_
if you are unsure whether your intended use of the Go Trademarks
is in compliance with these guidelines,
or to ask for permission to use the Go Trademarks,
clearly describing the intended usage and duration.
Thank you.

---

## File: _content/CONTRIBUTORS.md

---
redirect: /AUTHORS
---

---

## File: _content/copyright.md

---
title: "Copyright"
layout: article
date: 2019-11-05T15:50:08-05:00
---

Except as [noted](https://developers.google.com/terms/site-policies#restrictions), the contents of this site
are licensed under the <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0
License</a>, and code is licensed under a [BSD license](/LICENSE).

---

## File: _content/help.md

---
title: "Help"
template: true
layout: "article"
sidebar: "bug"
---



<section id="help" class="BigCard">
<h2>Get help</h2>
<h3 id="mailinglist">[Go Nuts Mailing List](https://groups.google.com/group/golang-nuts)</h3>

Get help from Go users, and share your work on the official mailing list.


Search the [golang-nuts](https://groups.google.com/group/golang-nuts)
archives and consult the [FAQ](/doc/go_faq.html) and
[wiki](/wiki) before posting.


<h3 id="forum">[Go Forum](https://forum.golangbridge.org/)</h3>

The [Go Forum](https://forum.golangbridge.org/) is a discussion
forum for Go programmers.


<h3 id="discord">[Gophers Discord](https://discord.gg/golang)</h3>

Get live support and talk with other gophers on the Go Discord.


<h3 id="slack">[Gopher Slack](https://blog.gopheracademy.com/gophers-slack-community/)</h3>
Get live support from other users in the Go Slack channel.

<h3 id="irc">[Go IRC Channel](ircs:irc.libera.chat/go-nuts)</h3>
Get live support at `#go-nuts` on `irc.libera.chat`,
the Go IRC channel.

<h3 id="faq">[Frequently Asked Questions (FAQ)](/doc/faq)</h3>
Answers to common questions about Go.
</section>

<section id="inform" class="BigCard">
<h2>Stay informed</h2>

<h3 id="announce">[Go Announcements Mailing List](https://groups.google.com/group/golang-announce)</h3>

Subscribe to
[golang-announce](https://groups.google.com/group/golang-announce)
for important announcements, such as the availability of new Go releases.


<h3 id="blog">[Go Blog](/blog/)</h3>
The Go project's official blog.

<h3 id="bluesky">[@golang.org on Bluesky](https://bsky.app/profile/golang.org)</h3>
The Go project's official Bluesky account.

<h3 id="mastodon">[@golang on Mastodon](https://hachyderm.io/@golang)</h3>
The Go project's official Mastodon account.

<h3 id="twitter">[@golang at Twitter](https://twitter.com/golang)</h3>
The Go project's official Twitter account.

<h3 id="reddit">[golang sub-Reddit](https://reddit.com/r/golang)</h3>

The [golang sub-Reddit](https://reddit.com/r/golang) is a place
for Go news and discussion.


<h3 id="gotime">[Go Time Podcast](https://changelog.com/gotime)</h3>

The [Go Time podcast](https://changelog.com/gotime) is a panel of Go experts and special guests
discussing the Go programming language, the community, and everything in between.

</section>


<section id="community" class="BigCard">
<h2>Community resources</h2>

<h3 id="go_user_groups">[Go User Groups](/wiki/GoUserGroups)</h3>

Each month in places around the world, groups of Go programmers ("gophers")
meet to talk about Go. Find a chapter near you.


<h3 id="playground">[Go Playground](/play)</h3>
A place to write, run, and share Go code.

<h3 id="wiki">[Go Wiki](/wiki)</h3>
A wiki maintained by the Go community.

<h3 id="conduct">[Code of Conduct](/conduct)</h3>

Guidelines for participating in Go community spaces
and a reporting process for handling issues.

</section>


          Opens in new window.

---

## File: _content/index.md

---
title: The Go Programming Language
summary: Go is an open source programming language that makes it simple to build secure, scalable systems.
template: true
---

{{$canShare := not googleCN}}

<section class="Hero bluebg">
  
    
      <h1>Build simple, secure, scalable systems with Go</h1>
      
        <li>
          <svg width="12" height="10" viewBox="0 0 12 10" fill="none" xmlns="http://www.w3.org/2000/svg">
            
          </svg>
          An open-source programming language supported by Google
        </li>
        <li>
          <svg width="12" height="10" viewBox="0 0 12 10" fill="none" xmlns="http://www.w3.org/2000/svg">
            
          </svg>
          Easy to learn and great for teams
        </li>
        <li>
          <svg width="12" height="10" viewBox="0 0 12 10" fill="none" xmlns="http://www.w3.org/2000/svg">
            
          </svg>
          Built-in concurrency and a robust standard library
        </li>
        <li>
          <svg width="12" height="10" viewBox="0 0 12 10" fill="none" xmlns="http://www.w3.org/2000/svg">
            
          </svg>
          Large ecosystem of partners, communities, and tools
        </li>
      
    
    
      
        <a class="Primary" href="/learn/" aria-label="Get Started" aria-describedby="getStarted-description" role="button">Get Started</a>
        <a class="Secondary js-downloadBtn" href="/dl" aria-label="Download" aria-describedby="download-description" role="button">Download</a>
        
          Opens a new window with the Get Started guide.
        
        
          Opens a new window to download Go.
        
      
      
        
          Download packages for
          <a class="js-downloadWin">Windows 64-bit</a>,
          <a class="js-downloadMac">macOS</a>,
          <a class="js-downloadLinux">Linux</a>, and
          [more](/dl/)
        
        
          The `go` command by default downloads and authenticates
          modules using the Go module mirror and Go checksum database run by
          Google. [Learn more.](/dl)
        
      
    
    
          Opens in new window.
    
    
      
    
  
</section>
<section class="WhoUses">
  
    
      <h2 class="WhoUses-headerH2">Companies using Go</h2>
      Organizations in every industry use Go to power their software and services
        <a href="/solutions/" class="WhoUsesCaseStudyList-seeAll" aria-describedby="newwindow-description">
        View all stories
       </a>
     
    
  
    
    {{- range newest (pages "/solutions/*")}}{{if eq .series "Case Studies"}}
      {{- if .link }}
        {{- if .inLandingPageGrid }}
          <li class="WhoUsesCaseStudyList-caseStudy">
            <a href="{{.link}}" aria-label="View CaseStudy of {{.company}}, (opens in new window)" target="_blank" rel="noopener"
              class="WhoUsesCaseStudyList-caseStudyLink">
              
            </a>
          </li>
        {{- end}}
      {{- else}}
        <li class="WhoUsesCaseStudyList-caseStudy">
          <a href="{{.URL}}" aria-label="View CaseStudy of {{.company}}, (opens in new window)" class="WhoUsesCaseStudyList-caseStudyLink">
            
            View case study
          </a>
        </li>
      {{- end}}
    {{- end}}
    {{- end}}
    
  
</section>
<section class="TestimonialsGo">
  
    
      
        
          {{- range $index, $element := data "/testimonials.yaml"}}
            <li class="TestimonialsGo-quoteGroup GoCarousel-slide" id="quote_slide{{$index}}">
              
                
                  {{raw .quote}}
                  — {{.name}},
                    {{.title}}
                     at {{.company}}
                  
                
              
            </li>
          {{- end}}
        
      
    
      navigate_before
    
    
      navigate_next
    
  
  
</section>
<section class="Playground">
  
    
      <h2 class="HomeSection-header">Try Go</h2>
    
    
      
        Press Esc to move out of the editor.
      
      <textarea class="Playground-input js-playgroundCodeEl" spellcheck="false" aria-label="Try Go" aria-describedby="editor-description" id="code">
// You can edit this code!
// Click here and start typing.
package main
import "fmt"
func main() {
  fmt.Println("Hello, 世界")
}</textarea>
    
    
      Press Esc to move out of the editor.
    
    
      <noscript>Hello, 世界</noscript>
    
    
      <select class="Playground-selectExample js-playgroundToysEl" aria-label="Code examples">
      <option value="hello.go">Hello, World!</option>
      <option value="life.go">Conway's Game of Life</option>
      <option value="fib.go">Fibonacci Closure</option>
      <option value="peano.go">Peano Integers</option>
      <option value="pi.go">Concurrent pi</option>
      <option value="sieve.go">Concurrent Prime Sieve</option>
      <option value="solitaire.go">Peg Solitaire Solver</option>
      <option value="tree.go">Tree Comparison</option>
      </select>
      
      Run
      
        {{- if $canShare}}
        Share
        {{- end}}
        <a class="Button tour Playground-button" href="/tour/" title="Tour Go from your browser">Tour</a>
      
      
    
  
</section>
<section class="WhyGo">
  
    
      <h2 class="WhyGo-headerH2">What’s possible with Go</h2>
      
        Use Go for a variety of software development purposes
      
    
    
      {{- range first 4 (data "/resources.yaml")}}
        <li class="WhyGo-reason">
          
            
              
              
            
            
              <h3 class="WhyGo-reasonTitle">{{.title}}</h3>
              
                {{.description}}
              
            
          
          
            
              
                
                Popular Packages:
              
              
                {{- range .packages }}
                  <li class="WhyGo-reasonPackage">
                    <a class="WhyGo-reasonLink" href="{{.url}}" target="_blank" rel="noopener">
                      {{.title}}
                    </a>
                  </li>
                  {{- end}}
              
            
            
              <a href="{{.link}}" aria-describedby="newwindow-description">Learn More 
              arrow_forward</a>
            
          
        </li>
      {{- end}}
      {{- if gt (len (data "resources.yaml")) 3}}
        <li class="WhyGo-reason">
          
            
              
            
            
              <a href="/solutions/use-cases" aria-describedby="newwindow-description">More use cases 
              arrow_forward</a>
            
          
        </li>
      {{- end}}
    
  
</section>
<section class="GettingStartedGo">
  
    
      <h2 class="GettingStartedGo-headerH2">Get started with Go</h2>
      
        Explore a wealth of learning resources, including guided journeys, courses, books, and more.
      
      
        <a class="GettingStartedGo-primaryCta" href="/learn/"aria-describedby="newwindow-description">Get Started</a>
        [Download Go](/doc/install/)
      
    
    
      
        <li class="GettingStartedGo-resourcesHeader">
          Resources to start on your own
        </li>
        <li class="GettingStartedGo-resourceItem">
          <a href="/learn#guided-learning-journeys" class="GettingStartedGo-resourceItemTitle" aria-describedby="newwindow-description">
            Guided learning journeys
          </a>
          
            Step-by-step tutorials to get your feet wet
          
        </li>
        <li class="GettingStartedGo-resourceItem">
          <a href="/learn#online-learning" class="GettingStartedGo-resourceItemTitle" aria-describedby="newwindow-description">
            Online learning
          </a>
          
            Browse resources and learn at your own pace
          
        </li>
        <li class="GettingStartedGo-resourceItem">
          <a href="/learn#featured-books" class="GettingStartedGo-resourceItemTitle" aria-describedby="newwindow-description">
            Featured books
          </a>
          
            Read through structured chapters and theories
          
        </li>
        <li class="GettingStartedGo-resourceItem">
          <a href="/learn#self-paced-labs" class="GettingStartedGo-resourceItemTitle" aria-describedby="newwindow-description">
            Cloud Self-paced labs
          </a>
          
            Jump in to deploying Go apps on GCP
          
        </li>
      
      
        <li class="GettingStartedGo-resourcesHeader">
          In-Person Trainings
        </li>
        {{- range first 4 (data "/learn/training.yaml")}}
          <li class="GettingStartedGo-resourceItem">
            <a href="{{.url}}" class="GettingStartedGo-resourceItemTitle" aria-describedby="newwindow-description">
              {{.title}}
            </a>
            
              {{.blurb}}
            
          </li>
        {{- end}}
      
    
  
</section>
<script src="/js/index.js" defer></script>

---

## File: _content/menus.yaml

main:
  - name: Why Go
    url: /solutions/
    children:
      - name: Case Studies
        explanation: Common problems companies solve with Go
        url: /solutions/case-studies
      - name: Use Cases
        explanation: Stories about how and why companies use Go
        url: /solutions/use-cases
      - name: Security
        explanation: How Go can help keep you secure by default
        url: /security/
  - name: Learn
    url: /learn/
  - name: Docs
    url: /doc/
    children:
      - name: Go Spec
        explanation: The official Go language specification
        url: /ref/spec
      - name: Go User Manual
        explanation: A complete introduction to building software with Go
        url: /doc
      - name: Standard library
        explanation: Reference documentation for Go's standard library
        url: https://pkg.go.dev/std
      - name: Release Notes
        explanation: Learn what's new in each Go release
        url: /doc/devel/release
      - name: Effective Go
        explanation: Tips for writing clear, performant, and idiomatic Go code
        url: /doc/effective_go
  - name: Packages
    url: https://pkg.go.dev
  - name: Community
    url: /example/
    children:
      - name: Recorded Talks
        explanation: Videos from prior events
        url: /talks/
      - name: Meetups
        explanation: Meet other local Go developers
        url: https://www.meetup.com/pro/go
        external: true
      - name: Conferences
        explanation: Learn and network with Go developers from around the world
        url: /wiki/Conferences
        external: true
      - name: Go blog
        explanation: The Go project's official blog.
        url: /blog
      - name: Go project
        explanation: Get help and stay informed from Go
        url: /help
      - name: Get connected
        socialIconsList:
          [
            {
              img: google-groups.svg,
              name: google-groups,
              url: 'https://groups.google.com/g/golang-nuts',
            },
            {img: github.svg, darkImg: github-light.svg, name: github, url: 'https://github.com/golang'},
            {img: bluesky.svg, name: bluesky, url: 'https://bsky.app/profile/golang.org'},
            {img: mastodon.svg, name: mastodon, url: 'https://hachyderm.io/@golang'},
            {img: twitter.svg, name: twitter, url: 'https://twitter.com/golang'},
            {img: reddit.svg, name: reddit ,url: 'https://www.reddit.com/r/golang/'},
            {img: slack.svg, name: slack, url: 'https://invite.slack.golangbridge.org/'},
            {
              img: stack-overflow.svg,
              name: stack-overflow,
              url: 'https://stackoverflow.com/tags/go',
            },
          ]

footer:
  - name: Why Go
    url: /solutions/
    children:
      - name: Use Cases
        url: /solutions/use-cases
      - name: Case Studies
        url: /solutions/case-studies

  - name: Get Started
    url: /learn/
    children:
      - name: Playground
        url: /play
      - name: Tour
        url: /tour/
      - name: Stack Overflow
        url: https://stackoverflow.com/questions/tagged/go?tab=Newest
      - name: Help
        url: /help/

  - name: Packages
    url: https://pkg.go.dev
    children:
      - name: Standard Library
        url: /pkg/
      - name: About Go Packages
        url: https://pkg.go.dev/about
      - name: pkg.go.dev API
        url: https://pkg.go.dev/api

  - name: About
    url: /project
    children:
      - name: Download
        url: /dl/
      - name: Blog
        url: /blog/
      - name: Issue Tracker
        url: https://github.com/golang/go/issues
      - name: Release Notes
        url: /doc/devel/release
      - name: Brand Guidelines
        url: /brand
      - name: Code of Conduct
        url: /conduct

  - name: Connect
    url: /wiki/#the-go-community
    children:
      - name: Bluesky
        url: https://bsky.app/profile/golang.org
      - name: Mastodon
        url: https://hachyderm.io/@golang
      - name: Twitter
        url: https://www.twitter.com/golang
      - name: GitHub
        url: https://github.com/golang
      - name: Slack
        url: https://invite.slack.golangbridge.org/
      - name: r/golang
        url: https://reddit.com/r/golang
      - name: Meetup
        url: https://www.meetup.com/pro/go
      - name: Golang Weekly
        url: https://golangweekly.com/

---

## File: _content/resources.yaml

- title: Cloud & Network Services
    link: /solutions/cloud/
    icon: /images/icons/sphere.svg
    iconDark: /images/icons/sphere-dark.svg
    iconName: Sphere
    packages:
    - title: cloud.google.com/go
      url: https://cloud.google.com/go/home
    - title: aws/client
      url: https://aws.amazon.com/sdk-for-go/
    - title: Azure/azure-sdk-for-go
      url: https://github.com/Azure/azure-sdk-for-go
  - title: Command-line Interfaces
    link: /solutions/clis/
    icon: /images/icons/command-folder.svg
    iconDark: /images/icons/command-folder-dark.svg
    iconName: Command Line
    packages:
    - title: spf13/cobra
      url: https://github.com/spf13/cobra
    - title: spf13/viper
      url: https://github.com/spf13/viper
    - title: urfave/cli
      url: https://github.com/urfave/cli
    - title: delve
      url: https://github.com/go-delve/delve
    - title: chzyer/readline
      url: https://github.com/chzyer/readline
  - title: Web Development
    link: /solutions/webdev/
    icon: /images/icons/code.svg
    iconDark: /images/icons/code-dark.svg
    iconName: Code
    packages:
    - title: net/http
      url: /pkg/net/http/
    - title: html/template
      url: /pkg/html/template/
    - title: flosch/pongo2
      url: https://github.com/flosch/pongo2
    - title: database/sql
      url: /pkg/database/sql/
    - title: elastic/go-elasticsearch
      url: https://github.com/elastic/go-elasticsearch
  - title: DevOps & Site Reliability
    link: /solutions/devops/
    icon: /images/icons/gear.svg
    iconDark: /images/icons/gear-dark.svg
    iconName: Sphere
    packages:
    - title: open-telemetry/opentelemetry-go
      url: https://github.com/open-telemetry/opentelemetry-go
    - title: istio/istio
      url: https://github.com/istio/istio
    - title: urfave/cli
      url: https://github.com/urfave/cli

---

## File: _content/robots.txt

User-agent: *
Allow: /

---

## File: _content/testimonials.yaml

- name: Jaime Enrique Garcia Lopez
  title: Senior Software Development Manager
  company: Capital One
  quote: |-
    “At the time, no single team member knew Go, but
    **within a month, everyone was writing in Go** and we were
    building out the endpoints. It was the flexibility, how easy it was to use,
    and the really cool concept behind Go (how Go handles native concurrency,
    garbage collection, and of course safety+speed.) that helped engage us
    during the build. Also, who can beat that cute mascot!”
- name: Clayton Coleman
  title: Lead Engineer, Open Shift
  company: RedHat
  quote: |-
    "**A small language that compiles fast makes for a happy developer.**
    The Go language is small, compiles really fast, and as a result it lets your
    mind focus on the actual problem and less on the tool you are using to solve
    it. Code, test, debug cycles are so quick that you forget you are not
    working with an interpreted language. Looking at our code, you see
    **less boilerplate and more business logic.**"
- name: Matt Boyle
  title: Lead Software Engineer
  company: Curve
  quote: |-
    “Go has excellent characteristics for scalability and services
    written using it typically have very small memory footprints.
    Because code is compiled into a single static binary, services can also be
    containerised with ease, making it much simpler to build and deploy. These
    attributes make Go an ideal choice for companies building
    microservices, as you can easily deploy into a highly available and
    scalable environment such as Kubernetes.”
- name: Bala Natarajan
  title: Sr. Director of Engineering, Developer Experience
  company: PayPal
  quote: |-
    "In our tightly managed environments where we run Go code,
    **we have seen a CPU reduction of approximately 10%**
    with cleaner and maintainable code."
- name: Benjamin Cane
  title: Vice President and Principal Engineer
  company: American Express
  quote: |-
    "Tooling has always been a problem with our legacy code base... but we have
     found that Go has excellent tooling, plus built-in testing, benchmarking,
     and profiling frameworks. It is easy to write efficient and resilient
     applications. After working on Go, most of our developers don't want
     to go back to other languages."
- name: John Biggs and Ben Popper
  title:
  company: Stack Overflow
  quote: |-
    "...when a programming language is designed for exactly the environment most
     of us use right now—scalable, cloud-based servers that are optimized for
      performance—a lot can go right."

---

## File: _content/tos.md

---
title: "Terms of Service"
layout: article
date: 2019-11-05T15:47:16-05:00
---

The Go website (the "Website") is hosted by Google. By using and/or visiting the Website, you consent to be bound by
Google's general [Terms of Service](https://www.google.com/intl/en/policies/terms/) and Google's general
[Privacy Policy](https://www.google.com/intl/en/privacy/privacy-policy.html).

---

## File: _content/blog/README.md

This directory holds Go blog articles, in *.article.
See https://pkg.go.dev/golang.org/x/tools/present?tab=doc
for documentation of the file format or look at any of the
articles for examples.

Article file names should be short, amenable to being typed by hand in URLs.
Typically article file names are up to three words, separated by dashes.
A trailing year in the name typically does not have a dash before it.

All supporting files for an article, even if there's only one, should be
placed in a directory named for the article (minus the .article suffix).

If your article has code that is meant to be a working program, please use
.code, or ideally .play, to load the lines from a supporting .go file.
That way you can easily check that the .go file, and therefore the code
in your article, still works.

Please use .image and .video to embed images and videos,
instead of using raw HTML tags. The .image and .video commands
provide a way to adjust the implementation of those embeddings
all in one place.

Please use .html when it is necessary to add large blocks of HTML,
keeping article text in the main .article file. Another important use of
.html is to factor out an HTML snippet that appears multiple times.
Short HTML sequences, like  or ,
are fine to put directly in the article files.

---

## File: _content/blog/10years.md

---
title: Go Turns 10
date: 2019-11-08
by:
- Russ Cox, for the Go team
summary: Happy 10th birthday, Go!
template: true
---


Happy birthday, Go!

This weekend we celebrate the 10th anniversary of
[the Go release](https://opensource.googleblog.com/2009/11/hey-ho-lets-go.html),
marking the 10th birthday of Go as an open-source programming language
and ecosystem for building modern networked software.

To mark the occasion,
[Renee French](https://twitter.com/reneefrench),
the creator of the
[Go gopher](/blog/gopher),
painted this delightful scene:

<a href="10years/gopher10th-large.jpg">
{{image "10years/gopher10th-small.jpg" 850}}
</a>

Celebrating 10 years of Go makes me think back to early November 2009,
when we were getting ready to share Go with the world.
We didn’t know what kind of reaction to expect,
whether anyone would care about this little language.
I hoped that even if no one ended up using Go,
we would at least have drawn attention to some good ideas,
especially Go’s approach to concurrency and interfaces,
that could influence follow-on languages.

Once it became clear that people were excited about Go,
I looked at the history of popular languages
like C, C++, Perl, Python, and Ruby,
examining how long each took to gain widespread adoption.
For example, Perl seemed to me to have appeared fully-formed
in the mid-to-late 1990s, with CGI scripts and the web,
but it was first released in 1987.
This pattern repeated for almost every language I looked at:
it seems to take roughly a decade of quiet, steady improvement
and dissemination before a new language really takes off.

I wondered: where would Go be after a decade?

Today, we can answer that question:
Go is everywhere, used by at least [a million developers worldwide](https://research.swtch.com/gophercount).

Go’s original target was networked system infrastructure,
what we now call cloud software.
Every major cloud provider today uses core cloud infrastructure written in Go,
such as Docker, Etcd, Istio, Kubernetes, Prometheus, and Terraform;
the majority of the
[Cloud Native Computing Foundation’s projects](https://www.cncf.io/projects/)
are written in Go.
Countless companies are using Go to move their own work to the cloud as well,
from startups building from scratch
to enterprises modernizing their software stack.
Go has also found adoption well beyond its original cloud target,
with uses ranging
from
controlling tiny embedded systems with
[GoBot](https://gobot.io) and [TinyGo](https://tinygo.org/)
to detecting cancer with
[massive big data analysis and machine learning at GRAIL](https://medium.com/grail-eng/bigslice-a-cluster-computing-system-for-go-7e03acd2419b),
and everything in between.

All this is to say that Go has succeeded beyond our wildest dreams.
And Go’s success isn’t just about the language.
It’s about the language, the ecosystem, and especially the community working together.

In 2009, the language was a good idea with a working sketch of an implementation.
The `go` command did not exist:
we ran commands like `6g` to compile and `6l` to link binaries,
automated with makefiles.
We typed semicolons at the ends of statements.
The entire program stopped during garbage collection,
which then struggled to make good use of two cores.
Go ran only on Linux and Mac, on 32- and 64-bit x86 and 32-bit ARM.

Over the last decade, with the help of Go developers all over the world,
we have evolved this idea and sketch into a productive language
with fantastic tooling,
a production-quality implementation,
a
[state-of-the-art garbage collector](/blog/ismmkeynote),
and [ports to 12 operating systems and 10 architectures](/doc/install/source#introduction).

Any programming language needs the support of a thriving ecosystem.
The open source release was the seed for that ecosystem,
but since then, many people have contributed their time and talent
to fill the Go ecosystem with great tutorials, books, courses, blog posts,
podcasts, tools, integrations, and of course reusable Go packages importable with `go` `get`.
Go could never have succeeded without the support of this ecosystem.

Of course, the ecosystem needs the support of a thriving community.
In 2019 there are dozens of Go conferences all over the world,
along with
[over 150 Go meetup groups with over 90,000 members](https://www.meetup.com/pro/go).
[GoBridge](https://golangbridge.org)
and
[Women Who Go](https://medium.com/@carolynvs/www-loves-gobridge-ccb26309f667)
help bring new voices into the Go community,
through mentoring, training, and conference scholarships.
This year alone, they have taught
hundreds of people from traditionally underrepresented groups
at workshops where community members teach and mentor those new to Go.

There are
[over a million Go developers](https://research.swtch.com/gophercount)
worldwide,
and companies all over the globe are looking to hire more.
In fact, people often tell us that learning Go
helped them get their first jobs in the tech industry.
In the end, what we’re most proud of about Go
is not a well-designed feature or a clever bit of code
but the positive impact Go has had in so many people’s lives.
We aimed to create a language that would help us be better developers,
and we are thrilled that Go has helped so many others.

As
[\#GoTurns10](https://twitter.com/search?q=%23GoTurns10),
I hope everyone will take a moment to celebrate
the Go community and all we have achieved.
On behalf of the entire Go team at Google,
thank you to everyone who has joined us over the past decade.
Let’s make the next one even more incredible!



<a href="10years/gopher10th-pin-large.jpg">
{{image "10years/gopher10th-pin-small.jpg" 150}}

---

## File: _content/blog/11years.md

---
title: Eleven Years of Go
date: 2020-11-10T12:01:00Z
by:
- Russ Cox, for the Go team
summary: Happy Birthday, Go!
---


Today we celebrate the eleventh birthday of the Go open source release.
The parties we had for
[Go turning 10](/blog/10years)
seem like a distant memory.
It’s been a tough year, but
we’ve kept Go development moving forward
and accumulated quite a few highlights.

In November, we launched [go.dev and pkg.go.dev](/blog/go.dev)
shortly after Go’s 10th birthday.

In February, the [Go 1.14 release](/blog/go1.14)
delivered the first officially “production-ready” implementation of Go modules,
along with many performance improvements,
including
[faster defers](/design/34481-opencoded-defers)
and
[non-cooperative goroutine preemption](/design/24543/conservative-inner-frame)
to reduce scheduling
and garbage collection latency.

In early March, we launched a
[new API for protocol buffers](/blog/protobuf-apiv2),
[google.golang.org/protobuf](https://pkg.go.dev/google.golang.org/protobuf),
with much-improved support for protocol buffer reflection and custom messages.



When the pandemic hit, we decided to pause any public announcements
or launches in the spring,
recognizing that everyone’s attention rightly belonged elsewhere.
But we kept working, and one of our team members joined the
Apple/Google collaboration on
[privacy-preserving exposure notifications](https://www.google.com/covid19/exposurenotifications/)
to support contact tracing efforts all over the world.
In May, that group launched the
[reference backend server](https://github.com/google/exposure-notifications-server),
written in Go.

We continued to improve [gopls](https://www.youtube.com/watch?v=EFJfdWzBHwE),
which enables advanced
[Go-aware support](https://github.com/golang/tools/blob/master/gopls/doc/user.md)
in many editors.
In June, the
[VSCode Go extension officially joined the Go project](/blog/vscode-go)
and is now maintained by the same developers who work on gopls.

Also in June, thanks to your feedback, we open-sourced
[the code behind pkg.go.dev](/blog/pkgsite)
as part of the Go project as well.

Later in June, we
[released the latest design draft for generics](/blog/generics-next-step),
along with a prototype tool and [generics playground](https://go2goplay.golang.org/).

In July, we published and discussed three new design drafts for future changes:
[new `//go:build` lines for file selection](/design/draft-gobuild),
[file system interfaces](/design/draft-iofs),
and
[build-time file embedding](/design/draft-embed).
(We’ll see all of those in 2021, as noted below.)

In August, the [Go 1.15 release](/blog/go1.15)
delivered mainly optimizations and bug fixes rather than new features.
The most significant was the start of a rewrite of the linker,
making it run 20% faster and use 30% less memory
on average for large builds.

Last month, we ran our [annual Go user survey](/blog/survey2020).
We will post results on the blog once we’ve analyzed them.

The Go community has adapted to “virtual-first” along with everyone else,
and we saw many virtual meetups and over a dozen virtual Go conferences this year.
Last week, the Go team hosted
[Go day at Google Open Source Live](https://opensourcelive.withgoogle.com/events/go)
(videos at the link).

## Going Forward

We’re also incredibly excited about what’s in store for Go’s 12th year.
Most immediately, this week Go team members will
be presenting eight events at
[GopherCon 2020](https://www.gophercon.com/).
Mark your calendars!

- “Typing [Generic] Go”,
  a talk by Robert Griesemer,\
  [Nov 11, 10:00 AM (US Eastern)](https://www.gophercon.com/agenda/session/233094);
  [Q&A at 10:30 AM](https://www.gophercon.com/agenda/session/417935).
- “What to Expect When You’re NOT Expecting”,
  a live taping of the Go time podcast with a panel of expert debuggers,
  including Hana Kim,\
  [Nov 11 12:00 PM](https://www.gophercon.com/agenda/session/2334490).
- “Evolving the Go Memory Manager's RAM and CPU Efficiency”,
  a talk by Michael Knyszek,\
  [Nov 11 1:00 PM](https://www.gophercon.com/agenda/session/233086);
  [Q&A at 1:50 PM](https://www.gophercon.com/agenda/session/417940).
- “Implementing Faster Defers”,
  a talk by Dan Scales,\
  [Nov 11 5:10 PM](https://www.gophercon.com/agenda/session/233397);
  [Q&A at 5:40 PM](https://www.gophercon.com/agenda/session/417941).
 - “Go Team - Ask Me Anything”,
  a live Q&A with Julie Qiu, Rebecca Stambler, Russ Cox, Sameer Ajmani, and Van Riper,\
  [Nov 12 3:00 PM](https://www.gophercon.com/agenda/session/420539).
- “Pardon the Interruption: Loop Preemption in Go 1.14”,
  a talk by Austin Clements,\
  [Nov 12 4:45 PM](https://www.gophercon.com/agenda/session/233441);
  [Q&A at 5:15 PM](https://www.gophercon.com/agenda/session/417943).
- “Working with Errors”,
  a talk by Jonathan Amsterdam,\
  [Nov 13 1:00 PM](https://www.gophercon.com/agenda/session/233432);
  [Q&A at 1:50 PM](https://www.gophercon.com/agenda/session/417945).
- “Crossing the Chasm for Go: Two Million Users and Growing”,
  a talk by Carmen Andoh,\
  [Nov 13 5:55 PM](https://www.gophercon.com/agenda/session/233426).

## Go Releases

In February, the Go 1.16 release will include the new
[file system interfaces](https://tip.golang.org/pkg/io/fs/)
and
[build-time file embedding](https://tip.golang.org/pkg/embed/).
It will complete the linker rewrite, bringing additional performance improvements.
And it will include support for the new Apple Silicon (`GOARCH=arm64`) Macs.

In August, the Go 1.17 release will no doubt bring more features and improvements,
although it’s far enough out that the exact details remain up in the air.
It will include a new register-based calling convention for x86-64
(without breaking existing assembly!),
which will make programs faster across the board.
(Other architectures will follow in later releases.)
One nice feature that will definitely be included is the
[new `//go:build` lines](/design/draft-gobuild),
which are far less error-prone than the
[current `//` `+build` lines](/cmd/go/#hdr-Build_constraints).
Another highly anticipated feature we hope will be ready for beta testing next year
is
[support for fuzzing in the `go test` command](/design/draft-fuzzing).

## Go Modules

Over the next year, we will continue to work on developing support for Go modules
and integrating them well into the entire Go ecosystem.
Go 1.16 will include our smoothest Go modules experience yet.
One preliminary result from our recent survey is that 96% of users
have now adopted Go modules (up from 90% a year ago).

We will also finally wind down support for GOPATH-based development:
any programs using dependencies other than the standard library will need a `go.mod`.
(If you haven’t switched to modules yet, see the
[GOPATH wiki page](/wiki/GOPATH)
for details about this final step in the journey from GOPATH to modules.)

From the start, the [goal for Go modules](https://research.swtch.com/vgo-intro)
has been “to add the concept of package versions to the working vocabulary
of both Go developers and our tools,”
to enable deep support for modules and versions throughout the Go ecosystem.
The [Go module mirror, checksum database, and index](/blog/modules2019)
were made possible by this ecosystem-wide understanding of what a package version is.
Over the next year, we will see rich module support added to more tools and systems.
For example, we plan to investigate new tooling to help module authors publish new versions
(`go release`)
as well as to help module consumers update their code to migrate away from
deprecated APIs (a new `go fix`).

As a larger example,
[we created gopls](https://github.com/golang/tools/blob/master/gopls/README.md)
to reduce many tools used by editors for Go support,
none of which supported modules, down to a single one that did.
Over the next year,
we’ll be ready to make the VSCode Go extension use `gopls` by default,
for an excellent module experience out of the box,
and we’ll release gopls 1.0.
Of course, one of the best things about gopls is that it is editor-neutral:
any editor that understands the
[language server protocol](https://langserver.org/)
can use it.

Another important use of version information is tracking whether
any package in a build has a known vulnerability.
Over the next year, we plan to develop a database of known vulnerabilities
as well as tools to check your programs against that database.

The Go package discovery site
[pkg.go.dev](https://pkg.go.dev/)
is another example of a version-aware system enabled by Go modules.
We’ve been focused on getting the core functionality and user experience right,
including a
[redesign launching today](/blog/pkgsite-redesign).
Over the next year,
we will be unifying godoc.org into pkg.go.dev.
We will also be expanding the version timeline for each package,
showing important changes in each version,
known vulnerabilities, and more,
following the overall goal of surfacing what you need to make
[informed decisions about adding dependencies](https://research.swtch.com/deps).

We’re excited to see this journey from GOPATH to Go modules
nearing completion and all the excellent dependency-aware tools
that Go modules are enabling.

## Generics

The next feature on everyone’s minds is of course generics.
As we mentioned above, we published the
[latest design draft for generics](/blog/generics-next-step)
back in June.
Since then, we’ve continued to refine rough edges and have turned our
attention to the details of implementing a production-ready version.
We will be working on that throughout 2021, with a goal of having
something for people to try out by the end of the year,
perhaps a part of the Go 1.18 betas.

## Thank You!

Go is far more than just us on the Go team at Google.
We are indebted to the contributors who work with us with the Go releases and tools.
Beyond that, Go only succeeds because of all of you who work in
and contribute to Go’s thriving ecosystem.
It has been a difficult year in the world outside Go.
More than ever, we appreciate you taking the time
to join us and help make Go such a success.
Thank you.
We hope you are all staying safe and wish you all the best.

---

## File: _content/blog/12years.md

---
title: Twelve Years of Go
date: 2021-11-10
by:
- Russ Cox, for the Go team
summary: Happy Birthday, Go!
---


Today we celebrate the twelfth birthday of the Go open source release.
We have had an eventful year and have a lot to look forward to next year.

The most visible change here on the blog is our
[new home on go.dev](/blog/tidy-web),
part of consolidating all our Go web sites into a single, coherent site.
Another part of that consolidation was
[replacing godoc.org with pkg.go.dev](/blog/godoc.org-redirect).

In February, the [Go 1.16 release](/blog/go1.16)
added [macOS ARM64 support](/blog/ports),
added [a file system interface](/pkg/io/fs) and [embedded files](/pkg/embed),
and [enabled modules by default](/blog/go116-module-changes),
along with the usual assortment of improvements and optimizations.

In August, the [Go 1.17 release](/blog/go1.17)
added Windows ARM64 support,
made [TLS cipher suite decisions easier and more secure](/blog/tls-cipher-suites),
introduced [pruned module graphs](/doc/go1.17#go-command)
to make modules even more efficient in large projects,
and added
[new, more readable build constraint syntax](https://pkg.go.dev/cmd/go#hdr-Build_constraints).
Under the hood, Go 1.17 also switched to a register-based calling convention for Go functions
on x86-64, improving performance in CPU-bound applications by 5–15%.

Over the course of the year, we
published [many new tutorials](/doc/tutorial/),
a [guide to databases in Go](/doc/database/),
a [guide to developing modules](/doc/#developing-modules),
and a [Go modules reference](/ref/mod).
One highlight is the new tutorial
“[Developing a RESTful API with Go and Gin](/doc/tutorial/web-service-gin)”,
which is also available in
[interactive form using Google Cloud Shell](/s/cloud-shell-web-tutorial).

We've been busy on the IDE side,
[enabling gopls by default in VS Code Go](/blog/gopls-vscode-go)
and delivering countless improvements to both `gopls` and VS Code Go,
including a [powerful debugging experience](https://github.com/golang/vscode-go/blob/master/docs/debugging.md)
powered by Delve.

We also launched the [Go fuzzing beta](/blog/fuzz-beta)
and [officially proposed adding generics to Go](/blog/generics-proposal),
both of which are now expected in Go 1.18.

Continuing to adapt to “virtual-first”, the Go team hosted our second annual
[Go day at Google Open Source Live](https://opensourcelive.withgoogle.com/events/go-day-2021).
You can watch the talks on YouTube:

- “[Using Generics in Go](https://www.youtube.com/watch?v=nr8EpUO9jhw)”,
  by Ian Lance Taylor, introduces generics and how to use them effectively.

- “[Modern Enterprise Applications](https://www.youtube.com/watch?v=5fgG1qZaV4w)”,
  by Steve Francia, shows how Go plays a role in enterprise modernization.

- “[Building Better Projects with the Go Editor](https://www.youtube.com/watch?v=jMyzsp2E_0U)”,
  by Suzy Mueller, demonstrates how VS Code Go's integrated tooling
  helps you navigate code, debug tests, and more.

- “[From Proof of Concept to Production](https://www.youtube.com/watch?v=e7PtBOsTpXE)”,
  by Benjamin Cane, a Distinguished Engineer at American Express,
  explains how American Express came to use Go for its payments and rewards platforms.

## Going Forward

We’re incredibly excited about what’s in store for Go’s 13th year.
Next month, we will have two talks at [GopherCon 2021](https://www.gophercon.com/),
along with [many talented speakers from across the Go community](https://www.gophercon.com/agenda).
Register for free and mark your calendars!

- “Why and How to Use Go Generics”,
  by Robert Griesemer and Ian Lance Taylor,
  who led the design and implementation of this new feature. \
  [Dec 8, 11:00 AM (US Eastern)](https://www.gophercon.com/agenda/session/593015).

- “Debugging Go Code Using the Debug Adapter Protocol (DAP)”,
  by Suzy Mueller,
  show how to use VS Code Go's advanced debugging features with Delve. \
  [Dec 9, 3:20 PM (US Eastern)](https://www.gophercon.com/agenda/session/593029).

In February, the Go 1.18 release will expand the new
register-based calling convention to non-x86 architectures,
bringing dramatic performance improvements with it.
It will include the new Go fuzzing support.
And it will be the first release to include support for generics.

Generics will be one of our focuses for 2022.
The initial release in Go 1.18 is only the beginning.
We need to spend time using generics and learning what works
and what doesn't, so that we can write best practices
and decide what should be added to the standard library
and other libraries.
We expect that Go 1.19 (expected in August 2022)
and later releases will further refine the design and implementation
of generics as well as integrating them further into the overall Go experience.

Another focus for 2022 is supply chain security.
We have been talking for years about the
[problems of dependencies](https://research.swtch.com/deps).
The design of Go modules provides
[reproducible, verifiable, verified builds](https://research.swtch.com/vgo-repro),
but there is still more work to be done.
Starting in Go 1.18, the `go` command will embed more information in binaries
about their build configurations, both to make reproducibility easier
and to help projects that need to
[generate an SBOM](https://en.wikipedia.org/wiki/Software_bill_of_materials) for Go binaries.
We have also started work on a
[Go vulnerability database](https://pkg.go.dev/golang.org/x/vuln)
and an associated tool to report vulnerabilities in a program's dependencies.
One of our goals in this work is to significantly improve the signal-to-noise ratio
of this kind of tool:
if a program doesn't use the vulnerable function, we don't want to report that.
Over the course of 2022 we plan to make this available as a standalone tool
but also to add it to existing tooling, including `gopls` and VS Code Go, and to [pkg.go.dev](https://pkg.go.dev).
There is also more to do to improve other aspects of Go's supply chain security posture.
Stay tuned for details.

Overall, we expect 2022 to be an eventful year for Go,
and we will continue to deliver the timely releases and improvements
you've come to expect.

## Thank You!

Go is far more than just us on the Go team at Google.
Thank you for your help making Go a success
and joining us on this adventure.
We hope you are all staying safe and wish you all the best.

---

## File: _content/blog/13years.md

---
title: Thirteen Years of Go
date: 2022-11-10
by:
- Russ Cox, for the Go team
summary: Happy Birthday, Go!
---



Today we celebrate the thirteenth birthday of the Go open source release.
[The Gopher](/doc/gopher) is a teenager!

It's been an eventful year for Go.
The most significant event was the release of
[Go 1.18 in March](/blog/go1.18),
which brought many improvements but most notably
Go workspaces, fuzzing, and generics.

Workspaces make it easy to work on multiple modules simultaneously,
which is most helpful when you are maintaining a set of related modules with
module dependencies between them.
To learn about workspaces, see Beth Brown's blog post
“[Get familiar with workspaces](/blog/get-familiar-with-workspaces)”
and the [workspace reference](/ref/mod#workspaces).

Fuzzing is a new feature of `go` `test` that
helps you find inputs that your code doesn't handle properly:
you define a fuzz test that should pass for any input at all,
and then fuzzing tries different random inputs, guided by code coverage,
to try to make the fuzz test fail.
Fuzzing is particularly useful when developing code that must be
robust against arbitrary (even attacker-controlled) inputs.
To learn more about fuzzing, see the tutorial
“[Getting started with fuzzing](/doc/tutorial/fuzz)”
and the [fuzzing reference](/security/fuzz/),
and keep an eye out for Katie Hockman's GopherCon 2022 talk
“Fuzz Testing Made Easy”,
which should be online soon.

Generics, quite possibly Go's most requested feature,
adds parametric polymorphism to Go, to allow writing
code that works with a variety of different types but is still
statically checked at compile time.
To learn more about generics, see the tutorial
“[Getting started with generics](/doc/tutorial/generics)”.
For more detail see
the blog posts
“[An Introduction to Generics](/blog/intro-generics)”
and
“[When to Use Generics](/blog/when-generics)”,
or the talks
“[Using Generics in Go](https://www.youtube.com/watch?v=nr8EpUO9jhw)”
from Go Day on Google Open Source Live 2021,
and
“[Generics!](https://www.youtube.com/watch?v=Pa_e9EeCdy8)” from GopherCon 2021,
by Robert Griesemer and Ian Lance Taylor.

Compared to Go 1.18, the [Go 1.19 release in August](/blog/go1.19) was a relatively quiet one:
it focused on refining and improving the features that Go 1.18 introduced
as well as internal stability improvements and optimizations.
One visible change in Go 1.19 was the addition of
support for [links, lists, and headings in Go doc comments](/doc/comment).
Another was the addition of a [soft memory limit](/doc/go1.19#runtime)
for the garbage collector, which is particularly useful in container workloads.
For more about recent garbage collector improvements,
see Michael Knyszek's blog post “[Go runtime: 4 years later](/blog/go119runtime)”,
his talk “[Respecting Memory Limits in Go](https://www.youtube.com/watch?v=07wduWyWx8M&list=PLtoVuM73AmsJjj5tnZ7BodjN_zIvpULSx)”,
and the new “[Guide to the Go Garbage Collector](/doc/gc-guide)”.

We've continued to work on making Go development scale gracefully to ever larger code bases,
especially in our work on VS Code Go and the Gopls language server.
This year, Gopls releases focused on improving stability and performance,
while delivering support for generics as well as new analyses and code lenses.
If you aren't using VS Code Go or Gopls yet, give them a try.
See Suzy Mueller's talk
“[Building Better Projects with the Go Editor](https://www.youtube.com/watch?v=jMyzsp2E_0U)”
for an overview.
And as a bonus,
[Debugging Go in VS Code](/s/vscode-go-debug)
got more reliable and powerful with Delve's native
[Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/) support.
Try Suzy's “[Debugging Treasure Hunt](https://www.youtube.com/watch?v=ZPIPPRjwg7Q)”!

Another part of development scale is the number of dependencies in a project.
A month or so after Go's 12th birthday,
the [Log4shell vulnerability](https://en.wikipedia.org/wiki/Log4Shell) served
as a wake-up call for the industry
about the importance of supply chain security.
Go's module system was designed specifically for this purpose,
to help you understand and track your dependencies,
identify which specific ones you are using,
and determine whether any of them have known vulnerabilities.
Filippo Valsorda's blog post
“[How Go Mitigates Supply Chain Attacks](/blog/supply-chain)”
gives an overview of our approach.
In September, we previewed
Go's approach to vulnerability management
in Julie Qiu's blog post “[Vulnerability Management for Go](/blog/vuln)”.
The core of that work is a new, curated vulnerability database
and a new [govulncheck command](https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck),
which uses advanced static analysis to eliminate most of the false positives
that would result from using module requirements alone.

Part of our effort to understand Go users is our annual end-of-year Go survey.
This year, our user experience researchers added a lightweight mid-year Go survey as well.
We aim to gather enough responses to be statistically significant
without being a burden on the Go community as a whole.
For the results, see Alice Merrick's blog post
“[Go Developer Survey 2021 Results](/blog/survey2021-results)”
and Todd Kulesza's post
“[Go Developer Survey 2022 Q2 Results](/blog/survey2022-q2-results)”.

As the world starts traveling more,
we've also been happy to meet many of you in person at Go conferences in 2022,
particularly at GopherCon Europe in Berlin in July and at GopherCon in Chicago in October.
Last week we held our annual virtual event,
[Go Day on Google Open Source Live](https://opensourcelive.withgoogle.com/events/go-day-2022).
Here are some of the talks we've given at those events:

 - “[How Go Became its Best Self](https://www.youtube.com/watch?v=vQm_whJZelc)”,
   by Cameron Balahan, at GopherCon Europe.
 - “[Go team Q&A](https://www.youtube.com/watch?v=KbOTTU9yEpI)”,
   with Cameron Balahan, Michael Knyszek, and Than McIntosh, at GopherCon Europe.
 - “[Compatibility: How Go Programs Keep Working](https://www.youtube.com/watch?v=v24wrd3RwGo)”,
   by Russ Cox at GopherCon.
 - “[A Holistic Go Experience](https://www.gophercon.com/agenda/session/998660)”,
   by Cameron Balahan at GopherCon (video not yet posted)
 - “[Structured Logging for Go](https://opensourcelive.withgoogle.com/events/go-day-2022/watch?talk=talk2)”,
   by Jonathan Amsterdam at Go Day on Google Open Source Live
 - “[Writing your Applications Faster and More Securely with Go](https://opensourcelive.withgoogle.com/events/go-day-2022/watch?talk=talk3)”,
   by Cody Oss at Go Day on Google Open Source Live
 - “[Respecting Memory Limits in Go](https://opensourcelive.withgoogle.com/events/go-day-2022/watch?talk=talk4),
   by Michael Knyszek at Go Day on Google Open Source Live

One other milestone for this year was the publication of
“[The Go Programming Language and Environment](https://cacm.acm.org/magazines/2022/5/260357-the-go-programming-language-and-environment/fulltext)”,
by Russ Cox, Robert Griesemer, Rob Pike, Ian Lance Taylor, and Ken Thompson,
in _Communications of the ACM_.
The article, by the original designers and implementers of Go,
explains what we believe makes Go so popular and productive.
In short, it is that Go effort focuses on delivering a full development environment
targeting the entire software development process,
with a focus on scaling both to large software engineering efforts
and large deployments.

In Go's 14th year, we'll keep working to make Go the best environment
for software engineering at scale.
We plan to focus particularly on supply chain security, improved compatibility,
and structured logging, all of which have been linked already in this post.
And there will be plenty of other improvements as well,
including profile-guided optimization.

## Thank You!

Go has always been far more than what the Go team at Google does.
Thanks to all of you—our contributors and everyone in the Go community—for
your help making Go the successful programming environment that it is today.
We wish you all the best in the coming year.

---

## File: _content/blog/14years.md

---
title: Fourteen Years of Go
date: 2023-11-10
by:
- Russ Cox, for the Go team
summary: Happy Birthday, Go!
---



Today we celebrate the fourteenth birthday of the Go open source release!
Go has had a great year, with two feature-filled releases and other important milestones.

We released [Go 1.20 in February](/blog/go1.20)
and [Go 1.21 in August](/blog/go1.21),
focusing more on implementation improvements
than new language changes.

Profile-guided optimization (PGO),
[previewed in Go 1.20](/blog/pgo-preview)
and
[released in Go 1.21](/blog/pgo),
allows the Go compiler to read a profile of your program
and then spend more time optimizing the parts
of your program that run most often.
In Go 1.21, workloads typically get between
2% and 7% CPU usage improvements from enabling PGO.
See “[Profile-guided optimization in Go 1.21](/blog/pgo)” for an overview
and the [profile-guided optimization user guide](/doc/pgo)
for complete documentation.

Go has provided support for gathering coverage profiles during `go test`
[since Go 1.2](/blog/cover).
Go 1.20 added support for gathering coverage profiles in binaries
built by `go build`,
allowing you to gather coverage during larger integration tests as well.
See “[Code coverage for Go integration tests](/blog/integration-test-coverage)” for details.

Compatibility has been an important part of Go since
“[Go 1 and the Future of Go Programs](/doc/go1compat)”.
Go 1.21 improved compatibility further
by expanding the conventions for use of GODEBUG
in situations where we need to make a change,
such as an important bug fix,
that must be permitted but may still break existing programs.
See the blog post
“[Backward Compatibility, Go 1.21, and Go 2](/blog/compat)”
for an overview and
the documentation
“[Go, Backwards Compatibility, and GODEBUG](/doc/godebug)” for details.

Go 1.21 also shipped support for built-in toolchain management,
allowing you to change which version of the
Go toolchain you use in a specific module
as easily as you change the versions of other dependencies.
See the blog post
“[Forward Compatibility and Toolchain Management in Go 1.21](/blog/toolchain)”
for an overview and the documentation
“[Go Toolchains](/doc/toolchain)”
for details.

Another important tooling achievement was the
integration of on-disk indexes into
gopls, the Go LSP server.
This cut gopls's startup latency and memory usage by 3-5X
in typical use cases.
“[Scaling gopls for the growing Go ecosystem](/blog/gopls-scalability)”
explains the technical details.
You can make sure you're running the latest gopls by running:

```
go install golang.org/x/tools/gopls@latest
```

Go 1.21 introduced new
[cmp](/pkg/cmp/),
[maps](/pkg/maps/),
and
[slices](/pkg/slices/)
packages — Go’s first generic standard libraries —
as well as expanding the set of comparable types.
For details about that, see the blog post
“[All your comparable types](/blog/comparable)”.

Overall, we continue to refine generics
and to write talks and blog posts explaining
important details.
Two notable posts this year were
“[Deconstructing Type Parameters](/blog/deconstructing-type-parameters)”,
and
“[Everything You Always Wanted to Know About Type Inference – And a Little Bit More](/blog/type-inference)”.

Another important new package in Go 1.21 is
[log/slog](/pkg/log/slog/),
which adds an official API for
structured logging to the standard library.
See “[Structured logging with slog](/blog/slog)” for an overview.

For the WebAssembly (Wasm) port, Go 1.21 shipped support
for running on WebAssembly System Interface (WASI) preview 1.
WASI preview 1 is a new “operating system” interface for Wasm
that is supported by most server-side Wasm environments.
See “[WASI support in Go](/blog/wasi)” for a walkthrough.

On the security side, we are continuing to make sure
Go leads the way in helping developers understand their
dependencies and vulnerabilities,
with [Govulncheck 1.0 launching in July](/blog/govulncheck).
If you use VS Code, you can run govulncheck directly in your
editor using the Go extension:
see [this tutorial](/doc/tutorial/govulncheck-ide) to get started.
And if you use GitHub, you can run govulncheck as part of
your CI/CD, with the
[GitHub Action for govulncheck](https://github.com/marketplace/actions/golang-govulncheck-action).
For more about checking your dependencies for vulnerability problems,
see this year's Google I/O talk,
“[Build more secure apps with Go and Google](https://www.youtube.com/watch?v=HSt6FhsPT8c&ab_channel=TheGoProgrammingLanguage)”.)

Another important security milestone was
Go 1.21's highly reproducible toolchain builds.
See “[Perfectly Reproducible, Verified Go Toolchains](/blog/rebuild)” for details,
including a demonstration of reproducing an Ubuntu Linux Go toolchain
on a Mac without using any Linux tools at all.

It has been a busy year!

In Go's 15th year, we'll keep working to make Go the best environment
for software engineering at scale.
One change we're particularly excited about is
redefining for loop `:=` semantics to remove the
potential for accidental aliasing bugs.
See “[Fixing For Loops in Go 1.22](/blog/loopvar-preview)”
for details,
including instructions for previewing this change in Go 1.21.

## Thank You!

The Go project has always been far more than just us on the Go team at Google.
Thank you to all our contributors and everyone in the Go community for
making Go what it is today.
We wish you all the best in the year ahead.

---

## File: _content/blog/15years.md

---
title: Go Turns 15
date: 2024-11-11
by:
- Austin Clements, for the Go team
tags:
- community
- birthday
summary: Happy 15th birthday, Go!
---



*Thanks to Renee French for drawing and animating the gopher doing the “15 puzzle”.*


Happy birthday, Go\!

On Sunday, we celebrated the 15th anniversary of [the Go open source
release](https://opensource.googleblog.com/2009/11/hey-ho-lets-go.html)\!

So much has changed since [Go's 10 year anniversary](/blog/10years),
both in Go and in the world. In other ways, so much has stayed the
same: Go remains committed to stability, safety, and supporting
software engineering and production at scale.

And Go is going strong\! Go's user base has more than tripled in the
past five years, making it one of the fastest growing languages. From
its beginnings just fifteen years ago, Go has become a top 10 language
and the language of the modern cloud.

With the releases of [Go 1.22 in February](/blog/go1.22) and [Go 1.23
in August](/blog/go1.23), it's been the year of `for` loops. Go 1.22
made variables introduced by `for` loops [scoped per
iteration](/blog/loopvar-preview), rather than per loop, addressing a
long-standing language "gotcha". Over ten years ago, leading up to the
release of Go 1, the Go team made decisions about several language
details; among them whether `for` loops should create a new loop
variable on each iteration. Amusingly, the discussion was quite brief
and distinctly unopinionated. Rob Pike closed it out in true Rob Pike
fashion with a single word: “stet” (leave it be). And so it was. While
seemingly insignificant at the time, years of production experience
highlighted the implications of this decision. But in that time, we
also built robust tools for understanding the effects of changes to
Go—notably, ecosystem-wide analysis and testing across the entire
Google codebase—and established processes for working with the
community and getting feedback. Following extensive testing, analysis,
and community discussion, we rolled out the change, accompanied by a
[hash bisection
tool](https://go.googlesource.com/proposal/+/master/design/60078-loopvar.md#transition-support-tooling)
to assist developers in pinpointing code affected by the change at
scale.

The change to `for` loops was part of a five year trajectory of
measured changes. It would not have been possible without [forward
language compatibility](/blog/toolchain) introduced in Go 1.21. This,
in turn, built upon the foundation laid by Go modules, which were
introduced in Go 1.14 four and a half years ago.

Go 1.23 further built on this change to introduce iterators and
[user-defined for-range loops](/blog/range-functions). Combined with
generics—introduced in Go 1.18, just two and a half years ago\!—this
creates a powerful and ergonomic foundation for custom collections and
many other programming patterns.

These releases have also brought many improvements in production
readiness, including [much-anticipated enhancements to the standard
library's HTTP router](/blog/routing-enhancements), a [total overhaul
of execution traces](/blog/execution-traces-2024), and [stronger
randomness](/blog/chacha8rand) for all Go applications. Additionally,
the introduction of our [first v2 standard library
package](/blog/randv2) establishes a template for future library
evolution and modernization.

Over the past year we've also been cautiously rolling out [opt-in
telemetry](/blog/gotelemetry) for Go tools. This system will give Go's
developers data to make better decisions, while remaining completely
[open](https://telemetry.go.dev/) and anonymous. Go telemetry first
appeared in
[gopls](https://github.com/golang/tools/blob/master/gopls/README.md),
the Go language server, where it has already led to a [litany of
improvements](https://github.com/golang/go/issues?q=is%3Aissue+label%3Agopls%2Ftelemetry-wins).
This effort paves the way to make programming in Go an even better
experience for everyone.

Looking forward, we're evolving Go to better leverage the capabilities
of current and future hardware. Hardware has changed a lot in the past
15 years. In order to ensure Go continues to support high-performance,
large-scale production workloads for the *next* 15 years, we need to
adapt to large multicores, advanced instruction sets, and the growing
importance of locality in increasingly non-uniform memory hierarchies.
Some of these improvements will be transparent. Go 1.24 will have a
totally new `map` implementation under the hood that's more efficient
on modern CPUs. And we're prototyping new garbage collection
algorithms designed around the capabilities and constraints of modern
hardware. Some improvements will be in the form of new APIs and tools
so Go developers can better leverage modern hardware. We're looking at
how to support the latest vector and matrix hardware instructions, and
multiple ways that applications can build in CPU and memory locality.
A core principle guiding our efforts is *composable optimization*: the
impact of an optimization on a codebase should be as localized as
possible, ensuring that the ease of development across the rest of the
codebase is not compromised.

We're continuing to ensure Go's standard library is safe by default
and safe by design. This includes ongoing efforts to incorporate
built-in, native support for FIPS-certified cryptography, so that FIPS
crypto will be just a flag flip away for applications that need it.
Furthermore, we're evolving Go's standard library packages where we
can and, following the example of `math/rand/v2`, considering where
new APIs can significantly enhance the ease of writing safe and secure
Go code.

We're working on making Go better for AI—and AI better for Go—by
enhancing Go's capabilities in AI infrastructure, applications, and
developer assistance. Go is a great language for building production
systems, and we want it to be a great language for [building
production *AI* systems](/blog/llmpowered), too.
Go's dependability as a language
for Cloud infrastructure has made it a natural choice for
[LLM](https://ollama.com/) [infrastructure](https://weaviate.io/)
[as](https://localai.io/) [well](https://zilliz.com/what-is-milvus).
For AI applications, we will continue building out first-class support
for Go in popular AI SDKs, including
[LangChainGo](https://pkg.go.dev/github.com/tmc/langchaingo) and
[Genkit](https://developers.googleblog.com/en/introducing-genkit-for-go-build-scalable-ai-powered-apps-in-go/).
And from its very beginning, Go aimed to improve the end-to-end
software engineering process, so naturally we're looking at bringing
the latest tools and techniques from AI to bear on reducing developer
toil, leaving more time for the fun stuff—like actually programming\!

## Thank you

All of this is only possible because of Go's incredible contributors
and thriving community. Fifteen years ago we could only dream of the
success that Go has become and the community that has developed around
Go. Thank you to everyone who has played a part, large and small. We
wish you all the best in the coming year.

---

## File: _content/blog/16years.md

---
title: Go’s Sweet 16
date: 2025-11-14
by:
- Austin Clements, for the Go team
tags:
- community
- birthday
summary: Happy Birthday, Go!
---

This past Monday, November 10th, we celebrated the 16th anniversary of Go’s
[open source
release](https://opensource.googleblog.com/2009/11/hey-ho-lets-go.html)\!

We released [Go 1.24 in February](/blog/go1.24) and [Go 1.25 in
August](/blog/go1.25), following our now well-established and dependable release
cadence. Continuing our mission to build the most productive language platform
for building production systems, these releases included new APIs for building
robust and reliable software, significant advances in Go’s track record for
building secure software, and some serious under-the-hood improvements.
Meanwhile, no one can ignore the seismic shifts in our industry brought by
generative AI. The Go team is applying its thoughtful and uncompromising mindset
to the problems and opportunities of this dynamic space, working to bring Go’s
production-ready approach to building robust AI integrations, products, agents,
and infrastructure.

# Core language and library improvements

First released in Go 1.24 as an experiment and then graduated in Go 1.25, the
new [`testing/synctest`](https://pkg.go.dev/testing/synctest) package
significantly simplifies writing tests for [concurrent, asynchronous
code](/blog/testing-time). Such code is particularly common in network services,
and is traditionally very hard to test well. The `synctest` package works by
virtualizing time itself. It takes tests that used to be slow, flaky, or both,
and makes them easy to rewrite into reliable and nearly instantaneous tests,
often with just a couple extra lines of code. It’s also a great example of Go’s
integrated approach to software development: behind an almost trivial API, the
`synctest` package hides a deep integration with the Go runtime and other parts
of the standard library.

This isn’t the only boost the `testing` package got over the past year. The new
[`testing.B.Loop`](https://pkg.go.dev/testing#B.Loop) API is both easier to use
than the original `testing.B.N` API and addresses many of the traditional—and
often invisible\!—[pitfalls](/blog/testing-b-loop) of writing Go benchmarks. The
`testing` package also has new APIs that [make it easy to
cleanup](https://pkg.go.dev/testing#T.Context) in tests that use
[`Context`](https://pkg.go.dev/context#Context), and that [make it
easy](https://pkg.go.dev/testing#T.Output) to write to the test’s log.

Go and containerization grew up together and work great with each other. Go 1.25
launched [container-aware scheduling](/blog/container-aware-gomaxprocs), making
this pairing even stronger. Without developers having to lift a finger, this
transparently adjusts the parallelism of Go workloads running in containers,
preventing CPU throttling that can impact tail latency and improving Go’s
out-of-the-box production-readiness.

Go 1.25’s new [flight recorder](/blog/flight-recorder) builds on our already
powerful execution tracer, enabling deep insights into the dynamic behavior of
production systems. While the execution tracer generally collected *too much*
information to be practical in long-running production services, the flight
recorder is like a little time machine, allowing a service to snapshot recent
events in great detail *after* something has gone wrong.

## Secure software development

Go continues to strengthen its commitment to secure software development, making
significant strides in its native cryptography packages and evolving its
standard library for enhanced safety.

Go ships with a full suite of native cryptography packages in the standard
library, which reached two major milestones over the past year. A security
audit conducted by independent security firm [Trail of
Bits](https://www.trailofbits.com/) yielded [excellent
results](/blog/tob-crypto-audit), with only a single low-severity finding.
Furthermore, through a collaborative effort between the Go Security Team and
[Geomys](https://geomys.org/), these packages achieved CAVP certification,
paving the way for [full FIPS 140-3 certification](/blog/fips140). This is a
vital development for Go users in certain regulated environments. FIPS 140
compliance, previously a source of friction due to the need for unsupported
solutions, will now be seamlessly integrated, addressing concerns related to
safety, developer experience, functionality, release velocity, and compliance.

The Go standard library has continued to evolve to be *safe by default* and
*safe by design*. For example, the [`os.Root`](https://pkg.go.dev/os#Root)
API—added in Go 1.24—enables [traversal-resistant file system
access](/blog/osroot), effectively combating a class of vulnerabilities where an
attacker could manipulate programs into accessing files intended to be
inaccessible. Such vulnerabilities are notoriously challenging to address
without underlying platform and operating system support, and the new
[`os.Root`](https://pkg.go.dev/os#Root) API offers a straightforward,
consistent, and portable solution.

## Under-the-hood improvements

In addition to user-visible changes, Go has made significant improvements under
the hood over the past year.

For Go 1.24, we completely [redesigned the `map`
implementation](/blog/swisstable), building on the latest and greatest ideas in
hash table design. This change is completely transparent, and brings significant
improvements to `map` performance, lower tail latency of `map` operations, and
in some cases even significant memory wins.

Go 1.25 includes an experimental and significant advancement in Go’s garbage
collector called [Green Tea](/blog/greenteagc). Green Tea reduces garbage
collection overhead in many applications by at least 10% and sometimes as much
as 40%. It uses a novel algorithm designed for the capabilities and constraints
of today’s hardware and opens up a new design space that we’re eagerly
exploring. For example, in the forthcoming Go 1.26 release, Green Tea will
achieve an additional 10% reduction in garbage collector overhead on hardware
that supports AVX-512 vector instructions—something that would have been nigh
impossible to take advantage of in the old algorithm. Green Tea will be enabled
by default in Go 1.26; users need only upgrade their Go version to benefit.

# Furthering the software development stack

Go is about far more than the language and standard library. It’s a software
development platform, and over the past year, we’ve also made four regular
releases of the [gopls language server](/gopls), and have formed partnerships to
support emerging new frameworks for agentic applications.

Gopls provides Go support to VS Code and other LSP-powered editors and IDEs.
Every release sees a litany of features and improvements to the experience of
reading and writing Go code (see the [v0.17.0](/gopls/release/v0.17.0),
[v0.18.0](/gopls/release/v0.18.0), [v0.19.0](/gopls/release/v0.19.0), and
[v0.20.0](/gopls/release/v0.20.0) release notes for full details, or our new
[gopls feature documentation](/gopls/features)\!). Some highlights include many
new and enhanced analyzers to help developers write more idiomatic and robust Go
code; refactoring support for variable extraction, variable inlining, and JSON
struct tags; and an [experimental built-in server](/gopls/features/mcp) for the
Model Context Protocol (MCP) that exposes a subset of gopls’ functionality to AI
assistants in the form of MCP tools.

With gopls v0.18.0, we began exploring *automatic code modernizers*. As Go
evolves, every release brings new capabilities and new idioms; new and better
ways to do things that Go programmers have been finding other ways to do. Go
stands by its [compatibility promise](/doc/go1compat)—the old way will continue
to work in perpetuity—but nevertheless this creates a bifurcation between old
idioms and new idioms. Modernizers are static analysis tools that recognize old
idioms and suggest faster, more readable, more secure, more *modern*
replacements, and do so with push-button reliability. What `gofmt` did for
[stylistic consistency](/blog/gofmt), we hope modernizers can do for idiomatic
consistency. We’ve integrated modernizers as IDE suggestions, where they can
help developers not only maintain more consistent coding standards, but where we
believe they will help developers discover new features and keep up with the
state of the art. We believe modernizers can also help AI coding assistants keep
up with the state of the art and combat their proclivity to reinforce outdated
knowledge of the Go language, APIs, and idioms. The upcoming Go 1.26 release
will include a total overhaul of the long-dormant `go fix` command to make it
apply the full suite of modernizers in bulk, a return to its [pre-Go 1.0
roots](/blog/introducing-gofix).

At the end of September, in collaboration with
[Anthropic](https://www.anthropic.com/) and the Go community, we released
[v1.0.0](https://github.com/modelcontextprotocol/go-sdk/releases/tag/v1.0.0) of
the [official Go SDK](https://github.com/modelcontextprotocol/go-sdk) for the
[Model Context Protocol (MCP)](https://modelcontextprotocol.io/). This SDK
supports both MCP clients and MCP servers, and underpins the new MCP
functionality in gopls. Contributing this work in open source helps empower
other areas of the growing open source agentic ecosystem built around Go, such
as the recently released [Agent Development Kit (ADK) for
Go](https://github.com/google/adk-go) from [Google](https://www.google.com/).
ADK Go builds on the Go MCP SDK to provide an idiomatic framework for building
modular multi-agent applications and systems. The Go MCP SDK and ADK Go
demonstrate how Go’s unique strengths in concurrency, performance, and
reliability differentiate Go for production AI development and we are expecting
more AI workloads to be written in Go in the coming years.

# Looking ahead

Go has an exciting year ahead of it.

We’re working on advancing developer productivity through the brand new `go fix`
command, deeper support for AI coding assistants, and ongoing improvements to
gopls and VS Code Go. General availability of the Green Tea garbage collector,
native support for Single Instruction Multiple Data (SIMD) hardware features,
and runtime and standard library support for writing code that scales even
better to massive multicore hardware will continue to align Go with modern
hardware and improve production efficiency. We’re focusing on Go’s “production
stack” libraries and diagnostics, including a massive (and long in the making)
[upgrade to `encoding/json`](/issue/71497), driven by Joe Tsai and people across
the Go community; [leaked goroutine
profiling](/design/74609-goroutine-leak-detection-gc), contributed by
[Uber’s](https://www.uber.com/us/en/about/) Programming Systems team; and many
other improvements to `net/http`, `unicode`, and other foundational packages.
We’re working to provide well-lit paths for building with Go and AI, evolving
the language platform with care for the evolving needs of today’s developers,
and building tools and capabilities that help both human developers and AI
assistants and systems alike.

On this 16th anniversary of Go’s open source release, we’re also looking to the
future of the Go open source project itself. From its [humble
beginnings](https://www.youtube.com/watch?v=wwoWei-GAPo), Go has formed a
thriving contributor community. To continue to best meet the needs of our
ever-expanding user base, especially in a time of upheaval in the software
industry, we’re working on ways to better scale Go's development
processes—without losing sight of Go’s fundamental principles—and more deeply
involve our wonderful contributor community.

Go would not be where it is today without our incredible user and contributor
communities. We wish you all the best in the coming year\!

---

## File: _content/blog/1year.md

---
title: "Go: one year ago today"
date: 2010-11-10
by:
- Andrew Gerrand
tags:
- birthday
summary: Happy 1st birthday, Go!
---


On the 10th of November 2009 we launched the Go project:
an open-source programming language with a focus on simplicity and efficiency.
The intervening year has seen a great many developments both in the Go project
itself and in its community.

We set out to build a language for systems programming - the kinds of programs
one might typically write in C or C++ - and we were surprised by Go’s
utility as a general purpose language.
We had anticipated interest from C, C++, and Java programmers,
but the flurry of interest from users of dynamically-typed languages like
Python and JavaScript was unexpected.
Go’s combination of native compilation,
static typing, memory management, and lightweight syntax seemed to strike
a chord with a broad cross-section of the programming community.

That cross-section grew to become a dedicated community of enthusiastic Go coders.
Our [mailing list](http://groups.google.com/group/golang-nuts) has over 3,800 members,
with around 1,500 posts each month.
The project has over 130 contributors
(people who have submitted code or documentation),
and of the 2,800 commits since launch almost one third were contributed
by programmers outside the core team.
To get all that code into shape, nearly 14,000 emails were exchanged on
our [development mailing list](http://groups.google.com/group/golang-dev).

Those numbers reflect a labor whose fruits are evident in the project’s code base.
The compilers have improved substantially,
with faster and more efficient code generation,
more than one hundred reported bugs fixed,
and support for a widening range of operating systems and architectures.
The Windows port is approaching completion thanks to a dedicated group of
contributors (one of whom became our first non-Google committer to the project).
The ARM port has also made great progress,
recently reaching the milestone of passing all tests.

The Go tool set has been expanded and improved.
The Go documentation tool, [godoc](/cmd/godoc/),
now supports the documentation of other source trees (you can browse and
search your own code) and provides a ["code walk"](/doc/codewalk/)
interface for presenting tutorial materials (among many more improvements).
[Goinstall](/cmd/goinstall/) ,
a new package management tool, allows users to install and update external
packages with a single command.
[Gofmt](/cmd/gofmt/),
the Go pretty-printer, now makes syntactic simplifications where possible.
Goplay,
a web-based “compile-as-you-type” tool,
is a convenient way to experiment with Go for those times when you don’t
have access to the [Go Playground](/doc/play/).

The standard library has grown by over 42,000 lines of code and includes
20 new [packages](/pkg/).
Among the additions are the [jpeg](/pkg/image/jpeg/),
[jsonrpc](/pkg/rpc/jsonrpc/),
[mime](/pkg/mime/), [netchan](/pkg/netchan/),
and [smtp](/pkg/smtp/) packages,
as well as a slew of new [cryptography](/pkg/crypto/) packages.
More generally, the standard library has been continuously refined and revised
as our understanding of Go’s idioms deepens.

The debugging story has gotten better, too.
Recent improvements to the DWARF output of the gc compilers make the GNU debugger,
GDB, useful for Go binaries, and we’re actively working on making that
debugging information more complete.
(See the [recent blog post](/blog/debugging-go-code-status-report) for details.)

It’s now easier than ever to link against existing libraries written in
languages other than Go.
Go support is in the most recent [SWIG](http://www.swig.org/) release,
version 2.0.1, making it easier to link against C and C++ code,
and our [cgo](/cmd/cgo/) tool has seen many fixes and improvements.

[Gccgo](/doc/install/gccgo),
the Go front end for the GNU C Compiler, has kept pace with the gc compiler
as a parallel Go implementation.
It now has a working garbage collector, and has been accepted into the GCC core.
We’re now working toward making [gofrontend](http://code.google.com/p/gofrontend/)
available as a BSD-licensed Go compiler front end,
fully decoupled from GCC.

Outside the Go project itself Go is starting to be used to build real software.
There are more than 200 Go programs and libraries listed on our [Project dashboard](http://godashboard.appspot.com/project),
and hundreds more on [Google Code](http://code.google.com/hosting/search?q=label:Go)
and [GitHub](https://github.com/search?q=language:Go).
On our mailing list and IRC channel you can find coders from around the
world who use Go for their programming projects.
(See our [guest blog post](/blog/real-go-projects-smarttwitter-and-webgo)
from last month for a real-world example.) Internally at Google there are
several teams that choose Go for building production software,
and we have received reports from other companies that are developing sizable systems in Go.
We have also been in touch with several educators who are using Go as a teaching language.

The language itself has grown and matured, too.
In the past year we have received many feature requests.
But Go is a small language, and we’ve worked hard to ensure that any new
feature strikes the right compromise between simplicity and utility.
Since the launch we have made a number of language changes,
many of which were driven by feedback from the community.

  - Semicolons are now optional in almost all instances. [spec](/doc/go_spec.html#Semicolons)
  - The new built-in functions `copy` and `append` make management of slices
    more efficient and straightforward.
    [spec](/doc/go_spec.html#Appending_and_copying_slices)
  - The upper and lower bounds may be omitted when making a sub-slice.
    This means that `s[:]` is shorthand for `s[0:len(s)]`.
    [spec](/doc/go_spec.html#Slices)
  - The new built-in function `recover` complements `panic` and `defer` as
    an error handling mechanism.
    [blog](/blog/defer-panic-and-recover),
    [spec](/doc/go_spec.html#Handling_panics)
  - The new complex number types (`complex`,
    `complex64`, and `complex128`) simplify certain mathematical operations.
    [spec](/doc/go_spec.html#Complex_numbers),
    [spec](/doc/go_spec.html#Imaginary_literals)
  - The composite literal syntax permits the omission of redundant type information
    (when specifying two-dimensional arrays, for example).
    [release.2010-10-27](/doc/devel/release.html#2010-10-27),
    [spec](/doc/go_spec.html#Composite_literals)
  - A general syntax for variable function arguments (`...T`) and their propagation
    (`v...`) is now specified.
    [spec](/doc/go_spec.html#Function_Types),
    [ spec](/doc/go_spec.html#Passing_arguments_to_..._parameters),
    [release.2010-09-29](/doc/devel/release.html#2010-09-29)

Go is certainly ready for production use,
but there is still room for improvement.
Our focus for the immediate future is making Go programs faster and more
efficient in the context of high performance systems.
This means improving the garbage collector,
optimizing generated code, and improving the core libraries.
We’re also exploring some further additions to the type system to make
generic programming easier.
A lot has happened in a year; it’s been both thrilling and satisfying.
We hope that this coming year will be even more fruitful than the last.

_If you’ve been meaning to get [back] into Go, now is a great time to do so! Check out the_
[_Documentation_](/doc/docs.html) _and_ [_Getting Started_](/doc/install.html)
_pages for more information, or just go nuts in the_ [_Go Playground_](/doc/play/).

---

## File: _content/blog/2years.md

---
title: The Go Programming Language turns two
date: 2011-11-10
by:
- Andrew Gerrand
tags:
- appengine
- community
- gopher
summary: Happy 2nd birthday, Go!
template: true
---


Two years ago a small team at Google went public with their fledgling project -
the Go Programming Language.
They presented a language spec, two compilers,
a modest standard library, some novel tools,
and plenty of accurate (albeit succinct) documentation.
They watched with excitement as programmers around the world began to play with Go.
The team continued to iterate and improve on what they had built,
and were gradually joined by dozens - and then hundreds - of programmers
from the open source community.
The Go Authors went on to produce lots of libraries,
new tools, and reams of [documentation](/doc/docs.html).
They celebrated a successful year in the public eye with a [blog post](/blog/go-one-year-ago-today)
last November that concluded "Go is certainly ready for production use,
but there is still room for improvement.
Our focus for the immediate future is making Go programs faster and more
efficient in the context of high performance systems."

Today is the second anniversary of Go's release,
and Go is faster and more stable than ever.
Careful tuning of Go's code generators, concurrency primitives,
garbage collector, and core libraries have increased the performance of Go programs,
and native support for [profiling](/blog/profiling-go-programs)
and [debugging](/blog/debugging-go-programs-with-gnu-debugger)
makes it easier to detect and remove performance issues in user code.
Go is also now easier to learn with [A Tour of Go](/tour/),
an interactive tutorial you can take from the comfort of your web browser.

This year we introduced the experimental [Go runtime](http://code.google.com/appengine/docs/go/)
for Google's App Engine platform,
and we have been steadily increasing the Go runtime's support for App Engine's APIs.
Just this week we released [version 1.6.0](http://code.google.com/appengine/downloads.html)
of the Go App Engine SDK,
which includes support for [backends](http://code.google.com/appengine/docs/go/backends/overview.html)
(long-running processes),
finer control over datastore indexes, and various other improvements.
Today, the Go runtime is near feature parity with - and is a viable alternative
to - the Python and Java runtimes.
In fact, we now serve [golang.org](/) by running a version
of [godoc](/cmd/godoc/) on the App Engine service.

While 2010 was a year of discovery and experimentation,
2011 was a year of fine tuning and planning for the future.
This year we issued several "[release](/doc/devel/release.html)"
versions of Go that were more reliable and better supported than weekly snapshots.
We also introduced [gofix](/cmd/gofix/) to take the
pain out of migrating to newer releases.
Furthermore, last month we announced a [plan for Go version 1](/blog/preview-of-go-version-1) -
a release that will be supported for years to come.
Work toward Go 1 is already underway and you can observe our progress by
the latest weekly snapshot at [weekly.golang.org](http://weekly.golang.org/pkg/).

The plan is to launch Go 1 in early 2012.
We hope to bring the Go App Engine runtime out of "experimental" status at the same time.

But that's not all. 2011 was an exciting year for the gopher, too.
He has manifested himself as a plush toy (a highly prized gift at Google
I/O and other Go talks) and in vinyl form (received by every attendee at
OSCON and now available at the [Google Store](http://www.googlestore.com/Fun/Go+Gopher+Figurine.axd)).

{{image "2years/2years-gophers.jpg"}}

And, most surprisingly, at Halloween he made an appearance with his gopher girlfriend!

{{image "2years/2years-costume.jpg"}}

Photograph by [Chris Nokleberg](https://plus.google.com/106640494112897458359/posts).

---

## File: _content/blog/3years.md

---
title: Go turns three
date: 2012-11-10
by:
- Russ Cox
tags:
- community
- birthday
summary: Happy 3rd birthday, Go!
---


The Go open source project is
[three years old today](http://google-opensource.blogspot.com/2009/11/hey-ho-lets-go.html).

It's great to look at how far Go has come in those three years.
When we launched, Go was an idea backed by two implementations that worked on Linux and OS X.
The syntax, semantics, and libraries changed regularly as we reacted to feedback from users
and experience with the language.

Since the open source launch,
we've been joined by
hundreds of external contributors,
who have extended and improved Go in myriad ways,
including writing a Windows port from scratch.
We added a package management system
[goinstall](https://groups.google.com/d/msg/golang-nuts/8JFwR3ESjjI/cy7qZzN7Lw4J),
which eventually became the
[go command](/cmd/go/).
We also added
[support for Go on App Engine](/blog/go-for-app-engine-is-now-generally).
Over the past year we've also given [many talks](/doc/#talks), created an [interactive introductory tour](/tour/)
and recently we added support for [executable examples in package documentation](/pkg/strings/#pkg-examples).

Perhaps the most important development in the past year
was the launch of the first stable version,
[Go 1](/blog/go1).
People who write Go 1 programs can now be confident that their programs will
continue to compile and run without change, in many environments,
on a time scale of years.
As part of the Go 1 launch we spent months cleaning up the
[language and libraries](/doc/go1.html)
to make it something that will age well.

We're working now toward the release of Go 1.1 in 2013. There will be some
new functionality, but that release will focus primarily on making Go perform
even better than it does today.

We're especially happy about the community that has grown around Go:
the mailing list and IRC channels seem like they are overflowing with discussion,
and a handful of Go books were published this year. The community is thriving.
Use of Go in production environments has also taken off, especially since Go 1.

We use Go at Google in a variety of ways, many of them invisible to the outside world.
A few visible ones include
[serving Chrome and other downloads](https://groups.google.com/d/msg/golang-nuts/BNUNbKSypE0/E4qSfpx9qI8J),
[scaling MySQL database at YouTube](http://code.google.com/p/vitess/),
and of course running the
[Go home page](/)
on [App Engine](https://developers.google.com/appengine/docs/go/overview).
Last year's
[Thanksgiving Doodle](/blog/from-zero-to-go-launching-on-google)
and the recent
[Jam with Chrome](http://www.jamwithchrome.com/technology)
site are also served by Go programs.

Other companies and projects are using Go too, including
[BBC Worldwide](http://www.quora.com/Go-programming-language/Is-Google-Go-ready-for-production-use/answer/Kunal-Anand),
[Canonical](http://dave.cheney.net/wp-content/uploads/2012/08/august-go-meetup.pdf),
[CloudFlare](http://blog.cloudflare.com/go-at-cloudflare),
[Heroku](/blog/go-at-heroku),
[Novartis](https://plus.google.com/114945221884326152379/posts/d1SVaqkRyTL),
[SoundCloud](http://backstage.soundcloud.com/2012/07/go-at-soundcloud/),
[SmugMug](http://sorcery.smugmug.com/2012/04/06/deriving-json-types-in-go/),
[StatHat](/blog/building-stathat-with-go),
[Tinkercad](https://tinkercad.com/about/jobs),
and
[many others](/wiki/GoUsers).

Here's to many more years of productive programming in Go.

---

## File: _content/blog/4years.md

---
title: Four years of Go
date: 2013-11-10
by:
- Andrew Gerrand
tags:
- community
- birthday
summary: Happy 4th birthday, Go!
template: true
---


Today marks the fourth anniversary of Go as an open source project.

{{image "4years/4years-gopher.png"}}

Rather than talk about our technical progress (there'll be much to talk about
when we release Go 1.2 in a couple of weeks) we thought we would instead take
this occasion to look at how the Go community has grown.

Let's start with a chart:

{{image "4years/4years-graph.png"}}

This chart shows the growth of Google searches for the term
"[golang](http://www.google.com/trends/explore?hl=en-US#q=golang&date=10/2009+50m&cmpt=q)"
over the past four years.
Notice the knee in the curve around March 2012, when Go 1.0 was released.
If these searches are a decent proxy for interest, then it's clear that
interest in Go has grown remarkably since launch, and particularly so in the
last 2 years.

But where is the interest coming from?

The open source community has embraced Go,
with our community wiki listing [hundreds of Go projects](/wiki/Projects). Some popular ones:

  - [Docker](http://docker.io) is a tool for packaging and running applications
    in lightweight containers.
    Docker makes it easy to isolate, package,
    and deploy applications, and is beloved by system administrators.
    Its creator Solomon Hykes cited Go's standard library,
    concurrency primitives, and ease of deployment as key factors,
    and said "To put it simply, if Docker had not been written in Go,
    it would not have been as successful."

  - [Packer](http://packer.io) is a tool for automating the creation of
    machine images for deployment to virtual machines or cloud services.
    Its author, Mitchell Hashimoto, is now working on another Go project,
    [serf](http://www.serfdom.io/), a decentralized discovery service.
    Like Docker, these projects help with management of large-scale,
    cluster-based services.

  - [Bitly](http://bit.ly)'s [NSQ](http://bitly.github.io/nsq/) is a realtime
    distributed messaging platform designed for fault-tolerance and high-availability,
    and is used in production at bitly and a bunch of other companies.

  - [Canonical](http://canonical.com/)'s [JuJu](https://juju.ubuntu.com/)
    infrastructure automation system was rewritten in Go.
    Project lead Gustavo Niemeyer said "It's not a single aspect of Go that
    makes it a compelling choice,
    but rather the careful organization of well-crafted small pieces."

  - The [raft](https://github.com/goraft/raft) package provides an implementation
    of the [Raft](https://ramcloud.stanford.edu/wiki/download/attachments/11370504/raft.pdf)
    distributed consensus protocol.
    It is the basis of Go projects like [etcd](https://github.com/coreos/etcd)
    and [SkyDNS](https://github.com/skynetservices/skydns).

  - Other popular projects include [biogo](https://github.com/biogo/biogo),
    the [Gorilla Web Toolkit](http://www.gorillatoolkit.org/),
    [groupcache](https://github.com/golang/groupcache),
    Mozilla's [heka](https://github.com/mozilla-services/heka),
    the [kv](https://github.com/cznic/kv) and [ql](https://github.com/cznic/ql)
    lightweight storage systems,
    and the [Sky](http://skydb.io/) behavioral database.

But this is just the tip of the iceberg. The number of high-quality open
source Go projects is phenomenal.
Prolific Go hacker [Keith Rarick](http://xph.us/software/) put it well:
"The state of the Go ecosystem after only four years is astounding.
Compare Go in 2013 to Python in 1995 or Java in 1999. Or C++ in 1987!"

Businesses are enjoying Go, too. The [Go Users wiki page](/wiki/GoUsers)
lists dozens of success stories (and if you use Go,
please add yourself to it). Some examples:

  - [CloudFlare](https://blog.cloudflare.com/go-at-cloudflare) built their
    distributed DNS service entirely with Go,
    and are in the process of migrating their gigabytes-per-minute logging infrastructure to the language.
    Programmer John Graham-Cumming said "We've found Go to be the perfect match for our needs:
    the combination of familiar syntax, a powerful type system,
    a strong network library and built-in concurrency means that more and more
    projects are being built here in Go."

  - [SoundCloud](http://soundcloud.com) is an audio distribution service
    that has "dozens of [systems in Go](http://backstage.soundcloud.com/2012/07/go-at-soundcloud/),
    touching almost every part of the site, and in many cases powering features
    from top to bottom." Engineer Peter Bourgon said "Go demonstrates that the
    cruft that burdens other languages and ecosystems—stuff that developers
    have learned to deal with,
    often in anger—is simply not a necessary part of modern programming.
    With Go, I have a straightforward and non-adversarial relationship with my tools,
    from development to production."

  - The [ngrok](https://ngrok.com/) service allows web developers to provide
    remote access to their development environments.
    Its author Alan Shreve said that "ngrok's success as a project is due in
    no small part to choosing Go as the implementation language," citing Go's HTTP libraries,
    efficiency, cross-platform compatibility,
    and ease of deployment as the major benefits.

  - [Poptip](http://poptip.com) provides social analytics services,
    and product engineer Andy Bonventre said "What started as an experiment
    in writing a single service in Go turned into moving almost our entire infrastructure over to it.
    What I love about Go the most is not necessarily the features of the language,
    but the focus on tooling, testing, and other elements that make writing
    large applications much more manageable."

  - Music collaboration startup [Splice](http://splice.com) chose to build
    their service with Go.
    Co-founder Matt Aimonetti said "We seriously studied and considered many
    programming languages,
    but Go's simplicity, efficiency, philosophy and community won us over."

  - And, of course, engineering teams across Google are moving to Go.
    Engineer Matt Welsh recently [shared his experience](http://matt-welsh.blogspot.com.au/2013/08/rewriting-large-production-system-in-go.html)
    rewriting a large production service in Go.
    Other notable public examples include YouTube's [vitess project](https://github.com/youtube/vitess)
    and [dl.google.com](/talks/2013/oscon-dl.slide).
    We hope to share more stories like these soon.

In September 2012, [Apcera](http://apcera.com/) CEO Derek Collison [predicted](https://twitter.com/derekcollison/status/245522124666716160)
that "Go will become the dominant language for systems work in [Infastructure-as-a-Service],
Orchestration, and [Platform-as-a-Service] in 24 months." Looking at the list above,
it's easy to believe that prediction.

So how can you get involved? Whether you're a seasoned Go programmer or just Go-curious,
there are many ways to get started in the Go community:

  - [Join your nearest Go User Group](/blog/getthee-to-go-meetup),
    where your local gophers meet to share their knowledge and experience.
    These groups are popping up all over the world.
    I have personally spoken at Go groups in Amsterdam,
    Berlin, Gothenburg, London, Moscow, Munich,
    New York City, Paris, San Francisco, Seoul,
    Stockholm, Sydney, Tokyo, and Warsaw;
    but there are [many more](/wiki/GoUserGroups)!

  - Create or contribute to an open source Go project (or [to Go itself](/doc/contribute.html)).
    (And if you're building something, we'd love to hear from you on the [Go mailing list](http://groups.google.com/group/golang-nuts).)

  - If you're in Europe in February 2014, come along to the [Go Devroom](https://code.google.com/p/go-wiki/wiki/Fosdem2014)
    at [FOSDEM 2014](https://fosdem.org/2014/).

  - Attend [GopherCon](http://gophercon.com),
    the first major Go conference, in Denver in April 2014.
    The event is organized by the [Gopher Academy](http://www.gopheracademy.com),
    who also run a [Go job board](http://www.gopheracademy.com/jobs).

The Go team has been amazed by the growth of the Go community over the past
four years. We are thrilled to see so many great things being built with Go,
and deeply grateful to work with our wonderful and dedicated contributors.
Thank you, everyone.

Here's to four more years!

---

## File: _content/blog/5years.md

---
title: Half a decade with Go
date: 2014-11-10
by:
- Andrew Gerrand
summary: Happy 5th birthday, Go!
template: true
---


Five years ago we launched the Go project. It seems like only yesterday that we
were preparing the initial public release: our
[website](https://web.archive.org/web/20091112094121/http://golang.org/) was
a lovely shade of yellow, we were calling Go a "systems language", and you had
to terminate statements with a semicolon and write Makefiles to build your
code. We had no idea how Go would be received. Would people share our vision
and goals? Would people find Go useful?

At launch, there was a flurry of attention. Google had produced a new
programming language, and everyone was eager to check it out. Some programmers
were turned off by Go's conservative feature set—at first glance they saw
"nothing to see here"—but a smaller group saw the beginnings of an ecosystem
tailored to their needs as working software engineers. These few would form the
kernel of the Go community.

{{image "5years/gophers5th.jpg" 850}}

[_Gopher_](/blog/gopher) _illustration by_ [_Renee French_](http://reneefrench.blogspot.com.au/)

After the initial release, it took us a while to properly communicate the
goals and design ethos behind Go. Rob Pike did so eloquently in his 2012 essay
[_Go at Google: Language Design in the Service of Software Engineering_](/talks/2012/splash.article) and
more personally in his blog post
[_Less is exponentially more_](https://commandcenter.blogspot.com.au/2012/06/less-is-exponentially-more.html).
Andrew Gerrand's
[_Code that grows with grace_](http://vimeo.com/53221560)
([slides](/talks/2012/chat.slide)) and
[_Go for Gophers_](https://www.youtube.com/watch?v=dKGmK_Z1Zl0)
([slides](/talks/2014/go4gophers.slide)) give a
more in-depth, technical take on Go's design philosophy.

Over time, the few became many. The turning point for the project was the
release of Go 1 in March 2012, which provided a stable language and standard
library that developers could trust. By 2014, the project had hundreds of core
contributors, the ecosystem had countless [libraries and tools](https://godoc.org/)
maintained by thousands of developers, and the greater community had
many passionate members (or, as we call them, "gophers"). Today, by our current
metrics, the Go community is growing faster than we believed possible.

Where can those gophers be found? They are at the many Go events that are
popping up around the world. This year we saw several dedicated Go conferences:
the inaugural [GopherCon](/blog/gophercon) and
[dotGo](http://www.dotgo.eu/) conferences in Denver and Paris, the
[Go DevRoom at FOSDEM](/blog/fosdem14) and two more
instances of the biannual [GoCon](https://github.com/GoCon/GoCon) conference
in Tokyo. At each event, gophers from around the globe eagerly presented their
Go projects. For the Go team, it is very satisfying to meet so many programmers
that share our vision and excitement.

{{image "5years/conferences.jpg"}}

_More than 1,200 gophers attended GopherCon in Denver and dotGo in Paris._

There are also dozens of community-run
[Go User Groups](/wiki/GoUserGroups) spread across cities
worldwide. If you haven't visited your local group, consider going along. And
if there isn't a group in your area, maybe you should
[start one](/blog/getthee-to-go-meetup)?

Today, Go has found a home in the cloud. Go arrived as the industry underwent a
tectonic shift toward cloud computing, and we were thrilled to see it quickly
become an important part of that movement. Its simplicity, efficiency, built-in
concurrency primitives, and modern standard library make it a great fit for
cloud software development (after all, that's what it was designed for).
Significant open source cloud projects like
[Docker](https://www.docker.com/) and
[Kubernetes](https://github.com/GoogleCloudPlatform/kubernetes) have been
written in Go, and infrastructure companies like Google, CloudFlare, Canonical,
Digital Ocean, GitHub, Heroku, and Microsoft are now using Go to do some heavy
lifting.

So, what does the future hold? We think that 2015 will be Go's biggest year yet.

Go 1.4—in addition to its [new features and fixes](/doc/go1.4)—lays
the groundwork for a new low-latency garbage collector and support for running
Go on mobile devices. It is due to be released on December 1st 2014.
We expect the new GC to be available in Go 1.5, due June 1st 2015, which will
make Go appealing for a broader range of applications.
We can't wait to see where people take it.

And there will be more great events, with [GothamGo](http://gothamgo.com/) in
New York (15 Nov), another Go DevRoom at FOSDEM in Brussels (Jan 31 and Feb 1;
[get involved!](https://groups.google.com/d/msg/golang-nuts/1xgBazQzs1I/hwrZ5ni8cTEJ)),
[GopherCon India](http://www.gophercon.in/) in Bengaluru (19-21 Feb),
the original [GopherCon](http://gophercon.com/) back at Denver in July, and
[dotGo](http://www.dotgo.eu/) on again at Paris in November.

The Go team would like to extend its thanks to all the gophers out there.
Here's to the next five years.

_To celebrate 5 years of Go, over the coming month the_
[_Gopher Academy_](http://blog.gopheracademy.com/)
_will publish a series of articles by prominent Go users. Be sure to check out_
[_their blog_](http://blog.gopheracademy.com/)
_for more Go action._

---

## File: _content/blog/6years.md

---
title: Six years of Go
date: 2015-11-10
by:
- Andrew Gerrand
summary: Happy 6th birthday, Go!
template: true
---


Six years ago today the Go language was released as an open source project.
Since then, more than 780 contributors have made over 30,000 commits to the
project's 22 repositories. The ecosystem continues to grow, with GitHub
reporting more than 90,000 Go repositories. And, offline, we see new Go events
and user groups pop up [around](/blog/gophercon2015)
[the](/blog/gouk15)
[world](/blog/gopherchina) with regularity.

{{image "6years/6years-gopher.png"}}

In August we [released Go 1.5](/blog/go1.5), the most
significant release since Go 1. It features a completely
[redesigned garbage collector](/doc/go1.5#gc) that makes
the language more suitable for latency-sensitive applications; it marks the
transition from a C-based compiler tool chain to one
[written entirely in Go](/doc/go1.5#c); and it includes
ports to [new architectures](/doc/go1.5#ports), with better
support for ARM processors (the chips that power most smartphones).
These improvements make Go better suited to a broader range of tasks, a trend
that we hope will continue over the coming years.

Improvements to tools continue to boost developer productivity.
We introduced the [execution tracer](/cmd/trace/) and the
"[go doc](/cmd/go/#hdr-Show_documentation_for_package_or_symbol)"
command, as well as more enhancements to our various
[static analysis tools](/talks/2014/static-analysis.slide).
We are also working on an
[official Go plugin for Sublime Text](https://groups.google.com/forum/#!topic/Golang-nuts/8oCSjAiKXUQ),
with better support for other editors in the pipeline.

Early next year we will release more improvements in Go 1.6, including
HTTP/2 support for [net/http](/pkg/net/http/) servers and
clients, an official package vendoring mechanism, support for blocks in text
and HTML templates, a memory sanitizer that checks both Go and C/C++ code, and
the usual assortment of other improvements and fixes.

This is the sixth time we have had the pleasure of writing a birthday blog post
for Go, and we would not be doing so if not for the wonderful and passionate
people in our community. The Go team would like to thank everyone who has
contributed code, written an open source library, authored a blog post, helped
a new gopher, or just given Go a try. Without you, Go would not be as complete,
useful, or successful as it is today. Thank you, and celebrate!

---

## File: _content/blog/7years.md

---
title: Seven years of Go
date: 2016-11-10
by:
- The Go Team
summary: Happy 7th birthday, Go!
---




Today marks seven years since we open-sourced our preliminary sketch of Go.
With the help of the open source community, including more than a thousand
individual contributors to the Go source repositories,
Go has matured into a language used all over the world.

The most significant user-facing changes to Go over the past year are the
addition of built-in support for
[HTTP/2](https://www.youtube.com/watch?v=FARQMJndUn0#t=0m0s) in
[Go 1.6](/doc/go1.6) and the integration of the
[context package](/blog/context) into the standard library in [Go 1.7](/doc/go1.7).
But we’ve been making many less visible improvements.
Go 1.7 changed the x86-64 compiler to use a new SSA-based back end,
improving the performance of most Go programs by 10–20%.
For Go 1.8, planned for release next February,
we have changed the compilers for the other architectures to use the new back end too.
We’ve also added new ports, to Android on 32-bit x86, Linux on 64-bit MIPS,
and Linux on IBM z Systems.
And we’ve developed new garbage-collection techniques that reduce typical
“stop the world” pauses to [under 100 microseconds](/design/17503-eliminate-rescan).
(Contrast that with Go 1.5’s big news of [10 milliseconds or less](/blog/go15gc).)

This year kicked off with a global Go hackathon,
the [Gopher Gala](/blog/gophergala), in January.
Then there were [Go conferences](/wiki/Conferences) in India and Dubai in February,
China and Japan in April, San Francisco in May, Denver in July,
London in August, Paris last month, and Brazil this past weekend.
And GothamGo in New York is next week.
This year also saw more than 30 new [Go user groups](/wiki/GoUserGroups),
eight new [Women Who Go](http://www.womenwhogo.org/) chapters,
and four [GoBridge](https://golangbridge.org/) workshops around the world.

We continue to be overwhelmed by and grateful for
the enthusiasm and support of the Go community.
Whether you participate by contributing changes, reporting bugs,
sharing your expertise in design discussions, writing blog posts or books,
running meetups, helping others learn or improve,
open sourcing Go packages you wrote, or just being part of the Go community,
the Go team thanks you for your help, your time, and your energy.
Go would not be the success it is today without you.

Thank you, and here’s to another year of fun and success with Go!

---

## File: _content/blog/8years.md

---
title: Eight years of Go
date: 2017-11-10
by:
- Steve Francia
tags:
- community
- birthday
summary: Happy 8th birthday, Go!
template: true
---


Today we celebrate 8 years since Go was released as an open source project.
During [Go’s 4th anniversary](/blog/4years), Andrew
finished the post with “Here's to four more years!”. Now that we have reached
that milestone, I cannot help but reflect on how much the project and
ecosystem has grown since then. In our post 4 years ago we included a chart
demonstrating Go's rising popularity on Google Trends with the search term
"golang". Today, we’re including an updated chart. In this relative scale of
popularity, what was 100 four years ago is now a mere 17. Go’s popularity has
increased exponentially over the last 8 years and continues to grow.

{{image "8years/image1.png"}}

Source: [trends.google.com](https://trends.google.com/trends/explore?date=2009-10-01%202017-10-30&q=golang&hl=en-US)

## Developers love Go

Go has been embraced by developers all over the world with approximately one
million users worldwide. In the [freshly published 2017 Octoverse](https://octoverse.github.com/)
by GitHub, **Go has become the #9 most popular language**, surpassing C.
**Go is the fastest growing language on GitHub in 2017** in the top 10 with
**52% growth over the previous year**. In growth, Go swapped places with
JavaScript, which fell to the second spot with 44%.

{{image "8years/image2.png"}}

Source: [octoverse.github.com](https://octoverse.github.com/)

In [Stack Overflow's 2017 developer survey](https://insights.stackoverflow.com/survey/2017#most-loved-dreaded-and-wanted)
, Go was the only language that was both on the **top 5 most loved and top 5 most wanted** languages.
People who use Go, love it, and the people who aren’t using Go, want to be.

{{image "8years/image3.png"}}
{{image "8years/image4.png"}}

Source: [insights.stackoverflow.com/survey/2017](https://insights.stackoverflow.com/survey/2017#most-loved-dreaded-and-wanted)

## Go: The language of Cloud Infrastructure

In 2014, analyst Donnie Berkholz called Go
[the emerging language of cloud infrastructure](http://redmonk.com/dberkholz/2014/03/18/go-the-emerging-language-of-cloud-infrastructure/).
**By 2017, Go has emerged as the language of cloud infrastructure**.
Today, **every single cloud company has critical components of their cloud infrastructure implemented in Go**
including Google Cloud, AWS, Microsoft Azure, Digital Ocean, Heroku and many others. Go
is a key part of cloud companies like Alibaba, Cloudflare, and Dropbox. Go is
a critical part of open infrastructure including Kubernetes, Cloud Foundry,
Openshift, NATS, Docker, Istio, Etcd, Consul, Juju and many more. Companies
are increasingly choosing Go to build cloud infrastructure solutions.

## Go’s Great Community

It may be hard to imagine that only four years ago the Go community was
transitioning from online-only to include in-person community with its first
conference. Now the Go community has had over 30 conferences all around the
world with hundreds of presentations and tens of thousands of attendees.
There are hundreds of Go meetups meeting monthly covering much of the globe.
Wherever you live, you are likely to find a Go meetup nearby.

Two different organizations have been established to help with inclusivity in
the Go community, Go Bridge and Women Who Go; the latter has grown to over 25
chapters. Both have been instrumental in offering free trainings. In 2017
alone over 50 scholarships to conferences have been given through efforts of
Go Bridge and Women Who Go.

This year we had two significant firsts for the Go project. We had our first
[contributor summit](/blog/contributors-summit) where
people from across the Go community came together to
discuss the needs and future of the Go project. Shortly after, we had the
first [Go contributor workshop](/blog/contributor-workshop)
where hundreds of people came to make their first Go contribution.

{{image "8years/photo.jpg"}}

Photo by Sameer Ajmani

## Go’s impact on open source

Go has become a major force in the world of open source powering some of the
most popular projects and enabling innovations across many industries. Find
thousands of additional applications and libraries at [awesome-go](https://github.com/avelino/awesome-go). Here are
just a handful of the most popular:

  - [Moby](https://mobyproject.org/) (formerly Docker) is a tool for packaging
    and running applications in lightweight containers.
    Its creator Solomon Hykes cited Go's standard library,
    concurrency primitives, and ease of deployment as key factors,
    and said "To put it simply, if Docker had not been written in Go,
    it would not have been as successful."

  - [Kubernetes](https://kubernetes.io/) is a system for automating deployment,
    scaling and management of containerized applications.
    Initially designed by Google and used in the Google cloud,
    Kubernetes now is a critical part of every major cloud offering.

  - [Hugo](https://gohugo.io/) is now the most popular open-source static website engine.
    With its amazing speed and flexibility, Hugo makes building websites fun again.
    According to [w3techs](https://w3techs.com/technologies/overview/content_management/all),
    Hugo now has nearly 3x the usage of Jekyll, the former leader.

  - [Prometheus](https://prometheus.io/) is an open source monitoring solution
    and time series database that powers metrics and alerting designed to be
    the system you go to during an outage to allow you to quickly diagnose problems.

  - [Grafana](https://grafana.com/) is an open source,
    feature-rich metrics dashboard and graph editor for Graphite,
    Elasticsearch, OpenTSDB, Prometheus and InfluxDB.

  - [Lantern](https://getlantern.org/) delivers fast, reliable and secure access to blocked websites and apps.

  - [Syncthing](https://syncthing.net/) is an open-source cross platform
    peer-to-peer continuous file synchronization application

  - [Keybase](https://keybase.io/) is a new and free security app for mobile
    phones and computers.
    Think of it as an open source Dropbox & Slack with end-to-end encryption
    public-key cryptography.

  - [Fzf](https://github.com/junegunn/fzf) is an interactive Unix filter
    for command-line that can be used with any list;
    files, command history, processes, hostnames,
    bookmarks, git commits, etc.
    Fzf supports Unix, macOS and has beta support for Windows.
    It also can operate as a vim plugin.

Many of these authors have said that their projects would not exist without
Go. Some like Kubernetes and Docker created entirely new solutions. Others
like Hugo, Syncthing and Fzf created more refined experiences where many
solutions already existed. The popularity of these applications alone is
proof that Go is an ideal language for a broad set of use cases.

## Thank You

This is the eighth time we have had the pleasure of writing a birthday blog
post for Go and we continue to be overwhelmed by and grateful for the
enthusiasm and support of the Go community.

Since Go was first open sourced we have had 10 releases of the language,
libraries and tooling with more than 1680 contributors making over 50,000
commits to the project's 34 repositories; More than double the number of
contributors and nearly double the number of commits from only [two years ago](/blog/6years).
This year we announced that we have begun planning [Go 2](/blog/toward-go2), our first major
revision of the language and tooling.

The Go team would like to thank everyone who has contributed to the project,
whether you participate by contributing changes, reporting bugs, sharing your
expertise in design discussions, writing blog posts or books, running events,
attending or speaking at events, helping others learn or improve, open
sourcing Go packages you wrote, contributing artwork, introducing Go to
someone, or being part of the Go community. Without you, Go would not be as
complete, useful, or successful as it is today.

Thank you, and here’s to eight more years!

---

## File: _content/blog/9years.md

---
title: Nine years of Go
date: 2018-11-10
by:
- Steve Francia
tags:
- community
- birthday
summary: Happy 9th birthday, Go!
template: true
---

## Introduction

Today marks the ninth anniversary of the day we open-sourced our initial sketch of Go.
On each anniversary we like to take time to reflect on what has happened over the past year.
The past 12 months have been a breakout year for the Go language and community.

## Go Love & Adoption

Thanks to all of you, 2018 was an amazing year for Go!
In multiple industry surveys Gophers expressed how happy they were using Go,
and many non-Go developers indicated they intended to learn Go before any other language.

In [Stack Overflow’s 2018 Developer Survey](https://insights.stackoverflow.com/survey/2018#most-loved-dreaded-and-wanted),
Go retained its coveted spot in both the top 5 most loved and top 5 most wanted languages.
People who use Go love it, and people who aren’t using Go want to.

In [ActiveState’s 2018 Developer Survey](https://www.activestate.com/developer-survey-2018-open-source-runtime-pains),
Go topped the charts with 36% of users responding they were “Extremely Satisfied” using Go
and 61% responding “Very Satisfied” or better.

[JetBrains’s 2018 Developer Survey](https://www.jetbrains.com/research/devecosystem-2018/) awarded Go
the “Most promising language” with 12% of respondents using Go today and 16% intending to use Go in the future.

In [HackerRank’s 2018 Developer Survey](https://research.hackerrank.com/developer-skills/2018/),
38% of developers responded that they were intending to learn Go next.

We are excited about all of our new gophers and actively working to improve our educational and community resources.

## Go Community

It’s hard to believe that it’s only been five years since
the first Go conferences and Go meetups.
We’ve seen major growth in this area of community leadership over the last year.
There are now over 20 [Go conferences](/wiki/Conferences)
and over 300 [Go-related meetups](https://www.meetup.com/topics/golang/) spanning the globe.

Thanks to the hard work put into these many conferences and meetups,
there have been hundreds of great talks this year.
Here are a few of our favorite talks specifically discussing the growth of our community
and how we can better support gophers worldwide.

  - [Writing Accessible Go](https://www.youtube.com/watch?v=cVaDY0ChvOQ), by Julia Ferraioli at GopherCon
  - [The Importance of Beginners](https://www.youtube.com/watch?v=7yMXs9TRvVI), by Natalie Pistunovich at GopherCon
  - [The Legacy of Go, Part 2](https://www.youtube.com/watch?v=I_KcpgxcFyU), by Carmen Andoh at GothamGo
  - [Growing a Community of Gophers](https://www.youtube.com/watch?v=dl1mCGKwlYY), by Cassandra Salisbury at Gopherpalooza

On that theme, this year we also [revised our code of conduct](/blog/conduct-2018)
to better support inclusivity in the Go community.

The Go community is truly global.
At GopherCon Europe in Iceland this past summer, gophers literally spanned the gap between the continents.

{{image "9years/9years-iceland.jpg" 800}}

_(Photo by Winter Francia.)_

## Go 2

After five years of experience with Go 1, we’ve started looking at
what we should change about Go to better support
[programming at scale](/talks/2012/splash.article).

Last spring, we published a [draft design for Go modules](/blog/versioning-proposal),
which provide an integrated mechanism for versioning and package distribution.
The most recent Go release, Go 1.11, included
[preliminary support for modules](/doc/go1.11#modules).

Last summer we published
[early draft designs](/blog/go2draft)
for how Go 2 might better support error values, error handling, and generic programming.

We are excited about refining these designs with the community’s help as we work
[toward Go 2](/blog/toward-go2).

## Go Contributors

The Go project has been increasing in the number of contributions from the community for several years.
The project hit a major milestone in mid-2018 when, for the first time,
we had more contributions coming from the community than the Go team.

{{image "9years/9years-graph.png" 600}}

## Thank You

On a personal note, from the entire Go team,
we want to sincerely thank all of you.
We feel privileged to be able to work on the Go project
and are grateful to the many gophers around the world who have joined us.

We are especially thankful for the thousands of volunteers
who help through mentorship, organizing, contributing,
and supporting your fellow gophers.
You have made Go what it is today.

---

## File: _content/blog/a-conversation-with-the-go-team.md

---
redirect: /blog/io2013-chat
---

---

## File: _content/blog/a-new-go-api-for-protocol-buffers.md

---
redirect: /blog/protobuf-apiv2
---

---

## File: _content/blog/advanced-go-concurrency-patterns.md

---
redirect: /blog/io2013-talk-concurrency
---

---

## File: _content/blog/alias-names.md

---
title: What's in an (Alias) Name?
date: 2024-09-17
by:
- Robert Griesemer
tags:
- type aliases
- type parameters
- generics
summary: A description of generic alias types, a planned feature for Go 1.24
---

This post is about generic alias types, what they are, and why we need them.


## Background

Go was designed for programming at scale.
Programming at scale means dealing with large amounts of data, but
also large codebases, with many engineers working on those codebases
over long periods of time.

Go's organization of code into packages enables programming at scale
by splitting up large codebases into smaller, more manageable pieces,
often written by different people, and connected through public
APIs.
In Go, these APIs consist of the identifiers exported by a package:
the exported constants, types, variables, and functions.
This includes the exported fields of structs and methods of types.

As software projects evolve over time or requirements change,
the original organization of the code into packages may turn out to be
inadequate and require _refactoring_.
Refactoring may involve moving exported identifiers and their respective
declarations from an old package to a new package.
This also requires that any references to the moved declarations must be
updated so that they refer to the new location.
In large codebases it may be unpractical or infeasible to make such
a change atomically; or in other words, to do the move and update all clients
in a single change.
Instead, the change must happen incrementally: for instance, to "move"
a function `F`, we add its declaration in a new package without
deleting the original declaration in the old package.
This way, clients can be updated incrementally, over time.
Once all callers refer to `F` in the new package, the original declaration
of `F` may be safely deleted (unless it must be retained indefinitely, for
backward compatibility).
Russ Cox describes refactoring in detail in his 2016 article on
[Codebase Refactoring (with help from Go)](/talks/2016/refactor.article).

Moving a function `F` from one package to another while also retaining it
in the original package is easy: a wrapper function is all that's needed.
To move `F` from `pkg1` to `pkg2`, `pkg2` declares a new function `F`
(the wrapper function) with the same signature as `pkg1.F`, and `pkg2.F`
calls `pkg1.F`.
New callers may call `pkg2.F`, old callers may call `pkg1.F`, yet in both
cases the function eventually called is the same.

Moving constants is similarly straightforward.
Variables take a bit more work: one may have to introduce a pointer to the
original variable in the new package or perhaps use accessor functions.
This is less ideal, but at least it is workable.
The point here is that for constants, variables, and functions,
existing language features exist that permit incremental refactoring as
described above.

But what about moving a type?

In Go, the [(qualified) identifier](/ref/spec#Qualified_identifiers),
or just _name_ for short, determines the _identity_ of types:
a type `T` [defined](/ref/spec#Type_definitions) and exported by a package
`pkg1` is [different](/ref/spec#Type_identity) from an _otherwise identical_
type definition of a type `T` exported by a package `pkg2`.
This property complicates a move of `T` from one package to another while
retaining a copy of it in the original package.
For instance, a value of type `pkg2.T` is not [assignable](/ref/spec#Assignability)
to a variable of type `pkg1.T` because their type names and thus their
type identities are different.
During an incremental update phase, clients may have values and variables
of both types, even though the programmer's intent is for them to have the
same type.

To solve this problem, [Go 1.9](/doc/go1.9) introduced the notion of a
[_type alias_](/ref/spec#Alias_declarations).
A type alias provides a new name for an existing type without introducing
a new type that has a different identity.

In contrast to a regular [type definition](/ref/spec#Type_definitions)

```go
type T T0
```

which declares a _new type_ that is never identical to the type on the right-hand side
of the declaration, an [alias declaration](/ref/spec#Alias_declarations)

```go
type A = T  // the "=" indicates an alias declaration
```
declares only a _new name_ `A` for the type on the right-hand side:
here, `A` and `T` denote the same and thus identical type `T`.

Alias declarations make it possible to provide a new name (in a new package!)
for a given type while retaining type identity:

```go
package pkg2

import "path/to/pkg1"

type T = pkg1.T
```

The type name has changed from `pkg1.T` to `pkg2.T` but values
of type `pkg2.T` have the same type as variables of type `pkg1.T`.


## Generic alias types

[Go 1.18](/doc/go1.18) introduced generics.
Since that release, type definitions and function
declarations can be customized through type parameters.
For technical reasons, alias types didn't gain the same ability at that time.
Obviously, there were also no large codebases exporting generic
types and requiring refactoring.

Today, generics have been around for a couple of years, and large codebases
are making use of generic features.
Eventually the need will arise to refactor these codebases, and with that the
need to migrate generic types from one package to another.

To support incremental refactorings involving generic types, the future Go 1.24 release,
planned for early February 2025, will fully support type parameters on alias types
in accordance with proposal [#46477](/issue/46477).
The new syntax follows the same pattern as it does for type definitions and function declarations,
with an optional type parameter list following the identifier (the alias name) on the left-hand side.
Before this change one could only write:

```go
type Alias = someType
```

but now we can also declare type parameters with the alias declaration:

```go
type Alias[P1 C1, P2 C2] = someType
```

Consider the previous example, now with generic types.
The original package `pkg1` declared and exported a generic type `G` with a type parameter `P`
that is suitably constrained:

```go
package pkg1

type Constraint      someConstraint
type G[P Constraint] someType
```

If the need arises to provide access to the same type `G` from a new package `pkg2`,
a generic alias type is just the ticket [(playground)](/play/p/wKOf6NbVtdw?v=gotip):

```go
package pkg2

import "path/to/pkg1"

type Constraint      = pkg1.Constraint  // pkg1.Constraint could also be used directly in G
type G[P Constraint] = pkg1.G[P]
```

Note that one **cannot** simply write

```go
type G = pkg1.G
```

for a couple of reasons:

1) Per [existing spec rules](/ref/spec#Type_definitions), generic
types must be [instantiated](/ref/spec#Instantiations) when they
are _used_.
The right-hand side of the alias declaration uses the type `pkg1.G` and
therefore type arguments must be provided.
Not doing so would require an exception for this case, making the spec more
complicated.
It is not obvious that the minor convenience is worth the complication.

2) If the alias declaration doesn't need to declare its own type parameters and
instead simply "inherits" them from the aliased type `pkg1.G`, the declaration of
`G` provides no indication that it is a generic type.
Its type parameters and constraints would have to be retrieved from the declaration
of `pkg1.G` (which itself might be an alias).
Readability will suffer, yet readable code is one of the primary aims of the Go project.

Writing down an explicit type parameter list may seem like an unnecessary burden
at first, but it also provides additional flexibility.
For one, the number of type parameters declared by the alias type doesn't have to
match the number of type parameters of the aliased type.
Consider a generic map type:

```go
type Map[K comparable, V any] mapImplementation
```

If uses of `Map` as sets are common, the alias

```go
type Set[K comparable] = Map[K, bool]
```

might be useful [(playground)](/play/p/IxeUPGCztqf?v=gotip).
Because it is an alias, types such as `Set[int]` and `Map[int, bool]` are
identical.
This would not be the case if `Set` were a [defined](/ref/spec#Type_definitions)
(non-alias) type.

Furthermore, the type constraints of a generic alias type don't have to match the
constraints of the aliased type, they only have to
[satisfy](/ref/spec#Satisfying_a_type_constraint) them.
For instance, reusing the set example above, one could define
an `IntSet` as follows:

```go
type integers interface{ ~int | ~int8 | ~int16 | ~int32 | ~int64 }
type IntSet[K integers] = Set[K]
```

This map can be instantiated with any key type that satisfies the `integers`
constraint [(playground)](/play/p/0f7hOAALaFb?v=gotip).
Because `integers` satisfies `comparable`, the type parameter `K` may be used
as type argument for the `K` parameter of `Set`, following the usual
instantiation rules.

Finally, because an alias may also denote a type literal, parameterized aliases
make it possible to create generic type literals
[(playground)](/play/p/wql3NJaUs0o?v=gotip):

```go
type Point3D[E any] = struct{ x, y, z E }
```

To be clear, none of these examples are "special cases" or somehow require
additional rules in the spec. They follow directly from the application of
the existing rules put in place for generics. The only thing that changed in the
spec is the ability to declare type parameters in an alias declaration.


## An interlude about type names

Before the introduction of alias types, Go had only one form of type declarations:

```go
type TypeName existingType
```

This declaration creates a new and different type from an existing type
and gives that new type a name.
It was natural to call such types _named types_ as they have a _type name_
in contrast to unnamed [type literals](/ref/spec#Types) such as
`struct{ x, y int }`.

With the introduction of alias types in Go 1.9 it became possible to give
a name (an alias) to type literals, too. For instance, consider:

```go
type Point2D = struct{ x, y int }
```

Suddenly, the notion of a _named type_ describing something that is different from
a type literal didn't make that much sense anymore, since an alias name clearly is
a name for a type, and thus the denoted type (which might be a type literal, not a type name!)
arguably could be called a "named type".

Because (proper) named types have special properties (one can bind methods to them,
they follow different assignment rules, etc.), it seemed prudent to use a new
term in order to avoid confusions.
Thus, since Go 1.9, the spec calls the types formerly called named types _defined types_:
only defined types have properties (methods, assignability restrictions, etc) that are
tied to their names.
Defined types are introduced through type definitions, and alias types are
introduced through alias declarations.
In both cases, names are given to types.

The introduction of generics in Go 1.18 made things more complicated.
Type parameters are types, too, they have a name, and they share rules
with defined types.
For instance, like defined types, two differently named type parameters
denote different types.
In other words, type parameters are named types, and furthermore, they
behave similarly to Go's original named types in some ways.

To top things off, Go's predeclared types (`int`, `string` and so on)
can only be accessed through their names, and like defined types and
type parameters, are different if their names are different
(ignoring for a moment the `byte` and `rune` alias types).
The predeclared types truly are named types.

Therefore, with Go 1.18, the spec came full circle and formally
re-introduced the notion of a [named type](/ref/spec#Types) which now
comprises "predeclared types, defined types, and type parameters".
To correct for alias types denoting type literals the spec says:
"An alias denotes a named type if the type given in the alias declaration
is a named type."

Stepping back and outside the box of Go nomenclature for a moment, the correct
technical term for a named type in Go is probably
[_nominal type_](https://en.wikipedia.org/wiki/Nominal_type_system).
A nominal type's identity is explicitly tied to its name which is exactly what
Go's named types (now using the 1.18 terminology) are all about.
A nominal type's behavior is in contrast to a _structural type_ which has
behavior that only depends on its structure and not its name
(if it has one in the first place).
Putting it all together, Go's predeclared, defined, and type parameter types are
all nominal types, while Go's type literals and aliases denoting type literals
are structural types.
Both nominal and structural types can have names, but having a name
doesn't mean the type is nominal, it just means it is named.

None of this matters for day-to-day use of Go and in practice the details
can safely be ignored.
But precise terminology matters in the spec because it makes it easier
to describe the rules governing the language.
So should the spec change its terminology one more time?
It is probably not worth the churn: it is not just the spec that would need
to be updated, but also a lot of supporting documentation.
A fair number of books written on Go might become inaccurate.
Furthermore, "named", while less precise, is probably intuitively clearer
than "nominal" for most people.
It also matches the original terminology used in the spec, even if it now
requires an exception for alias types denoting type literals.


## Availability

Implementing generic type aliases has taken longer than expected:
the necessary changes required adding a new exported `Alias` type
to [`go/types`](/pkg/go/types) and then adding the ability to record type parameters
with that type.
On the compiler side, the analogous changes also required modifications to
the export data format, the file format that describes a package's
exports, which now needs to be able to describe type parameters for aliases.
The impact of these changes is not confined to the compiler, but affects
clients of `go/types` and thus many third-party packages.
This was very much a change affecting a large code base; to avoid
breaking things, an incremental roll-out over several releases was necessary.

After all this work, generic alias types will finally be available by default in Go 1.24.

To allow third-party clients to get their code ready, starting with
Go 1.23, support for generic type aliases can be enabled by setting
`GOEXPERIMENT=aliastypeparams` when invoking the `go` tool.
However, be aware that support for exported generic aliases is still
missing for that version.

Full support (including export) is implemented at tip, and the default
setting for `GOEXPERIMENT` will soon be switched so that generic type
aliases are enabled by default.
Thus, another option is to experiment with the latest version of Go
at tip.

As always, please let us know if you encounter any problems by filing an
[issue](/issue/new);
the better we test a new feature, the smoother the general roll-out.

Thanks and happy refactoring!

---

## File: _content/blog/all.md

---
title: Blog Index
template: true
---



{{range newest (pages "/blog/*.md") -}}
{{if .date}}

  [{{.title}}]({{.URL}}), {{.date.Format "2 January 2006"}}
  {{with .by}}{{by .}}{{end}}
  {{with .Tags}}{{range .}}{{.}} {{end}}{{end}}


  {{.summary}}

{{end}}
{{end}}

---

## File: _content/blog/allocation-optimizations.md

---
title: Allocating on the Stack
date: 2026-02-27
by:
- Keith Randall
summary: A description of some of the recent changes to do allocations on the stack instead of the heap.
template: true
---

We're always looking for ways to make Go programs faster. In the last
2 releases, we have concentrated on mitigating a particular source of
slowness, heap allocations. Each time a Go program allocates memory
from the heap, there's a fairly large chunk of code that needs to run
to satisfy that allocation. In addition, heap allocations present
additional load on the garbage collector.  Even with recent
enhancements like [Green Tea](/blog/greenteagc), the garbage collector
still incurs substantial overhead.

So we've been working on ways to do more allocations on the stack
instead of the heap.  Stack allocations are considerably cheaper to
perform (sometimes completely free).  Moreover, they present no load
to the garbage collector, as stack allocations can be collected
automatically together with the stack frame itself. Stack allocations
also enable prompt reuse, which is very cache friendly.

## Stack allocation of constant-sized slices

Consider the task of building a slice of tasks to process:
{{raw `
~~~go
func process(c chan task) {
	var tasks []task
	for t := range c {
		tasks = append(tasks, t)
	}
	processAll(tasks)
}
~~~
`}}

Let's walk through what happens at runtime when pulling tasks from the
channel `c` and adding them to the slice `tasks`.

On the first loop iteration, there is no backing store for `tasks`, so
`append` has to allocate one. Because it doesn't know how big the
slice will eventually be, it can't be too aggressive. Currently, it
allocates a backing store of size 1.

On the second loop iteration, the backing store now exists, but it is
full. `append` again has to allocate a new backing store, this time of
size 2. The old backing store of size 1 is now garbage.

On the third loop iteration, the backing store of size 2 is
full. `append` *again* has to allocate a new backing store, this time
of size 4. The old backing store of size 2 is now garbage.

On the fourth loop iteration, the backing store of size 4 has only 3
items in it. `append` can just place the item in the existing backing
store and bump up the slice length. Yay! No call to the allocator for
this iteration.

On the fifth loop iteration, the backing store of size 4 is full, and
`append` again has to allocate a new backing store, this time of size
8.

And so on. We generally double the size of the allocation each time it
fills up, so we can eventually append most new tasks to the slice
without allocation. But there is a fair amount of overhead in the
"startup" phase when the slice is small. During this startup phase we
spend a lot of time in the allocator, and produce a bunch of garbage,
which seems pretty wasteful. And it may be that in your program, the
slice never really gets large. This startup phase may be all you ever
encounter.

If this code was a really hot part of your program, you might be
tempted to start the slice out at a larger size, to avoid all of these
allocations.

{{raw `
~~~go
func process2(c chan task) {
	tasks := make([]task, 0, 10) // probably at most 10 tasks
	for t := range c {
		tasks = append(tasks, t)
	}
	processAll(tasks)
}
~~~
`}}

This is a reasonable optimization to do. It is never incorrect; your
program still runs correctly. If the guess is too small, you get
allocations from `append` as before. If the guess is too large, you
waste some memory.

If your guess for the number of tasks was a good one, then there's
only one allocation site in this program. The `make` call allocates a
slice backing store of the correct size, and `append` never has to do
any reallocation.

The surprising thing is that if you benchmark this code with 10
elements in the channel, you'll see that you didn't reduce the number
of allocations to 1, you reduced the number of allocations to 0!

The reason is that the compiler decided to allocate the backing store
on the stack. Because it knows what size it needs to be (10 times the
size of a task) it can allocate storage for it in the stack frame of
`process2` instead of on the heap[<sup>1</sup>](#footnotes).  Note
that this depends on the fact that the backing store does not [escape
to the heap](/doc/gc-guide#Escape_analysis) inside of `processAll`.

## Stack allocation of variable-sized slices

But of course, hard coding a size guess is a bit rigid.
Maybe we can pass in an estimated length?

{{raw `
~~~go
func process3(c chan task, lengthGuess int) {
	tasks := make([]task, 0, lengthGuess)
	for t := range c {
		tasks = append(tasks, t)
	}
	processAll(tasks)
}
~~~
`}}

This lets the caller pick a good size for the `tasks` slice, which may
vary depending on where this code is being called from.

Unfortunately, in Go 1.24 the non-constant size of the backing store
means the compiler can no longer allocate the backing store on the
stack.  It will end up on the heap, converting our 0-allocation code
to 1-allocation code. Still better than having `append` do all the
intermediate allocations, but unfortunate.

But never fear, Go 1.25 is here!

Imagine you decide to do the following, to get the stack allocation
only in cases where the guess is small:

{{raw `
~~~go
func process4(c chan task, lengthGuess int) {
	var tasks []task
	if lengthGuess <= 10 {
		tasks = make([]task, 0, 10)
	} else {
		tasks = make([]task, 0, lengthGuess)
	}
	for t := range c {
		tasks = append(tasks, t)
	}
	processAll(tasks)
}
~~~
`}}

Kind of ugly, but it would work. When the guess is small, you use a
constant size `make` and thus a stack-allocated backing store, and
when the guess is larger you use a variable size `make` and allocate
the backing store from the heap.

But in Go 1.25, you don't need to head down this ugly road. The Go
1.25 compiler does this transformation for you!  For certain slice
allocation locations, the compiler automatically allocates a small
(currently 32-byte) slice backing store, and uses that backing store
for the result of the `make` if the size requested is small
enough. Otherwise, it uses a heap allocation as normal.

In Go 1.25, `process3` performs zero heap allocations, if
`lengthGuess` is small enough that a slice of that length fits into 32
bytes. (And of course that `lengthGuess` is a correct guess for how
many items are in `c`.)

We're always improving the performance of Go, so upgrade to the latest
Go release and [be
surprised](https://youtu.be/FUm0pfgWehI?si=QRTt_JYwr-cRHDNJ&t=960) by
how much faster and memory efficient your program becomes!

## Stack allocation of append-allocated slices

Ok, but you still don't want to have to change your API to add this
weird length guess. Anything else you could do?

Upgrade to Go 1.26!

{{raw `
~~~go
func process(c chan task) {
	var tasks []task
	for t := range c {
		tasks = append(tasks, t)
	}
	processAll(tasks)
}
~~~
`}}

In Go 1.26, we allocate the same kind of small, speculative backing
store on the stack, but now we can use it directly at the `append`
site.

On the first loop iteration, there is no backing store for `tasks`, so
`append` uses a small, stack-allocated backing store as the first
allocation. If, for instance, we can fit 4 `task`s in that backing store,
the first `append` allocates a backing store of length 4 from the stack.

The next 3 loop iterations append directly to the stack backing store,
requiring no allocation.

On the 4th iteration, the stack backing store is finally full and we
have to go to the heap for more backing store. But we have avoided
almost all of the startup overhead described earlier in this article.
No heap allocations of size, 1, 2, and 4, and none of the garbage that
they eventually become. If your slices are small, maybe you will never
have a heap allocation.

## Stack allocation of append-allocated escaping slices

Ok, this is all good when the `tasks` slice doesn't escape. But what if
I'm returning the slice? Then it can't be allocated on the stack, right?

Right! The backing store for the slice returned by `extract` below
can't be allocated on the stack, because the stack frame for `extract`
disappears when `extract` returns.

{{raw `
~~~go
func extract(c chan task) []task {
	var tasks []task
	for t := range c {
		tasks = append(tasks, t)
	}
	return tasks
}
~~~
`}}

But you might think, the *returned* slice can't be allocated on the
stack. But what about all those intermediate slices that just become
garbage? Maybe we can allocate those on the stack?

{{raw `
~~~go
func extract2(c chan task) []task {
	var tasks []task
	for t := range c {
		tasks = append(tasks, t)
	}
	tasks2 := make([]task, len(tasks))
	copy(tasks2, tasks)
	return tasks2
}
~~~
`}}

Then the `tasks` slice never escapes `extract2`. It can benefit from
all of the optimizations described above. Then at the very end of
`extract2`, when we know the final size of the slice, we do one heap
allocation of the required size, copy our `task`s into it, and return
the copy.

But do you really want to write all that additional code? It seems
error prone. Maybe the compiler can do this transformation for us?

In Go 1.26, it can!

For escaping slices, the compiler will transform the original `extract`
code to something like this:

{{raw `
~~~go
func extract3(c chan task) []task {
	var tasks []task
	for t := range c {
		tasks = append(tasks, t)
	}
	tasks = runtime.move2heap(tasks)
	return tasks
}
~~~
`}}

`runtime.move2heap` is a special compiler+runtime function that is the
identity function for slices that are already allocated in the heap.
For slices that are on the stack, it allocates a new slice on the
heap, copies the stack-allocated slice to the heap copy, and returns
the heap copy.

This ensures that for our original `extract` code, if the number of
items fits in our small stack-allocated buffer, we perform exactly 1
allocation of exactly the right size. If the number of items exceeds
the capacity of our small stack-allocated buffer, we do our normal
doubling-allocation once the stack-allocated buffer overflows.

The optimization that Go 1.26 does is actually better than the
hand-optimized code, because it does not require the extra
allocation+copy that the hand-optimized code always does at the end.
It requires the allocation+copy only in the case that we've exclusively
operated on a stack-backed slice up to the return point.

We do pay the cost for a copy, but that cost is almost completely
offset by the copies in the startup phase that we no longer have to
do. (In fact, the new scheme at worst has to copy one more element
than the old scheme.)

## Wrapping up

Hand optimization can still be beneficial, especially if you have a
good estimate of the slice size ahead of time. But hopefully the
compiler will now catch a lot of the simple cases for you and allow
you to focus on the remaining ones that really matter.

There are a lot of details that the compiler needs to ensure to get
all these optimizations right. If you think that one of these
optimizations is causing correctness or (negative) performance issues
for you, you can turn them off with
`-gcflags=all=-d=variablemakehash=n`. If turning these optimizations
off helps, please [file an issue](/issue/new) so we can investigate.

## Footnotes

<sup>1</sup> Go stacks do not have any `alloca`-style mechanism for
dynamically-sized stack frames. All Go stack frames are constant
sized.

---

## File: _content/blog/appengine-155.md

---
title: Go App Engine SDK 1.5.5 released
date: 2011-10-11
by:
- Andrew Gerrand
tags:
- appengine
- gofix
- release
summary: Go App Engine SDK 1.5.5 includes Go release.r60.2.
---


Today we released version 1.5.5 the Go App Engine SDK.
You can download it from the [App Engine downloads page](http://code.google.com/appengine/downloads.html).

This release includes changes and improvements to the App Engine APIs and
brings the supporting Go tool chain to [release.r60.2](/doc/devel/release.html#r60)
(the current stable release).
Also included in this release are the [godoc](/cmd/godoc/),
[gofmt](/cmd/gofmt/),
and [gofix](/cmd/gofix/) tools from the Go tool chain.
They can be found in the root directory of the SDK.

Some changes made in this release are backwards-incompatible,
so we have incremented the SDK `api_version` to 3.
Existing apps will require code changes when migrating to `api_version` 3.

The gofix tool that ships with the SDK has been customized with App Engine-specific modules.
It can be used to automatically update Go apps to work with the latest appengine
packages and the updated Go standard library.
To update your apps, run:

	/path/to/sdk/gofix /path/to/your/app

The SDK now includes the appengine package source code,
so you can use the local godoc to read App Engine API documentation:

	/path/to/sdk/godoc appengine/datastore Get

**Important note:** We have deprecated `api_version` 2.
Go apps that use `api_version` 2 will stop working after 16 December 2011.
Please update your apps to use `api_version` 3 before then.

See the [release notes](http://code.google.com/p/googleappengine/wiki/SdkForGoReleaseNotes)
for a full list of changes.
Please direct any questions about the new SDK to the [Go App Engine discussion group](http://groups.google.com/group/google-appengine-go).

---

## File: _content/blog/appengine-171.md

---
title: Go updates in App Engine 1.7.1
date: 2012-08-22
by:
- Andrew Gerrand
tags:
- appengine
- release
summary: App Engine SDK 1.7.1 adds memcache and other functionality for Go.
---


This week we released version 1.7.1 of the App Engine SDK.
It includes some significant updates specific to the App Engine runtime for Go.

The [memcache package](https://developers.google.com/appengine/docs/go/memcache/reference) has
had some additions to its [Codec](https://developers.google.com/appengine/docs/go/memcache/reference#Codec) convenience type.
The SetMulti, AddMulti, CompareAndSwap, and CompareAndSwapMulti methods
make it easier to store and update encoded data in the [Memcache Service](https://developers.google.com/appengine/docs/go/memcache/overview).

The [bulkloader tool](https://developers.google.com/appengine/docs/go/tools/uploadingdata) can
now be used with Go apps,
allowing users to upload and download datastore records in bulk.
This is useful for backups and offline processing,
and a great help when migrating Python or Java apps to the Go runtime.

The [Images Service](https://developers.google.com/appengine/docs/go/images/overview) is
now available to Go users.
The new [appengine/image package](https://developers.google.com/appengine/docs/go/images/reference) supports serving
images directly from Blobstore and resizing or cropping those images on the fly.
Note that this is not the full image service as provided by the Python and Java SDKs,
as much of the equivalent functionality is available in the [standard Go image package](/pkg/image/) and
external packages such as [graphics-go](http://code.google.com/p/graphics-go/).

The new [runtime.RunInBackground](https://developers.google.com/appengine/docs/go/backends/runtime#RunInBackground) function
allows backend requests to spawn a new request independent of the initial request.
These can run in the background as long as the backend stays alive.

Finally, we have filled in some missing functionality:
the [xmpp package](https://developers.google.com/appengine/docs/go/xmpp/reference) now
supports sending presence updates and chat invitations and retrieving the
presence state of another user,
and the [user package](https://developers.google.com/appengine/docs/go/users/reference) supports
authenticating clients with OAuth.

You can grab the new SDK from the [App Engine downloads page](https://developers.google.com/appengine/downloads#Google_App_Engine_SDK_for_Go) and
browse the [updated documentation](https://developers.google.com/appengine/docs/go).

---

## File: _content/blog/appengine-dec2013.md

---
title: "Go on App Engine: tools, tests, and concurrency"
date: 2013-12-13
by:
- Andrew Gerrand
- Johan Euphrosine
tags:
- appengine
summary: Announcing improvements to Go on App Engine.
---

## Background

When we [launched Go for App Engine](/blog/go-and-google-app-engine)
in May 2011 the SDK was just a modified version of the Python SDK.
At the time, there was no canonical way to build or organize Go programs, so it
made sense to take the Python approach. Since then Go 1.0 was released,
including the [go tool](/cmd/go/) and a
[convention](/doc/code.html) for organizing Go programs.

In January 2013 we announced
[better integration](/blog/the-app-engine-sdk-and-workspaces-gopath)
between the Go App Engine SDK and the go tool, promoting the use of
conventional import paths in App Engine apps and making it possible to use "go
get" to fetch app dependencies.

With the recent release of App Engine 1.8.8 we are pleased to announce more
improvements to the developer experience for Go on App Engine.

## The goapp tool

The Go App Engine SDK now includes the "goapp" tool, an App Engine-specific
version of the "go" tool. The new name permits users to keep both the regular
"go" tool and the "goapp" tool in their system PATH.

In addition to the existing "go" tool [commands](/cmd/go/),
the "goapp" tool provides new commands for working with App Engine apps.
The "[goapp serve](https://developers.google.com/appengine/docs/go/tools/devserver)"
command starts the local development server and the
"[goapp deploy](https://developers.google.com/appengine/docs/go/tools/uploadinganapp)"
command uploads an app to App Engine.

The main advantages offered by the "goapp serve" and "goapp deploy" commands
are a simplified user interface and consistency with existing commands like
"go get" and "go fmt".
For example, to run a local instance of the app in the current directory, run:

	$ goapp serve

To upload it to App Engine:

	$ goapp deploy

You can also specify the Go import path to serve or deploy:

	$ goapp serve github.com/user/myapp

You can even specify a YAML file to serve or deploy a specific
[module](https://developers.google.com/appengine/docs/go/modules/):

	$ goapp deploy mymodule.yaml

These commands can replace most uses of `dev_appserver.py` and `appcfg.py`,
although the Python tools are still available for their less common uses.

## Local unit testing

The Go App Engine SDK now supports local unit testing, using Go's native
[testing package](https://developers.google.com/appengine/docs/go/tools/localunittesting)
and the "[go test](/cmd/go/#hdr-Test_packages)" command
(provided as "goapp test" by the SDK).

Furthermore, you can now write tests that use App Engine services.
The [aetest package](https://developers.google.com/appengine/docs/go/tools/localunittesting#Go_Introducing_the_aetest_package)
provides an appengine.Context value that delegates requests to a temporary
instance of the development server.

For more information about using "goapp test" and the aetest package, see the
[Local Unit Testing for Go documentation](https://developers.google.com/appengine/docs/go/tools/localunittesting).
Note that the aetest package is still in its early days;
we hope to add more features over time.

## Better concurrency support

It is now possible to configure the number of concurrent requests served by
each of your app's dynamic instances by setting the
[`max_concurrent_requests`](https://developers.google.com/appengine/docs/go/modules/#max_concurrent_requests) option
(available to [Automatic Scaling modules](https://developers.google.com/appengine/docs/go/modules/#automatic_scaling) only).

Here's an example `app.yaml` file:

	application: maxigopher
	version: 1
	runtime: go
	api_version: go1
	automatic_scaling:
	  max_concurrent_requests: 100

This configures each instance of the app to serve up to 100 requests
concurrently (up from the default of 10). You can configure Go instances to
serve up to a maximum of 500 concurrent requests.

This setting allows your instances to handle more simultaneous requests by
taking advantage of Go's efficient handling of concurrency, which should yield
better instance utilization and ultimately fewer billable instance hours.

## Conclusion

With these changes Go on App Engine is more convenient and efficient than ever,
and we hope you enjoy the improvements. Please join the
[google-appengine-go group](http://groups.google.com/group/google-appengine-go/)
to raise questions or discuss these changes with the engineering team and the
rest of the community.

---

## File: _content/blog/appengine-ga.md

---
title: Go for App Engine is now generally available
date: 2011-07-21
by:
- Andrew Gerrand
tags:
- appengine
- release
summary: You can use Go on App Engine now!
---


The Go and App Engine teams are excited to announce that the Go runtime
for App Engine is now generally available.
This means you can take that Go app you've been working on (or meaning to
work on) and deploy it to App Engine right now with the new [1.5.2 SDK](http://code.google.com/appengine/downloads.html).

Since we announced the Go runtime at Google I/O we have continued to [improve and extend](http://code.google.com/p/googleappengine/wiki/SdkForGoReleaseNotes)
Go support for the App Engine APIs and have added the Channels API.
The Go Datastore API now supports transactions and ancestor queries, too.
See the [Go App Engine documentation](https://code.google.com/appengine/docs/go/)
for all the details.

For those who have been using the Go SDK already,
please note that the 1.5.2 release introduces `api_version` 2.
This is because the new SDK is based on Go `release.r58.1` (the current
stable version of Go) and is not backwards compatible with the previous release.
Existing apps may require changes as per the [r58 release notes](/doc/devel/release.html#r58).
Once you've updated your code, you should redeploy your app with the line
`api_version: 2` in its `app.yaml` file.
Apps written against `api_version` 1 will stop working after the 18th of August.

Finally, we owe a huge thanks to our trusted testers and their many bug reports.
Their help was invaluable in reaching this important milestone.

_The fastest way to get started with Go on App Engine is with the_ [_Getting Started guide_](http://code.google.com/appengine/docs/go/gettingstarted/).

_Note that the Go runtime is still considered experimental; it is not as well-supported as the Python and Java runtimes._

---

## File: _content/blog/appengine-go111.md

---
title: Announcing App Engine’s New Go 1.11 Runtime
date: 2018-10-16
by:
- Eno Compton
- Tyler Bui-Palsulich
tags:
- appengine
summary: Google Cloud is announcing a new Go 1.11 runtime for App Engine, with fewer limits on app structure.
template: true
---


[App Engine](https://cloud.google.com/appengine/) launched
[experimental support for Go](/blog/go-and-google-app-engine)
in 2011. In the subsequent years, the Go community has grown significantly and
has settled on idiomatic
patterns for cloud-based applications. Today, Google Cloud is
[announcing a new Go 1.11 runtime](https://cloud.google.com/blog/products/application-development/go-1-11-is-now-available-on-app-engine)
for the App Engine standard environment that provides all the
power of App Engine—things like paying only for what you use, automatic scaling,
and managed infrastructure—while supporting idiomatic Go.

Starting with Go 1.11, Go on App Engine has no limits on application structure,
supported packages, `context.Context` values, or HTTP clients. Write your Go
application however you prefer, add an `app.yaml` file, and your app is ready
to deploy on App Engine.
[Specifying Dependencies](https://cloud.google.com/appengine/docs/standard/go111/specifying-dependencies)
describes how the new runtime
supports [vendoring](/cmd/go/#hdr-Vendor_Directories) and
[modules](/doc/go1.11#modules) (experimental) for dependency
management.

Along with [Cloud Functions support for Go](https://twitter.com/kelseyhightower/status/1035278586754813952)
(more on that in a future post), App Engine provides a compelling way to run Go
code on Google Cloud Platform (GCP) with no concern for the underlying
infrastructure.

Let’s take a look at creating a small application for App Engine. For the
example here, we assume a `GOPATH`-based workflow, although Go modules have
[experimental support](https://cloud.google.com/appengine/docs/standard/go111/specifying-dependencies)
as well.

First, you create the application in your `GOPATH`:

{{code "appengine/main.go"}}

The code contains an idiomatic setup for a small HTTP server that responds with
“Hello, 世界.” If you have previous App Engine experience, you’ll notice the
absence of any call to `appengine.Main()`, which is now entirely optional.
Furthermore, the application code is completely portable—there are no ties to
the infrastructure that your application is deployed on.

If you need to use external dependencies, you can add those dependencies to a
`vendor` directory or to a `go.mod` file, both of which the new runtime
supports.

With the application code complete, create an `app.yaml` file to specify
the runtime:

	runtime: go111

Finally, set your machine up with a Google Cloud Platform account:

  - Create an account with [GCP](https://cloud.google.com).
  - [Create a project](https://cloud.google.com/resource-manager/docs/creating-managing-projects).
  - Install the [Cloud SDK](https://cloud.google.com/sdk/) on your system.

With all the setup complete, you can deploy using one command:

	gcloud app deploy

We think Go developers will find the new Go 1.11 runtime for App Engine an
exciting addition to the available options to run Go applications. There is a
[free tier](https://cloud.google.com/free/). Check out the
[getting started guide](https://cloud.google.com/appengine/docs/standard/go111/building-app/)
or the
[migration guide](https://cloud.google.com/appengine/docs/standard/go111/go-differences)
and deploy an app to the new runtime today!

---

## File: _content/blog/appengine-gopath.md

---
title: The App Engine SDK and workspaces (GOPATH)
date: 2013-01-09
by:
- Andrew Gerrand
tags:
- appengine
- tools
- gopath
summary: App Engine SDK 1.7.4 adds support for GOPATH-style workspaces.
---

## Introduction

When we released Go 1 we introduced the [go tool](/cmd/go/) and,
with it, the concept of workspaces.
Workspaces (specified by the GOPATH environment variable) are a convention
for organizing code that simplifies fetching,
building, and installing Go packages.
If you're not familiar with workspaces, please read [this article](/doc/code.html)
or watch [this screencast](http://www.youtube.com/watch?v=XCsL89YtqCs) before reading on.

Until recently, the tools in the App Engine SDK were not aware of workspaces.
Without workspaces the "[go get](/cmd/go/#hdr-Download_and_install_packages_and_dependencies)"
command cannot function,
and so app authors had to install and update their app dependencies manually. It was a pain.

This has all changed with version 1.7.4 of the App Engine SDK.
The [dev\_appserver](https://developers.google.com/appengine/docs/go/tools/devserver)
and [appcfg](https://developers.google.com/appengine/docs/go/tools/uploadinganapp)
tools are now workspace-aware.
When running locally or uploading an app,
these tools now search for dependencies in the workspaces specified by the
GOPATH environment variable.
This means you can now use "go get" while building App Engine apps,
and switch between normal Go programs and App Engine apps without changing
your environment or habits.

For example, let's say you want to build an app that uses OAuth 2.0 to authenticate
with a remote service.
A popular OAuth 2.0 library for Go is the [oauth2](https://godoc.org/golang.org/x/oauth2) package,
which you can install to your workspace with this command:

	go get golang.org/x/oauth2

When writing your App Engine app, import the oauth package just as you would in a regular Go program:

```go
import "golang.org/x/oauth2"
```

Now, whether running your app with the dev\_appserver or deploying it with appcfg,
the tools will find the oauth package in your workspace. It just works.

## Hybrid stand-alone/App Engine apps

The Go App Engine SDK builds on Go's standard [net/http](/pkg/net/http/)
package to serve web requests and,
as a result, many Go web servers can be run on App Engine with only a few changes.
For example, [godoc](/cmd/godoc/) is included in the
Go distribution as a stand-alone program,
but it can also run as an App Engine app (godoc serves [golang.org](/) from App Engine).

But wouldn't it be nice if you could write a program that is both a stand-alone
web server and an App Engine app? By using [build constraints](/pkg/go/build/#hdr-Build_Constraints), you can.

Build constraints are line comments that determine whether a file should
be included in a package.
They are most often used in code that handles a variety of operating systems
or processor architectures.
For instance, the [path/filepath](/pkg/path/filepath/)
package includes the file [symlink.go](/src/pkg/path/filepath/symlink.go),
which specifies a build constraint to ensure that it is not built on Windows
systems (which do not have symbolic links):

```go
// +build !windows
```

The App Engine SDK introduces a new build constraint term: "appengine". Files that specify

```go
// +build appengine
```

will be built by the App Engine SDK and ignored by the go tool. Conversely, files that specify

```go
// +build !appengine
```

are ignored by the App Engine SDK, while the go tool will happily build them.

The [goprotobuf](http://code.google.com/p/goprotobuf/) library uses this
mechanism to provide two implementations of a key part of its encode/decode machinery:
[pointer\_unsafe.go](http://code.google.com/p/goprotobuf/source/browse/proto/pointer_unsafe.go)
is the faster version that cannot be used on App Engine because it uses
the [unsafe package](/pkg/unsafe/),
while [pointer\_reflect.go](http://code.google.com/p/goprotobuf/source/browse/proto/pointer_reflect.go)
is a slower version that avoids unsafe by using the [reflect package](/pkg/reflect/) instead.

Let's take a simple Go web server and turn it into a hybrid app. This is main.go:

```go
package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe("localhost:8080", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello!")
}
```

Build this with the go tool and you'll get a stand-alone web server executable.

The App Engine infrastructure provides its own main function that runs its
equivalent to ListenAndServe.
To convert main.go to an App Engine app, drop the call to ListenAndServe
and register the handler in an init function (which runs before main). This is app.go:

```go
package main

import (
    "fmt"
    "net/http"
)

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

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello!")
}
```

To make this a hybrid app, we need to split it into an App Engine-specific part,
an stand-alone binary-specific part, and the parts common to both versions.
In this case, there is no App Engine-specific part,
so we split it into just two files:

app.go specifies and registers the handler function.
It is identical to the code listing above,
and requires no build constraints as it should be included in all versions of the program.

main.go runs the web server. It includes the "!appengine" build constraint,
as it must only be included when building the stand-alone binary.

```go
// +build !appengine

package main

import "net/http"

func main() {
    http.ListenAndServe("localhost:8080", nil)
}
```

To see a more complex hybrid app, take a look at the [present tool](https://godoc.org/golang.org/x/tools/present).

## Conclusions

We hope these changes will make it easier to work on apps with external dependencies,
and to maintain code bases that contain both stand-alone programs and App Engine apps.

---

## File: _content/blog/appengine-scalable.md

---
title: Writing scalable App Engine applications
date: 2011-11-01
by:
- David Symonds
tags:
- appengine
- optimization
summary: How to build scalable web applications using Go with Google App Engine.
---


Back in May, we [announced](/blog/go-and-google-app-engine)
the Go runtime for App Engine.
Since then, we've opened it up for everyone to use,
added many new APIs, and improved performance.
We have been thrilled by all the interesting ways that people are using Go on App Engine.
One of the key benefits of the Go runtime,
apart from working in a fantastic language,
is that it has high performance.
Go applications compile to native code, with no interpreter or virtual machine
getting between your program and the machine.

Making your web application fast is important because it is well known that
a web site's latency has a measurable impact on user happiness,
and [Google web search uses it as a ranking factor](https://googlewebmastercentral.blogspot.com/2010/04/using-site-speed-in-web-search-ranking.html).
Also announced in May was that App Engine would be [leaving its Preview status](http://googleappengine.blogspot.com/2011/05/year-ahead-for-google-app-engine.html)
and transitioning to a [new pricing model](https://www.google.com/enterprise/cloud/appengine/pricing.html),
providing another reason to write efficient App Engine applications.

To make it easier for Go developers using App Engine to write highly efficient,
scalable applications, we recently updated some existing App Engine articles
to include snippets of Go source code and to link to relevant Go documentation.

  - [Best practices for writing scalable applications](http://code.google.com/appengine/articles/scaling/overview.html)

  - [Managing Your App's Resource Usage](http://code.google.com/appengine/articles/managing-resources.html)

---

## File: _content/blog/appengine.md

---
title: Go and Google App Engine
date: 2011-05-10
by:
- David Symonds
- Nigel Tao
- Andrew Gerrand
tags:
- appengine
- release
summary: Announcing support for Go in Google App Engine.
---


Google’s App Engine provides a reliable,
scalable, easy way to build and deploy applications for the web.
Over a hundred thousand apps are hosted at appspot.com and custom domains
using the App Engine infrastructure.
Originally written for Python apps, in 2009 the system added a Java runtime.
And today, at Google I/O, we’re thrilled to announce that Go will be next.
It’s marked as an experimental App Engine feature for now,
because it’s early days, but both the App Engine and Go teams are very
excited about this milestone.

By early days, we mean that it’s still rolling out.
As of today, the App Engine SDK for Go is [available for download](http://code.google.com/p/googleappengine/downloads/list),
and we will soon enable deployment of Go apps into the App Engine hosting infrastructure.
Today, through the SDK, you’ll be able to write web apps,
learn about the APIs (and the language, if it’s new to you),
and run your web app locally.
Once full deployment is enabled, it’ll be easy to push your app to Google’s cloud.

One of the cool but less obvious things about this news is that it provides
a very easy way to play with Go.
You don’t even need to have Go installed beforehand because the SDK is
fully self-contained.
Just download the SDK, unzip it, and start coding.
Moreover, the SDK’s “dev app server” means you don’t even need to
run the compiler yourself;
everything is delightfully automatic.

What you’ll find in the SDK is many of the standard App Engine APIs,
custom designed in good Go style, including Datastore,
Blobstore, URL Fetch, Mail, Users, and so on.
More APIs will be added as the environment develops.
The runtime provides the full Go language and almost all the standard libraries,
except for a few things that don’t make sense in the App Engine environment.
For instance, there is no `unsafe` package and the `syscall` package is trimmed.
(The implementation uses an expanded version of the setup in the [Go Playground](/doc/play/)
on [golang.org](/).)

Also, although goroutines and channels are present,
when a Go app runs on App Engine only one thread is run in a given instance.
That is, all goroutines run in a single operating system thread,
so there is no CPU parallelism available for a given client request.
We expect this restriction will be lifted at some point.

Despite these minor restrictions, it’s the real language:
Code is deployed in source form and compiled in the cloud using the 64-bit x86 compiler (6g),
making it the first true compiled language that runs on App Engine.
Go on App Engine makes it possible to deploy efficient,
CPU-intensive web applications.

If you want to know more, read the [documentation](http://code.google.com/appengine/docs/go/)
(start with “[Getting Started](http://code.google.com/appengine/docs/go/gettingstarted/)”).
The libraries and SDK are open source, hosted at [http://code.google.com/p/appengine-go/](http://code.google.com/p/appengine-go/).
We’ve created a new [google-appengine-go](http://groups.google.com/group/google-appengine-go) mailing list;
feel free to contact us there with App Engine-specific questions.
The [issue tracker for App Engine](http://code.google.com/p/googleappengine/issues/list)
is the place for reporting issues related to the new Go SDK.

The Go App Engine SDK is [available](http://code.google.com/p/googleappengine/downloads/list)
for Linux and Mac OS X (10.5 or greater);
we hope a Windows version will also be available soon.

We’d like to offer our thanks for all the help and enthusiasm we received
from Google’s App Engine team in making this happen.

---

## File: _content/blog/archsimd.md

---
title: Arch-specific SIMD in Go
date: 2026-10-02
by:
- Junyang Shao
- David Chase
tags:
- SIMD
- performance
summary: Go 1.27 introduces experimental arch-specific SIMD vector APIs
---

Since Go 1.26, we have supported an experimental `amd64` SIMD API. Now in Go 1.27, we support two more architectures: `arm64` and `wasm`.

The new APIs can be accessed by setting `GOEXPERIMENT=simd` when building a program. They are defined in the `simd/archsimd` package.

`archsimd` is the lower-level infrastructure that `simd` builds on, essentially the intrinsics layer in other languages. For exotic operations that only exist on a specific architecture, users can access them by transitioning from `simd` to `archsimd` (via `ToArch` and `<Types>FromArch`). For details, please refer to the [simd blog](/blog/simd-experiment) post.

For readers with prior knowledge of SIMD intrinsics in other languages, you might find that our `archsimd` API does not directly mirror the underlying hardware instructions:
- We give our APIs sensible names: e.g., instead of `_mm512_slli_epi64`, we just call it `ShiftAllLeft`.
- We leave some architecture details to compiler optimizations rather than exposing them in the API: e.g., instead of `_mm512_maskz_add_ps(m, x, y)`, we optimize `x.Add(y).Masked(m)` into the same instruction.

These design decisions make our APIs smaller and more accessible, and they also happily make the `simd` implementation much easier.

For readers without prior knowledge of SIMD intrinsics, we hope our low-level API is a natural and pleasant journey for you.

Please share your feedback and comments. Anything about usability, performance, etc., is appreciated. The parent issue for this project is [#73787](/issue/73787).

## What is SIMD

SIMD stands for Single Instruction, Multiple Data. SIMD instructions operate on wide registers (128-bit, 256-bit, or more) containing multiple 8- to 64-bit elements, performing operations across all elements in parallel. Wider registers and parallel execution provide a significant performance boost to algorithms that can take advantage of them.

Until now, anyone who wanted to use SIMD in Go had to endure the friction of writing assembly language. The new `archsimd` package is here to change that.

## Goals

The goal is to support as many SIMD instructions across different architectures as possible. Currently, we have `amd64`, `arm64`, and `wasm` available. Our `amd64` support has the largest API surface, covering AVX, AVX2, and many AVX-512 extensions. Our `arm64` support currently covers NEON, with SVE and some SVE2 already on the way. Our `wasm` support is also mostly complete, thanks to its well-defined 128-bit SIMD abstraction.

Some users might be interested in matrix extensions on certain architectures, such as AMX and SME. We haven't fully settled on how to represent matrices effectively in Go, so they are not yet supported, but we might support them in the future.

## API Design and Naming

### Types

The architecture-specific SIMD API is imported from `simd/archsimd`. `archsimd` uses distinct struct types, such as `Float32x4`, `Int32x8`, or `Uint8x16`, to signal the shape and element type of each vector, and defines operations as methods on those types. At this moment, `archsimd` supports only fixed-width vector extensions. Scalable vector extensions like `arm64` SVE and RVV will have different struct types to represent vectors. Mask types also come with vector-like shapes, e.g., `Mask32x4`.

### Methods

Across different vector widths, element types, and architectures, we use the same method name whenever operations are semantically identical:
- Regardless of vector width or architecture, element-wise addition is simply `x.Add(y)`; the type of `x` determines which instruction to emit. Instead of 18 different function names for addition, there is only one method name.
- When instructions on different architectures look similar at a glance but differ in edge-case behavior, we give them distinct names so differences don't silently bite you. For example, 16-byte table lookup on `amd64` (`VPSHUFB`) zeros the output byte when the index is negative (`index < 0`) and wraps modulo 16 otherwise, so we call it `PermuteOrZero`. On `arm64` NEON (`VTBL`) and `wasm` (`i8x16.swizzle`), any out-of-range index (`index < 0 || index >= 16`) zeros the output byte, so we call it `LookupOrZero`.
- On `amd64`, many 256-bit and 512-bit instructions operate independently within 128-bit lanes rather than across the entire register. We explicitly suffix those methods with `Grouped` (such as `InterleaveLoGrouped` or `PermuteOrZeroGrouped`) to make the 128-bit lane boundary obvious.

Methods require a receiver value, which doesn't work for creating a vector from memory or a scalar. For those, `archsimd` provides package-level functions named with the target vector type:
- **Slices (the default)**: In Go 1.27, loading and storing slices use the shortest names: `archsimd.LoadFloat32x4(s []float32) Float32x4` and `x.Store(s []float32)`. For tail elements that may be shorter than a full vector, `archsimd.LoadFloat32x4Part(s []float32) (Float32x4, int)` zero-fills the remaining lanes and returns the number of elements loaded, paired with `x.StorePart(s []float32) int`.
- **Arrays and Broadcasts**: Fixed-size array pointers use the `Array` suffix (`archsimd.LoadFloat32x4Array(y *[4]float32)` and `x.StoreArray(y *[4]float32)`), and `archsimd.BroadcastFloat32x4(v float32)` broadcasts a scalar to all lanes.

### Type Reinterpretation

Reinterpretations are type casts without any cost. SIMD algorithms frequently reinterpret bits across element types and widths.

In the Go 1.26 experiment, we implemented this with `As<Type>` methods, which suffered from a quadratic explosion of type pairs and couldn't generalize to width-agnostic vectors in `simd` or SVE.

In Go 1.27, we replace them with composable zero-cost conversions:
- `ToBits()` reinterprets a signed integer or float vector as an unsigned integer vector of the same element width (e.g., `Int32x4.ToBits() -> Uint32x4`), and `BitsToInt32()` / `BitsToFloat32()` converts back.
- `ReshapeToUint<W>s()` on unsigned vectors changes the element width within the same register width. For example, if `x` is an `archsimd.Uint8x16`, then `x.ReshapeToUint32s().BitsToFloat32()` reinterprets the bits of `x` as an `archsimd.Float32x4` at zero runtime cost.

### Masks

Different architectures encode vector masks very differently, e.g. `k` mask registers on AVX-512, full vector bitmasks on AVX/AVX2, NEON, and `wasm`, and predicate registers on SVE. To hide this hardware detail, `archsimd` provides opaque `Mask` types (such as `Mask32x4`) matching each vector shape:
- Comparisons like `x.Greater(y)` produce a `Mask`.
- `x.Masked(m)` zeros elements where `m` is false, and `x.IfElse(m, y)` (which replaces `Merge` from Go 1.26) selects elements from `x` where `m` is true and from `y` where `m` is false.
- The compiler peepholes mask operations with the surrounding instructions: on AVX-512, `x.Add(y).Masked(m)` or `x.Add(y).IfElse(m, z)` compiles into a single zero-masked or merge-masked `VPADD` instruction; on AVX2, NEON, or `wasm`, it lowers to the appropriate bitwise `AND` or blend/bitselect instruction.

## Examples

Portable algorithms like inner product can easily be implemented using the portable `simd` package, as shown in the companion [simd blog](/blog/simd-experiment) post. However, we still expose `archsimd` to tap into exotic, architecture-specific instructions that do not fit into a portable intersection API, or instructions that can simply do things faster than what `simd` provides.

On `amd64`, the GFNI extension exposes `GaloisFieldAffineTransform` operations. Putting aside what a Galois Field is, these operations do a simple thing:
```go
// Each element of A is interpreted as a matrix of 8 rows of vectors of 8 bits.
// Each element of x is interpreted as a vector of 8 bits.
// The b argument is likewise a vector of 8 bits.
// The result is z[i] = (A[i/8] * x[i]) + b.
//
// The matrix * and vector + follow the usual rules for linear algebra,
// but based on AND and XOR for scalar * and +
//
// Asm: VGF2P8AFFINEQB, CPU Feature: AVX512GFNI
func (x Uint8x16) GaloisFieldAffineTransform(A Uint64x2, b uint8) Uint8x16
```

Each 8x8 bit matrix `A` is packed row-by-row into a single `uint64`. Because any linear combination or permutation of the 8 bits within a byte can be written as an 8x8 bit matrix, this single instruction is a Swiss Army knife for byte-level bit manipulation.

For example, reversing the bit order of every byte (`bits.Reverse8`) normally requires nibble lookup tables, masks, shifts, and ORs in SIMD. With `GaloisFieldAffineTransform`, we can simply multiply each byte by the 8x8 anti-diagonal identity matrix (`0x8040201008040201`) to reverse all 8 bits of 64 bytes at a time in a single instruction:

```go
/*
	Anti-diagonal 8x8 bit matrix (0x8040201008040201):
	[ 0 0 0 0 0 0 0 1 ]   [ x7 ]   [ x0 ]
	[ 0 0 0 0 0 0 1 0 ]   [ x6 ]   [ x1 ]
	[ 0 0 0 0 0 1 0 0 ]   [ x5 ]   [ x2 ]
	[ 0 0 0 0 1 0 0 0 ] * [ x4 ] = [ x3 ]
	[ 0 0 0 1 0 0 0 0 ]   [ x3 ]   [ x4 ]
	[ 0 0 1 0 0 0 0 0 ]   [ x2 ]   [ x5 ]
	[ 0 1 0 0 0 0 0 0 ]   [ x1 ]   [ x6 ]
	[ 1 0 0 0 0 0 0 0 ]   [ x0 ]   [ x7 ]
*/
func ReverseBits(dst, src []uint8) {
	if !archsimd.X86.AVX512GFNI() {
		// A slow fallback emulation impl, details omitted.
		slowReverseBits(dst, src)
		return
	}
	if len(src) > len(dst) {
		// Make sure src and dst are the same size
		src = src[:len(dst)]
	}
	revMatrix := archsimd.BroadcastUint64x8(0x8040201008040201)
	var v archsimd.Uint8x64
	var i int
	for i = 0; i < len(src)-v.Len()+1; i += v.Len() {
		v = archsimd.LoadUint8x64(src[i : i+v.Len()])
		v.GaloisFieldAffineTransform(revMatrix, 0).Store(dst[i : i+v.Len()])
	}
	if i < len(src) {
		v, _ = archsimd.LoadUint8x64Part(src[i:])
		v.GaloisFieldAffineTransform(revMatrix, 0).StorePart(dst[i:])
	}
}
```

Another example is matrix transpose. On `amd64`, the permutation instructions are shaped in a non-portable way, so using `simd` is cumbersome and might incur emulations. An efficient implementation can be written more directly in `archsimd`. The example below transposes an 8-by-8 matrix of 32-bit integers in registers on `amd64` using AVX2's 128-bit lane-grouped interleaves (`InterleaveLoGrouped`, `InterleaveHiGrouped`) and cross-lane permutations (`ConcatPermuteScalarsGrouped`, `ConcatPermute128Scalars`):

```go
func Transpose8(a0, a1, a2, a3, a4, a5, a6, a7 archsimd.Int32x8) (
	b0, b1, b2, b3, b4, b5, b6, b7 archsimd.Int32x8) {
	if !archsimd.X86.AVX2() {
		// A slow fallback emulation impl, details omitted.
		return slowTranspose8(a0, a1, a2, a3, a4, a5, a6, a7)
	}
	/*
		    LOW  HIGH
		a0: abcd efgh
		a1: ijkl mnop
		a2: qrst uvwx
		a3: 0123 4567
		a4: ABCD EFGH
		a5: IJKL MNOP
		a6: QRST UVWX
		a7: 89yz YZ$@
	*/
	t0 := a0.InterleaveLoGrouped(a1) // t0 = aibj emfn
	t1 := a0.InterleaveHiGrouped(a1) // t1 = ckdl gohp
	t2 := a2.InterleaveLoGrouped(a3) // t2 = q0r1 u4v5
	t3 := a2.InterleaveHiGrouped(a3) // t3 = s2t3 w6x7
	t4 := a4.InterleaveLoGrouped(a5) // t4 = AIBJ EMFN
	t5 := a4.InterleaveHiGrouped(a5) // t5 = CKDL GOHP
	t6 := a6.InterleaveLoGrouped(a7) // t6 = Q8R9 UYVZ
	t7 := a6.InterleaveHiGrouped(a7) // t7 = SyTz W$X@

	a0 = t0.ConcatPermuteScalarsGrouped(0, 1, 4, 5, t2) // a0 = aiq0 emu4
	a1 = t0.ConcatPermuteScalarsGrouped(2, 3, 6, 7, t2) // a1 = bjr1 fnv5
	a2 = t1.ConcatPermuteScalarsGrouped(0, 1, 4, 5, t3) // a2 = cks2 gow6
	a3 = t1.ConcatPermuteScalarsGrouped(2, 3, 6, 7, t3) // a3 = dlt3 hpx7
	a4 = t4.ConcatPermuteScalarsGrouped(0, 1, 4, 5, t6) // a4 = AIQ8 EMUY
	a5 = t4.ConcatPermuteScalarsGrouped(2, 3, 6, 7, t6) // a5 = BJR9 FNVZ
	a6 = t5.ConcatPermuteScalarsGrouped(0, 1, 4, 5, t7) // a6 = CKSy GOW$
	a7 = t5.ConcatPermuteScalarsGrouped(2, 3, 6, 7, t7) // a7 = DLTz HPX@

	b0 = a0.ConcatPermute128Scalars(0, 2, a4) // b0 = aiq0 AIQ8
	b1 = a1.ConcatPermute128Scalars(0, 2, a5) // b1 = bjr1 BJR9
	b2 = a2.ConcatPermute128Scalars(0, 2, a6) // b2 = cks2 CKSy
	b3 = a3.ConcatPermute128Scalars(0, 2, a7) // b3 = dlt3 DLTz
	b4 = a0.ConcatPermute128Scalars(1, 3, a4) // b4 = emu4 EMUY
	b5 = a1.ConcatPermute128Scalars(1, 3, a5) // b5 = fnv5 FNVZ
	b6 = a2.ConcatPermute128Scalars(1, 3, a6) // b6 = gow6 GOW$
	b7 = a3.ConcatPermute128Scalars(1, 3, a7) // b7 = hpx7 HPX@

	return
}
```

## Good Practices

When walking through the examples above, you might have a few questions:

- What is `archsimd.X86.AVX512GFNI()`, and can I omit it?
- Why is the strided loop written as `i = 0; i < len(src)-v.Len()+1; i += v.Len()`, instead of `i = 0; i + v.Len() <= len(src); i += v.Len()`?
- Why does `Transpose8` take 8 vector parameters rather than a struct or an `[8]archsimd.Int32x8` array?

At first glance these choices might look like minor stylistic preferences, but each of them is chosen for an important performance or correctness reason:

- CPU feature checks (`archsimd.X86.*`, `archsimd.ARM64.*`)

   On `amd64`, we provide runtime feature checks like `archsimd.X86.AVX()`, `AVX2()`, `AVX512()`, and extension checks like `AVX512GFNI()` or `AVX512VNNI()`; on `arm64`, NEON is always available, and we provide checks for optional extensions like `archsimd.ARM64.PMULL()`, `SVE()`, and `SVE2()`. The compiler doesn't know ahead of time whether the machine running your binary supports optional SIMD extensions. If you don't guard your SIMD code with the appropriate feature check, your program may crash with `SIGILL` on hardware that lacks the instruction.

   Just as importantly, CPU feature checks act as **compiler optimization hints**. For example, AVX-512 supports hardware merge-masking on instruction outputs. How the compiler lowers `x.Add(y).IfElse(m, z)` on a 128-bit or 256-bit vector depends on which CPU features are known to be available. If the code is not guarded by `archsimd.X86.AVX512()`, the compiler must conservatively emit a vector `VPADD` followed by a `VPBLEND` instruction. Inside an `if archsimd.X86.AVX512()` block, however, the compiler knows AVX-512 is available and fuses the sequence into a single merge-masked AVX-512 `VPADD` instruction.

- Bounds check elimination in strided loops

   How you write the loop bound determines whether the compiler's `prove` pass can eliminate slice bounds checks inside the loop. In `i + v.Len() <= len(src)`, the addition `i + v.Len()` could theoretically overflow to a negative `int` if `len(src)` were near `math.MaxInt`, which prevents the compiler from proving that `i` is always non-negative and in-bounds. Writing `i < len(src)-v.Len()+1` avoids that potential overflow, allowing the loop body to compile with zero bounds checks.

- Keeping vectors in registers (avoiding large composite types)

   `Transpose8` passes 8 vector parameters rather than a struct of 8 fields or an `[8]archsimd.Int32x8` array because Go's ABI and SSA backend currently place large composite types in memory rather than in registers (a known issue tracked at [#24416](/issue/24416)). Because SIMD vectors are 16 to 64 bytes each, spilling them to the stack hurts performance much more than spilling scalar values. This applies to both function parameters and local variables, so avoid wrapping SIMD vectors inside large arrays or structs in hot loops. There are ongoing efforts to promote composite memory accesses back into registers, which have not yet landed in Go 1.27.

## Trying it out

In Go 1.27, `GOEXPERIMENT=simd` supports `amd64` (AVX, AVX2, and AVX-512), `arm64` (NEON), and `wasm` (WebAssembly 128-bit SIMD) out of the box. Whether you are on an Intel/AMD machine, an `arm64` server or Apple Silicon Mac (M1/M2/M3/M4), or targeting WebAssembly, you can try `archsimd` natively right away:

```sh
GOEXPERIMENT=simd go test simd/archsimd/...
```

You can also cross-test `wasm` (or `amd64` via Rosetta emulation on Apple Silicon) by setting `GOARCH`:

```sh
# Run wasm SIMD tests using a WASI runtime:
GOOS=wasip1 GOARCH=wasm GOEXPERIMENT=simd go test simd/archsimd/...

# Or run amd64 AVX2 tests on Apple Silicon via Rosetta:
GOARCH=amd64 GOEXPERIMENT=simd go test simd/archsimd/...
```

We're interested in all sorts of feedback! Early users have already helped us catch bugs (such as [#77582](/issue/77582)) and identify places where code generation or API ergonomics could be improved. We tried hard to pick clear, consistent names and cover the most useful instructions, but `archsimd` is a massive API surface and there is always room to improve.

## Future work

For Go 1.28 and beyond, we are actively working on completing `arm64` SVE and SVE2 support in `archsimd` (introducing width-agnostic scalable vector types like `archsimd.Float32s` backed directly by hardware SVE registers and predicates) and wiring it into `simd`. We also plan to expand `archsimd` to additional architectures such as `riscv64`, `ppc64`, `s390x`, and `loong64`, improve register promotion for composite types, and continue filling in instructions and compiler optimizations based on community feedback.

---

## File: _content/blog/bossie.md

---
title: Go Wins 2010 Bossie Award
date: 2010-09-06
by:
- Andrew Gerrand
summary: Go wins a 2010 Bossie Award for “best open source application development software.”
---


The Go project has been awarded a [Bossie Award](http://www.infoworld.com/d/open-source/bossie-awards-2010-the-best-open-source-application-development-software-140&current=2&last=1)
for "best open source application development software." The [Bossie Awards](http://www.infoworld.com/d/open-source/bossie-awards-2010-the-best-open-source-software-the-year-115)
have been given each year since 2007 by [InfoWorld](http://infoworld.com/)
to recognize the best Open Source projects.
Their citation reads:

Google's Go language tries to restore simplicity to programming.
It does away with numerous constructs that have crept into all OO languages
by re-imagining how to simplify and improve the conversation between a developer and the code.
Go provides garbage collection, type safety,
memory safety, and built-in support for concurrency and for Unicode characters.
In addition, it compiles (fast!) to binaries for multiple platforms.
Go is still in development (new features are being added) and it has limitations,
notably poor support for Windows.
But it shows a new, exciting direction in programming languages.

The Go team are pleased to accept this award.
It reflects not only our hard work, but also the efforts of the growing
community of Go developers to whom we must extend our sincere thanks.

---

## File: _content/blog/building-stathat-with-go.md

---
redirect: /blog/stathat
---

---

## File: _content/blog/c-go-cgo.md

---
redirect: /blog/cgo
---

---

## File: _content/blog/cgo.md

---
title: C? Go? Cgo!
date: 2011-03-17
by:
- Andrew Gerrand
tags:
- cgo
- technical
summary: How to use cgo to let Go packages call C code.
---

## Introduction

Cgo lets Go packages call C code. Given a Go source file written with some special features,
cgo outputs Go and C files that can be combined into a single Go package.

To lead with an example, here's a Go package that provides two functions -
`Random` and `Seed` - that wrap C's `random` and `srandom` functions.

```go
package rand

/*
#include <stdlib.h>
*/
import "C"

func Random() int {
    return int(C.random())
}

func Seed(i int) {
    C.srandom(C.uint(i))
}
```

Let's look at what's happening here, starting with the import statement.

The `rand` package imports `"C"`, but you'll find there's no such package
in the standard Go library.
That's because `C` is a "pseudo-package",
a special name interpreted by cgo as a reference to C's name space.

The `rand` package contains four references to the `C` package:
the calls to `C.random` and `C.srandom`, the conversion `C.uint(i)`,
and the `import` statement.

The `Random` function calls the standard C library's `random` function and returns the result.
In C, `random` returns a value of the C type `long`,
which cgo represents as the type `C.long`.
It must be converted to a Go type before it can be used by Go code outside this package,
using an ordinary Go type conversion:

```go
func Random() int {
    return int(C.random())
}
```

Here's an equivalent function that uses a temporary variable to illustrate the type conversion more explicitly:

```go
func Random() int {
    var r C.long = C.random()
    return int(r)
}
```

The `Seed` function does the reverse, in a way.
It takes a regular Go `int`, converts it to the C `unsigned int` type,
and passes it to the C function `srandom`.

```go
func Seed(i int) {
    C.srandom(C.uint(i))
}
```

Note that cgo knows the `unsigned int` type as `C.uint`;
see the [cgo documentation](/cmd/cgo) for a complete
list of these numeric type names.

The one detail of this example we haven't examined yet is the comment above the `import` statement.

```go
/*
#include <stdlib.h>
*/
import "C"
```

Cgo recognizes this comment.  Any lines starting with `#cgo` followed by
a space character are removed;
these become directives for cgo.
The remaining lines are used as a header when compiling the C parts of the package.
In this case those lines are just a single `#include` statement,
but they can be almost any C code.
The `#cgo` directives are used to provide flags for the compiler and linker
when building the C parts of the package.

There is a limitation: if your program uses any `//export` directives,
then the C code in the comment may only include declarations (`extern int f();`),
not definitions (`int f() { return 1; }`).
You can use `//export` directives to make Go functions accessible to C code.

The `#cgo` and `//export` directives are documented in the [cgo documentation](/cmd/cgo/).

## Strings and things

Unlike Go, C doesn't have an explicit string type. Strings in C are represented by a zero-terminated array of chars.

Conversion between Go and C strings is done with the `C.CString`,
`C.GoString`, and `C.GoStringN` functions.
These conversions make a copy of the string data.

This next example implements a `Print` function that writes a string to
standard output using C's `fputs` function from the `stdio` library:

```go
package print

// #include <stdio.h>
// #include <stdlib.h>
import "C"
import "unsafe"

func Print(s string) {
    cs := C.CString(s)
    C.fputs(cs, (*C.FILE)(C.stdout))
    C.free(unsafe.Pointer(cs))
}
```

Memory allocations made by C code are not known to Go's memory manager.
When you create a C string with `C.CString` (or any C memory allocation)
you must remember to free the memory when you're done with it by calling `C.free`.

The call to `C.CString` returns a pointer to the start of the char array,
so before the function exits we convert it to an [`unsafe.Pointer`](/pkg/unsafe/#Pointer)
and release the memory allocation with `C.free`.
A common idiom in cgo programs is to [`defer`](/doc/articles/defer_panic_recover.html)
the free immediately after allocating (especially when the code that follows
is more complex than a single function call),
as in this rewrite of `Print`:

```go
func Print(s string) {
    cs := C.CString(s)
    defer C.free(unsafe.Pointer(cs))
    C.fputs(cs, (*C.FILE)(C.stdout))
}
```

## Building cgo packages

To build cgo packages, just use [`go build`](/cmd/go/#hdr-Compile_packages_and_dependencies)
or [`go install`](/cmd/go/#hdr-Compile_and_install_packages_and_dependencies) as usual.
The go tool recognizes the special `"C"` import and automatically uses cgo for those files.

## More cgo resources

The [cgo command](/cmd/cgo/) documentation has more
detail about the C pseudo-package and the build process.
The [cgo examples](/misc/cgo/) in the Go tree demonstrate
more advanced concepts.

Finally, if you're curious as to how all this works internally,
take a look at the introductory comment of the runtime package's [cgocall.go](/src/runtime/cgocall.go).

---

## File: _content/blog/chacha8rand.md

---
title: "Secure Randomness in Go 1.22"
date: 2024-05-02
by:
- Russ Cox
- Filippo Valsorda
summary: ChaCha8Rand is a new cryptographically secure pseudorandom number generator used in Go 1.22.
template: true
---

Computers aren't random.
On the contrary, hardware designers work very hard to make sure computers run every program the same way every time.
So when a program does need random numbers, that requires extra effort.
Traditionally, computer scientists and programming languages
have distinguished between two different kinds of random numbers:
statistical and cryptographic randomness.
In Go, those are provided by [`math/rand`](/pkg/math/rand/)
and [`crypto/rand`](/pkg/crypto/rand), respectively.
This post is about how Go 1.22 brings the two closer together,
by using a cryptographic random number source in `math/rand`
(as well as `math/rand/v2`, as mentioned in our [previous post](/blog/randv2)).
The result is better randomness and far less damage when
developers accidentally use `math/rand` instead of `crypto/rand`.

Before we can explain what Go 1.22 did, let's take a closer look
at statistical randomness compared to cryptographic randomness.

## Statistical Randomness

Random numbers that pass basic statistical tests
are usually appropriate for use cases like simulations, sampling,
numerical analysis, non-cryptographic randomized algorithms,
[random testing](/doc/security/fuzz/),
[shuffling inputs](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle),
and
[random exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff#Collision_avoidance).
Very basic, easy to compute mathematical formulas turn out to work
well enough for these use cases.
Because the methods are so simple, however, an observer who
knows what algorithm is being used can typically predict the rest
of the sequence after seeing enough values.

Essentially all programming environments provide a mechanism for generating
statistical random numbers
that traces back through C to
Research Unix Third Edition (V3), which added a pair of functions: `srand` and `rand`.
The manual page included
a note that read:

> _WARNING   The author of this routine has been writing
random-number generators for many years and has never been
known to write one that worked._

This note was partly a joke but also an acknowledgement that such
generators are [inherently not random](https://www.tuhs.org/pipermail/tuhs/2024-March/029587.html).

The source code of the generator makes clear how trivial it is.
Translated from PDP-11 assembly to modern C, it was:

	uint16 ranx;

	void
	srand(uint16 seed)
	{
	    ranx = seed;
	}

	int16
	rand(void)
	{
	    ranx = 13077*ranx + 6925;
	    return ranx & ~0x8000;
	}

Calling `srand` seeds the generator with a single integer seed,
and `rand` returns the next number from the generator.
The AND in the return statement clears the sign bit to make sure the result is positive.

This function is an instance of the general class of
[linear congruential generators (LCGs)](https://en.wikipedia.org/wiki/Linear_congruential_generator),
which Knuth analyzes in _The Art of Computer Programming_, Volume 2, section 3.2.1.
The main benefit of LCGs is that constants can be chosen such that they
emit every possible output value once before repeating,
as the Unix implementation did for 15-bit outputs.
A serious problem with LCGs, however, is that the high bits of the state do not affect the low bits at all,
so every truncation of the sequence to _k_ bits necessarily repeats with a smaller period.
The low bit must toggle: 0, 1, 0, 1, 0, 1.
The low two bits must count up or down: 0, 1, 2, 3, 0, 1, 2, 3, or else 0, 3, 2, 1, 0, 3, 2, 1.
There are four possible three-bit sequences; the original Unix implementation repeats 0, 5, 6, 3, 4, 1, 2, 7.
(These problems can be avoided by reducing the value modulo a prime,
but that would have been quite expensive at the time.
See S. K. Park and K. W. Miller's 1988 CACM paper
“[Random number generators: good ones are hard to find](https://dl.acm.org/doi/10.1145/63039.63042)”
for a short analysis
and the first chapter of Knuth Volume 2 for a longer one.)

Even with these known problems,
the `srand` and `rand` functions were included in the first C standard,
and equivalent functionality was included in essentially every language since then.
LCGs were once the dominant implementation strategy,
although they've fallen off in popularity due to some important drawbacks.
One significant remaining use is [`java.util.Random`](https://github.com/openjdk/jdk8u-dev/blob/master/jdk/src/share/classes/java/util/Random.java),
which powers [`java.lang.Math.random`](https://github.com/openjdk/jdk8u-dev/blob/master/jdk/src/share/classes/java/util/Random.java).

Another thing you can see from the implementation above
is that the internal state is completely exposed by the result of `rand`.
An observer who knows the algorithm and sees a single result
can easily compute all future results.
If you are running a server that calculates some random values
that become public and some random values that must stay secret,
using this kind of generator would be disastrous:
the secrets wouldn't be secret.

More modern random generators aren't as terrible as the original Unix one,
but they're still not completely unpredictable.
To make that point, next we will look at the original `math/rand` generator from Go 1
and the PCG generator we added in `math/rand/v2`.

## The Go 1 Generator

The generator used in Go 1's `math/rand` is an instance of what is called a
[linear-feedback shift register](https://en.wikipedia.org/wiki/Linear-feedback_shift_register).
The algorithm is based on an idea by George Marsaglia,
tweaked by Don Mitchell and Jim Reeds,
and further customized by Ken Thompson for Plan 9 and then Go.
It has no official name, so this post calls it the Go 1 generator.

The Go 1 generator's internal state is a slice `vec` of 607 uint64s.
In that slice, there are two distinguished elements: `vec[606]`, the last element, is called the “tap”,
and `vec[334]` is called the “feed”.
To generate the next random number,
the generator adds the tap and the feed
to produce a value `x`,
stores `x` back into the feed,
shifts the entire slice one position to the right
(the tap moves to `vec[0]` and `vec[i]` moves to `vec[i+1]`),
and returns `x`.
The generator is called “linear feedback” because the tap is _added_ to the feed;
the entire state is a “shift register” because each step shifts the slice entries.

Of course, actually moving every slice entry forward would be prohibitively expensive,
so instead the implementation leaves the slice data in place
and moves the tap and feed positions backward
on each step. The code looks like:

{{raw `
~~~go
func (r *rngSource) Uint64() uint64 {
	r.tap--
	if r.tap < 0 {
		r.tap += len(r.vec)
	}

	r.feed--
	if r.feed < 0 {
		r.feed += len(r.vec)
	}

	x := r.vec[r.feed] + r.vec[r.tap]
	r.vec[r.feed] = x
	return uint64(x)
}
~~~
`}}

Generating the next number is quite cheap: two subtractions, two conditional adds, two loads, one add, one store.

Unfortunately, because the generator directly returns one slice element from its internal state vector,
reading 607 values from the generator completely exposes all its state.
With those values, you can predict all the future values, by filling in your own `vec`
and then running the algorithm.
You can also recover all the previous values, by running the algorithm backward
(subtracting the tap from the feed and shifting the slice to the left).

As a complete demonstration, here is an [insecure program](/play/p/v0QdGjUAtzC)
generating pseudorandom authentication
tokens along with code that predicts the next token given a sequence of earlier tokens.
As you can see, the Go 1 generator provides no security at all (nor was it meant to).
The quality of the generated numbers also depends on the initial setting of `vec`.

## The PCG Generator

For `math/rand/v2`, we wanted to provide a more modern statistical random generator
and settled on Melissa O'Neill's PCG algorithm, published in 2014 in her paper
“[PCG: A Family of Simple Fast Space-Efficient Statistically Good Algorithms for Random Number Generation](https://www.pcg-random.org/pdf/hmc-cs-2014-0905.pdf)”.
The exhaustive analysis in the paper can make it hard to notice at first glance how utterly trivial the generators are:
PCG is a post-processed 128-bit LCG.

If the state `p.x` were a `uint128` (hypothetically), the code to compute the next value would be:

```go
const (
	pcgM = 0x2360ed051fc65da44385df649fccf645
	pcgA = 0x5851f42d4c957f2d14057b7ef767814f
)

type PCG struct {
	x uint128
}

func (p *PCG) Uint64() uint64 {
	p.x = p.x * pcgM + pcgA
	return scramble(p.x)
}
```

The entire state is a single 128-bit number,
and the update is a 128-bit multiply and add.
In the return statement, the `scramble` function reduces the 128-bit state
down to a 64-bit state.
The original PCG used (again using a hypothetical `uint128` type):

```go
func scramble(x uint128) uint64 {
	return bits.RotateLeft(uint64(x>>64) ^ uint64(x), -int(x>>122))
}
```

This code XORs the two halves of the 128-bit state together
and then rotates the result according to the top six bits of the state.
This version is called PCG-XSL-RR, for “xor shift low, right rotate”.

Based on a [suggestion from O'Neill during proposal discussion](/issue/21835#issuecomment-739065688),
Go's PCG uses a new scramble function based on multiplication,
which mixes the bits more aggressively:

```go
func scramble(x uint128) uint64 {
	hi, lo := uint64(x>>64), uint64(x)
	hi ^= hi >> 32
	hi *= 0xda942042e4dd58b5
	hi ^= hi >> 48
	hi *= lo | 1
}
```

O'Neill calls PCG with this scrambler PCG-DXSM, for “double xorshift multiply.”
Numpy uses this form of PCG as well.

Although PCG uses more computation to generate each value,
it uses significantly less state: two uint64s instead of 607.
It is also much less sensitive to the initial values of that state,
and [it passes many statistical tests that other generators do not](https://www.pcg-random.org/statistical-tests.html).
In many ways it is an ideal statistical generator.

Even so, PCG is not unpredictable.
While the scrambling of bits to prepare the result does not
expose the state directly like in the LCG and Go 1 generators,
[PCG-XSL-RR can still be reversed](https://pdfs.semanticscholar.org/4c5e/4a263d92787850edd011d38521966751a179.pdf),
and it would not be surprising if PCG-DXSM could too.
For secrets, we need something different.

## Cryptographic Randomness

_Cryptographic random numbers_ need to be utterly unpredictable
in practice, even to an observer who knows how they are generated
and has observed any number of previously generated values.
The safety of cryptographic protocols, secret keys, modern commerce,
online privacy, and more all critically depend on access to cryptographic
randomness.

Providing cryptographic randomness is ultimately the job of the
operating system, which can gather true randomness from physical devices—timings
of the mouse, keyboard, disks, and network, and more recently
[electrical noise measured directly by the CPU itself](https://web.archive.org/web/20141230024150/http://www.cryptography.com/public/pdf/Intel_TRNG_Report_20120312.pdf).
Once the operating system has gathered a meaningful
amount of randomness—say, at least 256 bits—it can use cryptographic
hashing or encryption algorithms to stretch that seed into
an arbitrarily long sequence of random numbers.
(In practice the operating system is also constantly gathering and
adding new randomness to the sequence too.)

The exact operating system interfaces have evolved over time.
A decade ago, most systems provided a device file named
`/dev/random` or something similar.
Today, in recognition of how fundamental randomness has become,
operating systems provide a direct system call instead.
(This also allows programs to read randomness even
when cut off from the file system.)
In Go, the [`crypto/rand`](/pkg/crypto/rand/) package abstracts away those details,
providing the same interface on every operating system: [`rand.Read`](/pkg/crypto/rand/#Read).

It would not be practical for `math/rand` to ask the operating system for
randomness each time it needs a `uint64`.
But we can use cryptographic techniques to define an in-process
random generator that improves on LCGs, the Go 1 generator, and even PCG.

## The ChaCha8Rand Generator

Our new generator, which we unimaginatively named ChaCha8Rand for specification purposes
and implemented as `math/rand/v2`'s [`rand.ChaCha8`](/pkg/math/rand/v2/#ChaCha8),
is a lightly modified version of Daniel J. Bernstein's [ChaCha stream cipher](https://cr.yp.to/chacha.html).
ChaCha is widely used in a 20-round form called ChaCha20, including in TLS and SSH.
Jean-Philippe Aumasson's paper “[Too Much Crypto](https://eprint.iacr.org/2019/1492.pdf)”
argues persuasively that the 8-round form ChaCha8 is secure too (and it's roughly 2.5X faster).
We used ChaCha8 as the core of ChaCha8Rand.

Most stream ciphers, including ChaCha8, work by defining a function that is given
a key and a block number and produces a fixed-size block of apparently random data.
The cryptographic standard these aim for (and usually meet) is for this output to be indistinguishable
from actual random data in the absence of some kind of exponentially costly brute force search.
A message is encrypted or decrypted by XOR'ing successive blocks of input data
with successive randomly generated blocks.
To use ChaCha8 as a `rand.Source`,
we use the generated blocks directly instead of XOR'ing them with input data
(this is equivalent to encrypting or decrypting all zeros).

We changed a few details to make ChaCha8Rand more suitable for generating random numbers. Briefly:

 - ChaCha8Rand takes a 32-byte seed, used as the ChaCha8 key.
 - ChaCha8 generates 64-byte blocks, with calculations treating a block as 16 `uint32`s.
   A common implementation is to compute four blocks at a time using [SIMD instructions](https://en.wikipedia.org/wiki/Single_instruction,_multiple_data)
   on 16 vector registers of four `uint32`s each.
   This produces four interleaved blocks that must be unshuffled for XOR'ing with the input data.
   ChaCha8Rand defines that the interleaved blocks are the random data stream,
   removing the cost of the unshuffle.
   (For security purposes, this can be viewed as standard ChaCha8 followed by a reshuffle.)
 - ChaCha8 finishes a block by adding certain values to each `uint32` in the block.
   Half the values are key material and the other half are known constants.
   ChaCha8Rand defines that the known constants are not re-added,
   removing half of the final adds.
   (For security purposes, this can be viewed as standard ChaCha8 followed by subtracting the known constants.)
 - Every 16th generated block, ChaCha8Rand takes the final 32 bytes of the block for itself,
   making them the key for the next 16 blocks.
   This provides a kind of [forward secrecy](https://en.wikipedia.org/wiki/Forward_secrecy):
   if a system is compromised by an attack that
   recovers the entire memory state of the generator, only values generated
   since the last rekeying can be recovered. The past is inaccessible.
   ChaCha8Rand as defined so far must generate 4 blocks at a time,
   but we chose to do this key rotation every 16 blocks to leave open the
   possibility of faster implementations using 256-bit or 512-bit vectors,
   which could generate 8 or 16 blocks at a time.

We wrote and published a [C2SP specification for ChaCha8Rand](https://c2sp.org/chacha8rand),
along with test cases.
This will enable other implementations to share repeatability with the Go implementation
for a given seed.

The Go runtime now maintains a per-core ChaCha8Rand state (300 bytes),
seeded with operating system-supplied cryptographic randomness,
so that random numbers can be generated quickly without any lock contention.
Dedicating 300 bytes per core may sound expensive,
but on a 16-core system, it is about the same as storing a single shared Go 1 generator state (4,872 bytes).
The speed is worth the memory.
This per-core ChaCha8Rand generator is now used in three different places in the Go standard library:

 1. The `math/rand/v2` package functions, such as
   [`rand.Float64`](/pkg/math/rand/v2/#Float64) and
   [`rand.N`](/pkg/math/rand/v2/#N), always use ChaCha8Rand.

 2. The `math/rand` package functions, such as
   [`rand.Float64`](/pkg/math/rand/#Float64) and
   [`rand.Intn`](/pkg/math/rand/#Intn),
   use ChaCha8Rand when
   [`rand.Seed`](/pkg/math/rand/#Seed) has not been called.
   Applying ChaCha8Rand in `math/rand` improves the security of programs
   even before they update to `math/rand/v2`,
   provided they are not calling `rand.Seed`.
   (If `rand.Seed` is called, the implementation is required to fall back to the Go 1 generator for compatibility.)

 3. The runtime chooses the hash seed for each new map
    using ChaCha8Rand instead of a less secure [wyrand-based generator](https://github.com/wangyi-fudan/wyhash)
    it previously used.
    Random seeds are needed because if
    an attacker knows the specific hash function used by a map implementation,
    they can prepare input that drives the map into quadratic behavior
    (see Crosby and Wallach's “[Denial of Service via Algorithmic Complexity Attacks](https://www.usenix.org/conference/12th-usenix-security-symposium/denial-service-algorithmic-complexity-attacks)”).
    Using a per-map seed, instead of one global seed for all maps,
    also avoids [other degenerate behaviors](https://accidentallyquadratic.tumblr.com/post/153545455987/rust-hash-iteration-reinsertion).
    It is not strictly clear that maps need a cryptographically random seed,
    but it's also not clear that they don't. It seemed prudent and was trivial to switch.

Code that needs its own ChaCha8Rand instances can create its own [`rand.ChaCha8`](/pkg/math/rand/v2/#ChaCha8) directly.

## Fixing Security Mistakes

Go aims to help developers write code that is secure by default.
When we observe a common mistake with security consequences,
we look for ways to reduce the risk of that mistake
or eliminate it entirely.
In this case, `math/rand`'s global generator was far too predictable,
leading to serious problems in a variety of contexts.

For example, when Go 1.20 deprecated [`math/rand`’s `Read`](/pkg/math/rand/#Read),
we heard from developers who discovered (thanks to tooling pointing out
use of deprecated functionality) they had been
using it in places where [`crypto/rand`’s `Read`](/pkg/crypto/rand/#Read)
was definitely needed, like generating key material.
Using Go 1.20, that mistake
is a serious security problem that merits a detailed investigation
to understand the damage.
Where were the keys used?
How were the keys exposed?
Were other random outputs exposed that might allow an attacker to derive the keys?
And so on.
Using Go 1.22, that mistake is just a mistake.
It's still better to use `crypto/rand`,
because the operating system kernel can do a better job keeping the random values
secret from various kinds of prying eyes,
the kernel is continually adding new entropy to its generator,
and the kernel has had more scrutiny.
But accidentally using `math/rand` is no longer a security catastrophe.

There are also a variety of use cases that don't seem like “crypto”
but nonetheless need unpredictable randomness.
These cases are made more robust by using ChaCha8Rand instead of the Go 1 generator.

For example, consider generating a
[random UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)).
Since UUIDs are not secret, using `math/rand` might seem fine.
But if `math/rand` has been seeded with the current time,
then running it at the same instant on different computers
will produce the same value, making them not “universally unique”.
This is especially likely on systems where the current time
is only available with millisecond precision.
Even with auto-seeding using OS-provided entropy,
as introduced in Go 1.20,
the Go 1 generator's seed is only a 63-bit integer,
so a program that generates a UUID at startup
can only generate 2⁶³ possible UUIDs and is
likely to see collisions after 2³¹ or so UUIDs.
Using Go 1.22, the new ChaCha8Rand generator
is seeded from 256 bits of entropy and can generate
2²⁵⁶ possible first UUIDs.
It does not need to worry about collisions.

As another example, consider load balancing in a front-end server
that randomly assigns incoming requests to back-end servers.
If an attacker can observe the assignments and knows the
predictable algorithm generating them,
then the attacker could send a stream
of mostly cheap requests but arrange for all the expensive requests
to land on a single back-end server.
This is an unlikely but plausible problem using the Go 1 generator.
Using Go 1.22, it's not a problem at all.

In all these examples, Go 1.22 has eliminated or greatly reduced
security problems.

## Performance

The security benefits of ChaCha8Rand do have a small cost,
but ChaCha8Rand is still in the same ballpark as both the Go 1 generator and PCG.
The following graphs compare the performance of the three generators,
across a variety of hardware, running two operations:
the primitive operation “Uint64,” which returns the next `uint64` in the random stream,
and the higher-level operation “N(1000),” which returns a random value in the range [0, 1000).











The “running 32-bit code” graphs show modern 64-bit x86 chips
executing code built with `GOARCH=386`, meaning they are
running in 32-bit mode.
In that case, the fact that PCG requires 128-bit multiplications
makes it slower than ChaCha8Rand, which only uses 32-bit SIMD arithmetic.
Actual 32-bit systems matter less every year,
but it is still interesting that ChaCha8Rand is faster than PCG
on those systems.

On some systems, “Go 1: Uint64” is faster than “PCG: Uint64”,
but “Go 1: N(1000)” is slower than “PCG: N(1000)”.
This happens because “Go 1: N(1000)” is using `math/rand`'s algorithm for
reducing a random `int64` down to a value in the range [0, 1000),
and that algorithm does two 64-bit integer divide operations.
In contrast, “PCG: N(1000)” and “ChaCha8: N(1000)” use the [faster `math/rand/v2` algorithm](/blog/randv2#problem.rand),
which almost always avoids the divisions.
Removing the 64-bit divisions dominates the algorithm change
for 32-bit execution and on the Ampere.

Overall, ChaCha8Rand is slower than the Go 1 generator,
but it is never more than twice as slow, and on typical servers the
difference is never more than 3ns.
Very few programs will be bottlenecked by this difference,
and many programs will enjoy the improved security.

## Conclusion

Go 1.22 makes your programs more secure without any code changes.
We did this by identifying the common mistake of accidentally using `math/rand`
instead of `crypto/rand` and then strengthening `math/rand`.
This is one small step in Go's ongoing journey to keep programs
safe by default.

These kinds of mistakes are not unique to Go.
For example, the npm `keypair` package tries to generate an RSA key pair
using Web Crypto APIs, but if they're not available, it falls back to JavaScript's `Math.random`.
This is hardly an isolated case,
and the security of our systems cannot depend on developers not making mistakes.
Instead, we hope that eventually all programming languages
will move to cryptographically strong pseudorandom generators
even for “mathematical” randomness,
eliminating this kind of mistake, or at least greatly reducing its blast radius.
Go 1.22's [ChaCha8Rand](https://c2sp.org/chacha8rand) implementation
proves that this approach is competitive with other generators.

--- METRICS ---
- Files Extracted: 57
- Estimated Token Budget: ~59414 tokens
- Recency Window: Active (< 180 days)
- Canonical Reference: https://codewiki.google/github.com/golang/oauth2
