Hey Gophers,
If a CPU works on four numbers at once, what happens when you give it ten? This week, we'll follow Go's experimental SIMD package through two full batches and the two values left over. You'll see where an ordinary loop still matters, with a small function you can run and check.
First, a security update to ship, a lock that can make its own wait longer, and a chance to influence what the Go team works on next.
Prefer to watch? Join me for a walkthrough of this week's edition (12:35). We open the original articles and work through the SIMD example.

Warm-up Time
1. Go 1.27.3 and 1.26.10: rebuild the binaries you ship
Go security team · October 2026
Updating Go on your laptop won't fix a binary already running in production. These releases block certificate chains through a small set of unsafe intermediate certificates, which help connect a website's certificate to a trusted authority. The Go team recommends upgrading immediately. Pick the patch for your Go branch, then rebuild and redeploy the programs you ship.
2. Why waiting for a lock can make the wait longer
Alex Rios · 16 October 2026
A lock written in a few lines can look cheaper than sync.Mutex. Alex shows what that comparison misses. A spinlock keeps checking whether the lock is free, but the waiter can occupy the execution slot that the holder needs to release it. His experiment makes the scheduler's role visible and explains why spinning needs a budget and an exit. Go's standard mutex already makes a limited choice between spinning and sleeping.
3. Tell the Go team what keeps getting in your way
Cameron Balahan · Go blog · 21 October
The 2026 Go Developer Survey is open until 3 November. It takes about 10–20 minutes, and every question is optional. The announcement connects earlier feedback about learning idiomatic Go to changes in go fix. If you have a recurring frustration with Go's tools, testing or workflow, this is a concrete way to put it in front of the team planning the next year's work.

Tool Time
🛠️ GoReleaser 2.19: choose your compression tradeoff
22 October
GoReleaser builds and packages your releases. Version 2.19 lets you tune Zstandard compression: a larger window can find repeated data farther apart in an archive, at the cost of more memory and time. The release note shows the settings, and leaving them out keeps the existing behaviour. There's also one fewer build dependency for Nix packages: GoReleaser now calculates the required hash itself.
🧪 TinyGo 0.43: bring more of your tests with you
9 October · release catch-up
Trying TinyGo for a microcontroller or WebAssembly target can mean discovering that a test feature you rely on is missing. Version 0.43 adds parallel tests and testing/synctest, closing two of those gaps. The release notes also cover runtime and reflection changes. TinyGo still has its own compiler and runtime, so check support for your packages and target before moving an existing project.

Deep Dive
What happens to the last two readings?
Suppose a sensor gives us ten readings, and a calibration step needs to double each one. A normal loop handles one value at a time. SIMD, short for Single Instruction, Multiple Data, lets the CPU apply the same operation to several values together.
Jesús Espino's new walkthrough explains the registers and operations behind this. Let's try a smaller example with Go 1.27's experimental, portable simd package.
A vector holds a group of values. Each position is called a lane. On the arm64 machine used for this example, a Float32s vector holds four readings. We ask Len() for that number because another machine can use a different width.
For our ten readings, the work looks like this:
Step | Readings | After multiplying by 2 |
|---|---|---|
First full batch | 1, 2, 3, 4 | 2, 4, 6, 8 |
Second full batch | 5, 6, 7, 8 | 10, 12, 14, 16 |
Remaining values | 9, 10 | 18, 20 |
The last row is the part a batch loop can miss. There aren't four values left, so we finish those two with an ordinary loop.
func scale(samples []float32, gain float32) {
factors := simd.BroadcastFloat32s(gain)
width := factors.Len()
i := 0
for ; i+width <= len(samples); i += width {
values := simd.LoadFloat32s(samples[i:])
values.Mul(factors).Store(samples[i:])
}
for ; i < len(samples); i++ {
samples[i] *= gain
}
}BroadcastFloat32s puts the same multiplier in every lane. The first loop loads a full group, multiplies each reading by its matching multiplier, then writes the results back into the slice. Its condition checks that a complete group is available before loading it.
When that loop stops, i points at the first unfinished value. The second loop continues from there. It also handles a slice shorter than one vector: the first loop does nothing, and the ordinary loop handles everything.
To try it, add import "simd" to your program and call scale(samples, 2). Build with Go 1.27.3 and the experiment enabled:
GOEXPERIMENT=simd go run .Starting with []float32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} produced:
[2 4 6 8 10 12 14 16 18 20]The example matches an ordinary loop for empty slices, full batches, and lengths just beyond a batch boundary. This checks the result; it isn't a speed benchmark. Ten readings are here to make the work visible. Measure with your real data before replacing a simple loop, and remember that this API is still experimental.
Watch: a conversation with the Go team
Panel with the Go Team, GopherCon Europe 2026
Published 13 October 2026 · 30 minutes
Jonathan Amsterdam and Roland Shoemaker join Bill Kennedy for questions about Go's tools, security and direction. Use the recording's chapters to jump to the team's priorities or how to contribute. It pairs with the survey above: hear the discussion, then add the problems you would like the team to work on.
Where would you try the batch example: sensor data, image processing, or something else? Hit reply and tell me what you work with.
Thanks for reading,
Moein


