From C# to Golang

…is it worth it?

Davide Migone
Growens Innovation Blog
5 min readMar 31, 2021

--

Every tech company in our ages must face challenging problems to bring its infrastructure and applications up to date. New scaling requirements, code maintainability and evolution are just a few of them. At MailUp we started this evolution journey several years ago, moving from two very big monolithic applications to an ever-growing swarm of microservices and micro frontends.

In this big adventure for the backend applications, we jumped into an even bigger challenge… moving the whole codebase from .Net C# to Golang.
Is it worth it?

5 years ago…

Our web application was entirely written in C#. The services were provided by one huge multilayered web service. The deployments were done manually and everything was hard and prone to errors. So we made the decision to move towards microservices.

The natural prosecution of our ecosystem was to gradually introduce WebAPI spawning the first few new services (a lot of work was done also on CI/CD and infrastructure automation), .Net and C# were an obvious choice because we had to deal with too many new aspects and that was our “safe zone”.

After a few months, the infrastructure complexity grew and carried with it a new requirement, to reduce license costs for our server farm.

Our new goal

Our new goal was to move away from Microsoft servers and reduce costs of the infrastructure, but how?

On the infrastructure side, Linux was the right choice, but how could we handle code migration to the new operative system? The Mono project was out there, but we were not comfortable that it could be stable enough for the company standards. .Net Core was at its very beginning (although promising) and library support was limited. Both solutions still obliged us to carry the whole framework with the application which was not a perfect suite for the microservice architecture we were moving to.

That’s why we started looking out for alternatives and Golang seemed to be shining bright.

Golang pros & cons

The Golang main positive aspects were:

  • compiled language (no JIT compilation)
  • managed memory handling (powerful GC)
  • lack of a runtime framework (everything is bounded in the executable)
  • multiplatform (cross-compile)

Cons were:

  • nobody had ever seen it before
  • we would have liked to be fast-moving

The transition began with some internal courses to let the development team learn the basics of the new language, then, we decided to use it on a new feature not to impact the core system of the application and try and test this new approach.

Did it go well?

We faced two key obstacles: none of us knew anything about Golang before those days and we wanted to move fast.

Last come first, did we go fast? Well, yes and no…

No because:

  • the learning curve was steep, having to deal with years of working with .Net and some old habits took their time to change.
  • the size of the old code base was huge and we are still migrating features to new services at present

Yes because:

  • the language sounds to be more explicit compared to C# and this makes it easier to read and maintain
  • the lack of “exception events” in favor of “error handling” made us feels like being “less prone to mistakes”

Problems we had to face while implementing Golang

Although the language basics were affordable quite easily for most developers, some major constructs and features of the language are still producing some friction, not convincing the development team as a whole.

To ease the transition, we used some key features of Golang very carefully and only where high performance was a “must-have”, relaxing the complexity where some “trade-off” could be applied.

Memory management is the field where we had the most tricky problem to handle.

Golang has a very efficient GC and for most use cases it’s not something that you have to deal with too much, but everything takes a different direction when you have to scale at enterprise-grade.

In that scenario you have to be super careful with some basic tooling that seems “stupid” like slice preallocation and the append construct. Together they can literally eat up all the server memory in a fraction of a millisecond and unfortunately, in our experience, they were the last things we looked at when investigating problems. Every cloud has a silver lining and fixing such kind of problems is quite easy and you can prevent them just by paying a bit of attention.

Other critical issues derived by the way GC works.

As previously said, GC in Golang is very efficient, but when you have to deal with massive workloads investigating memory leaks and the real GC behavior could cause major headaches.

Fortunately, there are some very detailed sources on the internet about the topic so having a good knowledge of the insights is quite “easy”. The profiling tool is another powerful feature that comes with Go and can be a useful ally in finding anomalies in code.

Take aways

So finally, is it worth the pain?

In our case yes, indeed. When we started our journey, .Net Core was not a good choice because it was in its early stages and we didn’t think Mono was suitable to keep our software up and stable.

However, as of today, things are different and .Net Core is battle-tested in many different enterprise solutions, so is it still worth it to move from C# to Golang?

As an architect or a manager,s there are many different aspects you should consider before getting yourself into a major change, but keep an eye on:

  • Do you need superpowers (and performance)? …Golang is the choice
  • What does your development team look like? …if you have long term experienced developers in C# probably keeping them in the comfort zone is more productive, so go for .Net Core.

As a developer:

  • Golang is nice, powerful and definitely a good to know language
  • .Net Core is nice, powerful and definitely a good to know language

Learn both, have a good time and happy coding!!

Nice to read:

References:

--

--