homewritingsreadsmeumi
Tell-tales of a Junior Engineer: On the Topic of OptimizationDaffa | September 3, 2026

Now, we’re accustomed to hearing about “this is small and doesn’t introduce any noticeable difference”, especially from the explanations from AI.

Like the other day, while conversing about the decision on whether or not I should pass the struct to a semaphore channel before spawning the goroutine or inside the goroutine, I was told that “this code is extremely lightweight either way and it'll spawn ~2KB for each goroutine, so for 1000 topics, only ~2MB or RAM would be used, which is negligible”.

I initially overlooked it but later on I thought: if I could save 2MB now why shouldn’t I?

Later I thought that this “tolerance” is now overlooked due to the availability in storage capacity of modern computers. And more often than not, modern engineers, upon dissecting the code and work of engineers of the old days would see highly optimized code due to them spending much of their time optimizing, naturally, due to the limit of resources.

2MB of RAM today is nothing, but 20 years ago it would be the difference between a laggy experience or a smooth one.

Context: the problem I was solving was "unbounded concurrency" when I needed to do repeated network calls to get the protoclass details of a list of Kafka topics at service startup (I know this is inefficient, and I didn't go with this approach in the end) and the solution is a pattern called Bounded Concurrency using a Semaphore. In Go, a semaphore is commonly implemented using a buffered channel with a strict capacity limit (e.g., 10 slots), where we push an empty struct (struct{}{}) to claim an execution slot and pop it out to release one. Placing this semaphore check before spawning the goroutine pauses the loop itself when the channel is full while placing it inside the goroutines allows the loop to still spawn them.