Why Did Go's Map Get Slower? Let's See How Go 1.25 Plans to Fix It

This article explains why your program might have gotten slower using maps in Go 1.24, and how the Go team plans to fix this issue.

 

This article explains why your program might have gotten slower using maps in Go 1.24, and how the Go team plans to fix this issue.

The feature in Go 1.24 that excited me most was SwissMap. Previously, some unofficial implementations showed up to 50% performance improvements in certain scenarios. The official implementation also provided noticeable gains. You can find more details in my earlier articles:

SwissTable: A High-Performance Hash Table Implementation

Swiss Map in Go 1.24: Compatibility, Extendible Hashing, and Legacy Issues

However, you might have noticed that SwissMap in Go 1.24 doesn’t perform as expected and might even slow down your programs, especially with large maps. This isn’t your imagination—it’s a real issue.
Pasted image 20250520225126
https://x.com/valyala/status/1879988053076504761

The issue has been documented in Issue #70835, and the developers are actively working to address it.

What’s the Problem?

Go’s maps in the latest version use a Swiss Table structure, which is very fast for small maps and highly concurrent scenarios. However, performance degrades significantly when maps become large and data isn’t cached by the CPU (so-called “cold” data).

Why does this happen?

Because SwissMap has a relatively complex internal structure, it organizes data in multiple layers:

  1. A header structure for the map.
  2. A directory pointing to a list of table pointers.
  3. Each table contains control information, keys, and values.

When you look up a key, you might encounter 4 to 6 memory jumps, each potentially resulting in a cache miss. This causes the CPU to frequently fetch data from slower main memory, significantly reducing speed.

Large projects like Prometheus noticed this issue clearly after upgrading to Go 1.24, where CPU usage increased dramatically. Upon investigation, it turned out to be due to slower map lookups.

How Was It Discovered?

Test cases didn’t detect this issue but instead surfaced in real-world scenarios:

  • Using huge maps (several megabytes in size).
  • Frequent reads from the map.
  • Data was not cached in the CPU’s fast cache.

Michael Pratt from the Go team conducted extensive testing to identify the cause of map access slowdown and detailed his findings in Issue #70835.

How Will It Be Fixed?

To make maps faster, the Go team plans several key changes:

  • Simplify directory structure: Replace pointer lists with direct structure storage, reducing one memory jump.
  • Compact control information: Organize control data more densely to enable more effortless CPU loading.
  • Separate keys and values: Change layout to “key-key-key + value-value-value” for optimized memory access.
  • Align control bytes: Align control information to CPU cache lines to minimize cache misses.

These changes are quite challenging since they impact Go’s runtime core:

  • Garbage collection must continue to work correctly.
  • Map resizing logic needs updating.
  • Performance for small maps must remain unaffected.

Where Can You Follow the Discussion?

This issue is actively discussed and tracked. You can find more details in Issue #70835. The Go Release Dashboard has already marked this issue for resolution in Go 1.25. Additionally, Issue #71368 discusses another related memory layout issue.

Conclusion

The Go team consistently strives to enhance the language’s speed and reliability. SwissMap is a significant improvement, but it has also brought new challenges, such as the recent performance degradation for cold caches.

Issue #70835 demonstrates how Go continuously improves through community feedback. Thanks to open-source projects like Prometheus, their reports help make Go better.

If all goes well, Go 1.25 will restore the balance between speed and stability.

Let’s look forward to it together!

Licensed under CC BY-NC-SA 4.0
Last updated on May 20, 2025 22:22 CST
Built with Hugo
Theme Stack designed by Jimmy