Go 1.15 was released on August 11, 2020. It is not the kind of release that asks for a celebratory rewrite of every service; it is quieter than that. The value sits in compilation, runtime cost, and smaller details that make production Go feel more boring in the best sense.1Note 1Primary release note for Go 1.15.

Release field note

Go 1.15 as a maintenance release.

The interesting parts are not loud. Faster linking, cheaper defers, smaller binaries, and a few standard-library additions make the upgrade feel like housekeeping that pays rent.

This sentence is rendered through the localized text helper, which lets the same MDX component vocabulary carry both English and Chinese essays.

Toolchain improvements.

Linker rewrite.

The most significant change in Go 1.15 is the rewritten linker. The release notes describe faster linking, lower memory use, and a Go implementation that gives future toolchain work a cleaner base.2Note 2Announcement context from the Go team.

A toolchain improvement is successful when the application code does not have to perform for it.

01

Measure the build you already have

Run the same package set before and after the upgrade. Keep the command boring so the result says something about the toolchain, not about a newly invented benchmark.

02

Watch memory while linking

Large services and generated codebases benefit most from the linker rewrite. Compare peak memory and wall time, not just final binary size.

03

Ship behind your normal checks

Go 1.15 is conservative, but toolchain upgrades still deserve CI, integration tests, and a small rollout window.

The migration note I would keep in a repository is short. It records the compiler version, a baseline build time, and the one or two project-level checks that should catch drift.

go version
go test ./...
go test -race ./...
go build -trimpath ./cmd/service

Smaller binaries.

Go 1.15 also improves dead code elimination. Typical binaries are smaller, symbol tables are handled more efficiently, and deployment artifacts get a little easier to move around.

go test ./...
go build -trimpath ./cmd/service
go version

repeatable local check

A small upgrade checklist

Upgrade note without shape

"We upgraded Go. The build is faster. CI is green." This is true, but it is hard to audit six months later.

Upgrade note with shape

"Go 1.14.7 to Go 1.15.15. Link time: 42s to 28s. Binary: 81MB to 76MB. No code changes." This is boring, which is useful.

Link time
The number most teams will feel first when working on large services or generated code.
Memory pressure
The number most likely to matter on CI workers with narrow resource limits.
Artifact size
The quieter win that compounds in container registries, deploy caches, and cold starts.

Runtime performance.

Defer performance.

The defer statement got a practical speedup. In many common cases, Go can use open-coded defers, making cleanup-heavy code less expensive while preserving the shape that humans actually want to read.

func processFile(filename string) error {
    f, err := os.Open(filename)
    if err != nil {
        return err
    }
    defer f.Close()
 
    return process(f)
}
The best runtime improvement is the one that lets ordinary code stay ordinary.

Zhaphar field note

The practical rule is simple:

  1. 01Keep defer where it communicates ownership.
  2. 02Measure hot paths before hand-optimizing.
  3. 03Prefer readable cleanup until a profile proves otherwise.
func BenchmarkDeferClose(b *testing.B) {
    for i := 0; i < b.N; i++ {
        closer := noopCloser{}
        defer closer.Close()
    }
}

a tiny defer benchmark skeleton

Standard library updates.

Embedded timezone data.

The new time/tzdata package allows a program to embed timezone data directly in the binary. That matters for small containers, restricted systems, and deployments where the host filesystem cannot be trusted to provide the same zoneinfo files everywhere.3Note 3Useful when a deployed system does not provide zoneinfo files.

package main
 
import (
    "fmt"
    "time"
    _ "time/tzdata"
)
 
func main() {
    loc, err := time.LoadLocation("Asia/Shanghai")
    if err != nil {
        panic(err)
    }
    fmt.Println(time.Now().In(loc).Format(time.RFC3339))
}

Test temporary directories.

testing.TB.TempDir gives tests a managed temporary directory that is automatically removed when the test finishes. It is a small API, but it removes a surprising amount of cleanup ceremony.

func TestSomething(t *testing.T) {
    dir := t.TempDir()
    path := filepath.Join(dir, "sample.txt")
 
    if err := os.WriteFile(path, []byte("hello"), 0o644); err != nil {
        t.Fatal(err)
    }
}

Use Ctrl + K or / to search for follow-up notes across the site.

  • Use t.TempDir() for filesystem tests.
  • Keep cleanup local to the test instead of sharing global temporary paths.
  • Only test the operating system behavior you actually depend on.

Compatibility notes.

Go 1.15 is intentionally conservative, but conservative does not mean invisible. When I review an upgrade like this, I put the risk in three buckets.

BucketWhat to inspectTypical signal
Toolchainbuild, link, vet, raceCI duration and peak memory
Runtimedefers, allocation-heavy pathsprofile deltas
Environmenttimezone files, containers, testsfailures that only appear outside a laptop

Not necessarily. A quiet release still deserves the same rollout discipline as any other runtime change. Upgrade a representative service first, then move the rest when the behavior is boring.

Build and link performance. It is visible in CI, easy to compare, and does not require a product narrative.

Watch error rates, memory, CPU, startup time, and any tests that depend on filesystem layout or timezones. Most projects will not see drama, but the habit is valuable.

FIG 01
A typographic figure placeholder for a release note that wants one visual pause without importing a low-quality migrated image.

Editorial component sync.

I

Structured component sampler.

The blocks below are intentionally dense. They are here so the article can exercise the full reading system on one page: component headings, badges, prompt boxes, lists, tables, references, copy buttons, and interactive panels.

Stable New block Optional Beta Deprecated

#A short component heading.

They let long technical essays carry reference material, comparisons, prompts, and supporting figures without turning into a separate documentation system.

The class names and component shapes stay aligned, but the colors, spacing, and placeholder media are adapted to the current Zhaphar design tokens.

Code
Use fenced Markdown for highlighted code, or CodeBlock when a caption is needed.
References
Use frontmatter references with inline Footnote markers and a closing References block.
Lists
Plain Markdown lists now render with the v3 list vocabulary.
package main
 
import "fmt"
 
func main() {
fmt.Println("Go 1.15 still rewards simple programs.")
}

go tab panel

Component behavior checks

  • Render the full synchronized component set.
  • Keep copy buttons delegated through GlobalUI.
  • Use the blocks in future essays only when they make the reading flow clearer.
PromptEditorial reviewer
Review this Go upgrade note. Keep the prose calm, identify hidden operational risks, and suggest one measurement that would make the rollout easier to trust.
Go 1.15 release notesPrimary notes for linker, runtime, compiler, and standard library changes. REPOZhaphar on GitHubSource, notes, and future public work. FILERSS feedA lightweight file-style showcase row for syndication and references.

Plain Markdown also participates in the component system:

  • Fenced code uses the editorial code frame.
  • Lists use quiet custom markers.
  • Tables keep their hairline editorial rhythm.
  • Blockquotes are routed into the same quote component as explicit <C>Quote</C> usage.
type UpgradeNote = {
  from: "go1.14";
  to: "go1.15";
  checks: Array<"test" | "build" | "race" | "smoke">;
};
SurfaceRoleDetail
Calloutemphasisleft rule and mono label
Tabsvariantskeyboard-aware interaction
Referencessourcesbidirectional footnote jumps
PromptBoxreusable textcopyable editorial prompt
Galleryvisual pacingtypographic placeholders or real images

Components are not decoration; they are pacing tools for long reading.

Zhaphar

Conclusion.

Go 1.15 is a grounded release: faster linking, lower memory use, cheaper defers, smaller binaries, and a few standard library niceties. The release is worth upgrading to because it lets existing code keep its shape while the platform underneath becomes a little calmer.