Why Valoreo decided to use Golang
The classical conundrum of any startup… Which language should we use? What requirements do we have? It is clear there is no one-size-fits-all answer to this problem. Depending on the problem area, the answer probably varies. Also having the best language doesn’t guarantee the best outcome since it also depends on how it is used… But following along, nowadays there are many great contenders:
- Rust
- Go
- Python
- Ruby
- NodeJS / Typescript
- Java / Kotlin / Scala
- C++
Note: We discarded all .Net related languages as we decided not to use Microsoft systems in general.
For Valoreo specifically, the needs are more backend related. While there are a few frontends to tend to, there’s more backend work of complicated multi-way integrations between SaaS third-parties + legacy systems.
To be able to narrow down our decision, we established a series of requirements:
- Learning curve: Language should not be that hard to learn
- Available pool of developers: Language should not be that big of a barrier to hire new developers to help out.
- Popularity of the language: Not because we wanted to be part of the latest trend, but more about the number of stackoverflow answers and number of libraries for the language
- Performance and web framework scalability / adaptability: The chosen language should be performant, scalable and adaptable for a wide variety of tasks. For example the same web server framework should be great at serving lots of small requests vs few but data heavy requests.
- Code legibility: We believe that readability of code depends greatly on the chosen language. This was a critical point, as growing code on complicated business logic projects tends to be tough to ramp-up on. The more we can do to make it easier to read the better.
- CI/CD overhead: Some languages need more work to get a decent CI/CD pipeline going than others. While not a huge concern, it was also something to look out for.
- Testing: Testing should not take longer than twice the time it takes to write the implementation!
With these in mind we proceeded to evaluate the different contenders:
Learning curve
Python, Ruby and maybe JS/TS are the winners here. Learning these languages is a breeze and it’s easy to have a new joiner ramped up in weeks. Rust and C++are at the other end of the spectrum being hard to learn and needing to read-up on memory management and pointer / Box handling.
Available pool of developers
This one is somewhat correlated with language popularity. In Mexico particularly there has been a surge of Python developers while in the past Java (maybe still today?) was taught in most universities. Go, Rust, Scala, Kotlin are probably the lesser known languages across the dev community.
Popularity of the language
We went with stackoverflow dev survey. Because our analysis was mainly about backend languages, we heavily discounted JS and TS. Python, Java, C++, Go, Kotlin, Ruby, Rust in that order. Should mention that even if C++ and Java are super popular, the available tooling is bad, compile times are long, dealing with dependencies is a headache etc.
Performance and web framework scalability / adaptability
Performance is not a difficult question to answer. Rust, C++, Go, JVM langs, Python, Ruby, JS /TS in that order. However web framework scalability and adaptability is tougher since each language has a plethora of options. For our intents and purposes we decided to evaluate the following:
- C++ → Drogon
- Rust → Rocket
- Go → Gin-Gonic
- Java → Spring Boot
- Python → Django / FastAPI
- Ruby → Ruby on Rails
- JS / TS → ExpressJS
We honestly did not invest all the time to evaluate each one. We rather anecdotically shared opinions on each one. This was really subjective but at least time efficient.
Drogon again tooling, compile time, dependency management and IDE friendliness rank really low (although I personally really like C++).
Rocket was unknown to everyone unfortunately.
Gin-Gonic was great in everyone’s mind with the caveat of Go’s generics and difficulty leading with ill-formed JSONs (think arrays containing different data types).
Spring Boot was an upgrade on traditional Java, but still lacks good dependency management. For some reason everyone agreed that every App written in Java for desktop is super unresponsive.
Django / FastAPI great frameworks. They do get a bit hairy when plugging Gunicorn + Nginx or the server of choice. Calibrating workers and threads, and using asyncio is not very easy to setup.
Ruby on Rails great framework as well. No fans of RoR mindset of magically doing things as opposed to being deliberate of how things happen.
ExpressJS had some experiences where at scale the single process looping threads is not the best. Great for websockets, but not our choice for the rest of usecases.
Code Legibility
Here there are actually few languages where we could be sure that the output would be great. Yes, with enough policing then every language can be super legible. However it was agreed that policing was not top-of-mind but rather a laissez faire approach would be used. In this regard Go and Rust ranked at the top since without a lot of strict code reviewing, these can still create standard and legible code. Java is also not that bad, however the huge boilerplate needed for it does decrease legibility.
CI/CD overhead
Overall Python, Ruby, Go and Rust are easy to setup. Java, C++ and Javascript ranked at the bottom in this regard mostly because of the tooling and dependency management solutions available.
Testing
Testing was found to be great in Go, Java and Rust. On the other hand C++, Javascript and Python ranked at the bottom. Yes, these have testing libraries. However it is either not super natively integrated to the dev tools, or the workarounds (C++/GUnit I’m looking at you) are not good or easy to setup.
Conclusion
After all these considerations Go ranked at the top for the shear scalability, flexibility, performance, tooling and legibility. It is not the most popular nor there is a big pool of coders out there for it. However given the variables, we found that Golang was the best given our optimization function.