Real time? What do you mean? • The Applied Go Weekly Newsletter 2024-09-29
Your weekly source of Go news, tips, and projects
"Go has garbage collection and therefore can never be considered a high-speed language." Um, wrong. Speed is relative, and Go is orders of magnitudes faster than dynamically typed, interpreted scripting languages, so the garbage collector certainly isn't a major factor in application speed. Moreover, the GC has improved tremendously over the years and can be considered one of the most efficient GCs around.
Besides that, talking about "speed" isn't going anywhere. What's speed, exactly? "Being able to respond to events in real time" might be one answer. But then, what does "in real time" mean? If you look closer, "real time" can be many different things. In the Spotlight section, I inspect the various aspects of "real time" and how Go can be optimized for (certain forms of) real-time tasks.
But this doesn't mean you can simply skip the Featured Articles and Podcast sections.
Featured articles
Register allocation in the Go compiler | Red Hat Developer
You won't need this knowledge for writing great Go apps, but if compiler construction is your cup of tea, then Vladimir Makarov has some brain food for you.
Go Singleflight Melts in Your Code, Not in Your DB
The singleflight
package suppresses duplicate requests for the same data, to reduce the number of calls to costly operations (like a database query).
Podcast corner
Ardan Labs: Go Team, Law, and Business with Cameron Balahan
Cameron Balahan, the Product Lead for Go, is this episode's guest. Follow the path through his life, from first memory of a computer to his time as a Go team member.
Cup o' Go: 🐋🐋 Two Orcas swimming in a pod(cast); FDs, Aliases, and more with Maxim Vovshin
Maxim Vovshin from Orca Security joins Shay in this episode, discussing Go proposals and blog posts.
Go Time: "Founder Mode" at work when you're not a founder
Founder Mode, as per this essay by Paul Graham, distinguishes itself from Manager Mode by the direct involvement of the CEO. Read: The CEO doesn't delegate control to managers. Do you have to bother about Founder Mode if you're not a founder? Johnny, Kris, and Angelica discuss the essay through the eyes of developers.
Spotlight: Go for real-time applications
Some say Go isn't suitable for real-time applications because Go's garbage collector gets in the way of delivering real-time responses. Is this true?
A seasoned engineer answers this question with the seasoned engineer's standard answer:
It depends.
And then the seasoned engineer will ask back:
What kind of "real-time" are you talking about?
What is "real-time"?
The term "real-time application" means different things to different people.
- Some expect zero latency.
- Some need a form of processing load synchronously.
- Some want a steady stream of information with no pause.
- And some require that a certain operation must occur within a specified deadline.
The last case needs a closer look. How long is this deadline? Are we talking about milliseconds? Seconds? Or even hours or days? (These questions make clear that saying "real-time" does not necessarily mean "superfast".)
Then we have to distinguish between three different levels of "real-time":
- Soft real-time operations may miss a deadline, but the result remains useful.
- Firm real-time operations may occasionally miss a deadline, but not too many, or the quality of service degrades.
- Hard real-time operations must meet the deadline or the service fails completely.
Obviously, we don't need to talk about soft real-time systems with deadlines of one day. But what about timings where garbage collection activities might get in the way?
Go's garbage collector
Go's garbage collector cleans up unused memory in batches. Every cleanup cycle includes a brief stop-the-world pause when the GC transitions between two phases, and increased CPU load while the GC works concurrently in the mark or the sweep phase. In summary, each cycle delays the rest of the application. The garbage collector has a few knobs to turn for fine-tuning its behavior, but a certain delay is unavoidable.
For operations with a hard deadline in the milliseconds range, this delay could already result in missing a deadline. Go certainly isn't the right choice for this kind of high-speed, short-deadline applications. Prepare to enter the space of tedious manual memory management with GC-less languages. For softer requirements, however, Go may actually be a good choice.
Moreover, the border between suitable and not suitable is not fixed. It can be moved by reducing the number of allocations in the hot path of the application, even down to zero allocations.
Zero-allocation Go
If you don't want the garbage collector to get in the way, ensure it has nothing to collect. Go code can be designed for low- or zero-allocation with a few techniques, including the following:
- Re-use slices, arrays, and buffers. For example, declare a slice outside the hot path and pre-allocate the maximum capacity needed by the app. Inside the hot path, re-use the slice instead of throwing it away and creating a new one.
- Use pass-by-value where possible. If you pass an object to a function by value, the function call only needs to use memory on the stack. If you pass a pointer to a function, the object the pointer refers to might "escape to the heap" and create memory that needs to be garbage-collected. The same happens if a function creates a new object and returns a pointer to it. So do not use pointers "for performance reason" but only if the application logic absolutely requires the use of a pointer.
- Avoid function literals as they can escape to the heap in certain situations.
- Use
sync.Pool
. Resources, especially external ones, are expensive to instantiate, not only in terms of memory consumption. Pooling them makes them re-usable, even across goroutines. - Use the
unique
package for eliminating duplicate data. Theunique
package stores only one copy of a value in memory. If the application wants to store the same value again,unique
creates a reference to the unique copy instead. This technique not only reduces allocations and memory usage but also enables the GC to clean up unique data in a single cycle. - Be aware of hidden pointers. For example, slices and interfaces contain an internal pointer. And
time.Time
contains a pointer to location information. All these may cause heap allocations.
How to determine allocation
You shouldn't apply the above techniques blindly. A few tests and measurements help reveal memory usage and allocations.
- Measure memory allocations with
go test -bench .
- See which objects escape to the heap:
go build -gcflags '-m'
(orgo build -gcflags=-m=3
for more contextual information) - Create a CPU profile and look for GC activity in the profile, such as
runtime.gcBgMarkWorker
,runtime.mallocgc
, orruntime.gcAssistAlloc
. - If CPU costs turn out to be significant, create a memory profile and inspect the profile's
alloc_space
view to identify allocation hot spots.
The above tools and techniques are a good start into writing real-time applications in Go. The Guide to the Go Garbage Collector is my recommended read for digging deeper into this topic.
When do you write your first real-time Go app? (Don't say, "it depends.")
Quote of the Week: How simple
I think the reason I love writing websites in Go so much is how simple it is to use, I can just
apt-get install golang-go
or whatever and everything just works,go build
will give me a binary that I can immediately copy to a server and run in production if I wantI work on a lot of small projects and being able to spend ~0 time setting up my development environment is worth a lot to me.
More articles, videos, talks
Numscript - Formance
Rule #1 for financial calculations: Never. Use. Floating-Point Numbers. Numscript uses a custom type with big.Int
under the hood. Besides that, it's a comprehensive domain-specific language for modeling financial transactions, from simple to complex ones.
Developing a go bot embedding ichiban Prolog
Do you know Prolog? Or should I say, do you remember Prolog? This language was once popular in AI research, when the idea of AI was that of a superintelligence capable of precise logical reasoning about complex facts and interrelations. (Today, our notion of AI has changed quite much...)
But Prolog is still a great choice for building rule-based bots, as Roger Sen demonstrated in this article.
Go and my realization about what I'll call the 'Promises' pattern
Modeling promises with Go's concurrency primitives is not so straightforward as it might seem.
Projects
Libraries
GitHub - leomorpho/GoShip: Opinionated Go/HTMX boilerplate with payments, emails, auth, notifications and more!⛵️
Sure—we Gophers like to build our apps without frameworks and as few dependencies as possible. But when you need to quickly bring an app from zero to launch, a boilerplate like GoShip can be a life saver.
GitHub - luikyv/go-oidc: A configurable OpenID Provider built in Go.
This OpenID library implements OpenID Connect Corea nd Discovery, as well as a number of OAuth RFCs.
htmgo: build simple and scalable systems with go + htmx
Write HTML in Go, with support for HTMX and TailwindCSS.
GitHub - Tochemey/goakt: [Go] Fast and Distributed Actor framework using protocol buffers as message for Golang
An actor library for Go, inspired by Akka.
Tools and applications
TXTD - Fast web pages and notes for everybody
Publishing on the web cannot get any simpler than that.
GitHub - piqoni/cast-text: A zero latency, easy-to-use full-text news terminal reader.
A (single-feed) RSS reader for the terminal.
GitHub - onurhanak/AletheiaDesktop: Aletheia is a Library Genesis client that supports searching, downloading, bookmarking, converting and emailing books.
A Fyne-based desktop client for Library Genesis, a project that describes itself as "a community aiming at collecting and cataloging items descriptions for the most part of scientific, scientific and technical directions, as well as file metadata."
GitHub - absolutelightning/treds: Sorted Data Structure Server
Like Redis but faster. And with a few improvements. (But neither API- nor command-compatible. Hence it's not a drop-in replacement.)
GitHub - dx314/go2type: A Go to TypeScript API client generator.
If you want to attach a TypeScript-based frontend to your Go service, save some work by letting go2type
generate TS types and queries from the backend code.
GitHub - dlvhdr/diffnav: A git diff pager based on delta but with a file tree, à la GitHub.
Reclaim control over your multi-file Git diffs, with this convenient TUI app.
Completely unrelated to Go
Notes on building event-driven systems
When microservice conglomerates burst into uncontrolled complexity, an even-driven architecture can bring back sanity (or prevent unnecessary complexity in the first place).
TIL: Building llamafiles from Llama 3.2 GGUFs
Tiny LLMs become more powerful with every release. Markus "Maragu" Wüstenberg runs a tiny 1B LLama 3.2 model on his machine and discovered that it can return useful answers to questions about SQLite. The model even runs quite well on a Raspberry Pi 5.
Happy coding! ʕ◔ϖ◔ʔ
Questions or feedback? Drop me a line. I'd love to hear from you.
Best from Munich, Christoph
Not a subscriber yet?
If you read this newsletter issue online, or if someone forwarded the newsletter to you, subscribe for regular updates to get every new issue earlier than the online version, and more reliable than an occasional forwarding.
Find the subscription form at the end of this page.
How I can help
If you're looking for more useful content around Go, here are some ways I can help you become a better Gopher (or a Gopher at all):
On AppliedGo.net, I blog about Go projects, algorithms and data structures in Go, and other fun stuff.
Or visit the AppliedGo.com blog and learn about language specifics, Go updates, and programming-related stuff.
My AppliedGo YouTube channel hosts quick tip and crash course videos that help you get more productive and creative with Go.
Enroll in my Go course for developers that stands out for its intense use of animated graphics for explaining abstract concepts in an intuitive way. Numerous short and concise lectures allow you to schedule your learning flow as you like.
Christoph Berger IT Products and Services
Dachauer Straße 29
Bergkirchen
Germany