Written by Bo Thorsen
2024/9/17
Over the last couple of years I have spent more time doing web based development than Qt and C++. The work has been within many different environments, so I have a pretty good basis for doing comparisons between these.
This blog post is all about web backends, either as backends for a single site or REST-like API backends, the arguments here apply to both of them.
I will take you through the choices I consider when a customer wants us to implement a web based backend. However, there is one argument that I don’t take into account here, but will do with a customer: What experience do your developers already have? If you have a bus load of, say, python devs, then don’t look anywhere else. Here I will give more general thoughts on the matter.
The Contenders
As of today, these are the languages I choose between for a new backend:
- Rust
- Go
- C#
- Python
For the candidates not on the list:
There is definitely an argument for Java on this list, but over the last 10 years or so, I haven’t had a single customer ask about Java. I take this as a clear sign that it’s not used for any new development.
I would never consider Ruby, PHP or some other legacy system for new development, unless the customer forces me to do it. These are dead and should not be a reasonable choice. That doesn’t mean no development can be done with these, because there are very good arguments against replacing sites already running in production for a long time.
If you ask about Javascript based backends, I would ask you to go find another company to do it. I consider Javascript on the frontend a necessary evil, but in the backend there are no acceptable reasons for choosing it. Even you have a busload of Javascript developers, I say – teach them something reasonable!
In the text below, I spend more time on the newer languages, because there is a good chance that the reader will know less of them.
Rust
Rust has been the hot new topic for the last 2 years. I don’t remember ever seeing this much excitement from developers about a new language before. Sure, hype often happens, but it’s usually from less techy people.
After working with Rust quite a lot, I can understand some of it, but must also admit that I don’t get why the level of the hype is this high.
Rust is a pretty nice language with some good and bad points to it. I can definitely appreciate that the compiler can guarantee lifetimes of objects, for example. Especially coming from a C++ background where there can be many issues with memory management.
Other good points are the Option class instead of null pointers, better exception handling than Go, great introspection (see below) and a very nice module based approach to development.
There are some bad points in Rust as well. For example, when there are several pages on stackoverflow describing how to add strings, that points to a clear flaw in the language. Yes, I know they claim it’s all for performance reasons, but I would rather sell a bit of performance for a nicer language. And enums are really unions and too powerful for their own good.
I think Rust code is aesthetically the ugliest new language to look at. The basic syntax is okay, except for all the annoying abbreviations. But when you start doing generics, traits and lifetimes, the code starts looking like modem noise. I’m reminded of why I took an oath in the nineties to never write a single line of Perl in my life.
One place where Rust shines above everything else is cargo and access to external crates. Cargo is the best environment for dependency handling I have ever seen. It shows Go what they should have done instead of their abuse of git repos for dependencies.
Rust is often mentioned for speed. I don’t care about this one, though. If I write something in Rust, Go, C++ or C, it’s fast. (C# and Java are fast too, once things are up and running). Whether one of them is 1% faster or slower than the others is completely irrelevant to me. If you are Cloudflare or Facebook, this may not be the case, but you probably aren’t. It’s fast enough, and that’s all I need.
The main problem with Rust is immaturity of the ecosystem. For example, I just started a subproject to generate PDF documents in the backend, and I have been quite annoyed with how bad the options in this area are. The number of crates available for Rust are few, and those that are there have absurdly bad documentation and no blog reports or YouTube videos about them. This is not the first time I’ve hit that with Rust, and it’s quite common that you need to figure things out yourself. This is one of the few places where Go is doing much better than Rust.
Even with the disadvantages mentioned above, I do believe that Rust is the best choice for a backend right now. If you have never done Rust before, you have a lot of frustration ahead of you, but it’s probably worth it.
Go
I have done several Go based backends that are running in production now. And in some ways I really like it.
Go and Rust solve many of the same problems and I recommend them for many of the same things. The choice between these two is a lot about personal preference, because both are good. But my preference has shifted to Rust over Go, and these are the reasons why:
Cargo makes Rust based development so much more enjoyable. I can see what Go is doing and how this could have been an influence on Cargo, but it’s just done so much better in Rust.
The Rust language is a bit richer and more precise. For example the inability to use RAII in Go just bugs me. Unfortunately both of them has chosen to not do inheritance and proper polymorphism, but Rust just gives a bit more language options that helps solve some problems. Exception handling is just silly in Go, for example.
The environment around Go is better than Rust, though. There is a lot more help online when you do things for the first time. Documentation also seems to be generally better with Go. But I expect this to get better and better for Rust as time goes, leaving one of the best Go arguments weaker and weaker.
One of my biggest beefs with Go (aside from dependency handling) is that it’s difficult to do something slightly different than what is considered the right way. For example, it’s incredibly easy to do JSON conversions to and from structs, but if you don’t like the default behaviour, then you have to do real tricks to go around the problems.
Another big problem in Go is that it’s difficult to see where it goes from the current state. The forces behind it seems to be fairly happy with where it is, and it hasn’t received many real updates over the last couple of years. This does make me a bit worried, as it feels like even 35 year old C++ is evolving faster than 10 year old Go. I don’t know if Go is settled in “Not just good, but good enough” mode, we will see over the next couple of years.
Go is a fine choice for web backends, though. It’s easy to work with and easy to be productive – and definitely easier than Rust. If you do prefer not to use Rust, this would be my second choice.
C# / .NET
This is an odd beast. There are so many things with C# I think are great, but I would still never choose this for a web backend, unless a customer prefers it. When I do C# based backend, I actually enjoy the language and the environment, so I consider it a good choice if you prefer it.
Pros:
- Easier and faster (measured in development time) to produce something useful
- Very rich and mature environment, not just for web backends but for many different types of projects
- Nice language, although it’s missing some things that newer designed languages have
- Great documentation and a lot of help available online
- Blazor looks awesome!
The reason I never have C# as my first choice is that in every field there is another technology that is better.
And even though the language itself is producing fast executables, there is something in the environment that have large negative performance impacts. These can be overcome, but then you suddenly go from a simple system to a harder one. This is most easily seen when you work with the Microsoft admin pages for MS365, it’s so painfully slow, and you would have expected those guys to know how to work around the performance issues.
There is one place where I do recommend C#: If a company has many different types of products, then it’s possible that C# will do all of them well. And in that case it’s a really good choice.
Python
Python has one advantage over the others, and that is that it’s easy to get something up and running. But once you are past that, I consider it a worse choice in every possible way. It is slow (compared to the others), and it’s hard to do an architecture that allows your project to grow for years to come.
We have several Python based projects, and the reason for those is that the customer had Python developers available. I’m not fundamentally against Python, and do think that it’s a pretty nice language.
However, if I don’t have any good reasons to choose Python, then I will only use it as a nicer script language than bash.
So, What’s the Verdict?
Predictably, it really depends.
Even though this blog entry is fairly long, it still only scratches the surface of why you want to go with one over the others. I consider this the starting point of a long discussion, preferably over a beer.
And as I mentioned above, sometimes there are many non-technical reasons for preferring one of them – company policy, focus on a single technology, preference of current developers, etc. Those are not irrelevant reasons, especially when several of these are similarly good choices.
If you only take one thing away from reading all of this, then please let it be this: Javascript has no place in serverspace. Then it will have been worth yours and my time 🙂
In my case, I’ve choose C# initially because it’s more of a “business language”, at least in my country, so the job offers are much higher compared to all these other languages. But I started to really like the way it works like a C++ with better dev env and it’s versatility for cross-platform apps and game development.
I really do think there’s a lot to like about C#. It’s a good language and the tools are pretty decent – much better than C++, worse than Go or Rust. Here in Denmark, there are a lot of companies that use C#. It’s not a bad idea to learn it.
Liked the article. can’t agree with the conclusion in the end “JavaScript has no place in serverspace”… as you said in the beginning its not all about performance especially if you are not in a corporate company… getting to a product / feature faster yet maintaining the ability to move fast is key for most companies on smaller scales. I worked on monday.com where all product teams are full-stack and coding in Typescript both for front (react) and back (node).. I would suggest taking a look at Nest.js framework, which remind me of Java Spring. It brings some structure I was missing. Anyway do agree that if you need something a bit more optimized I would pick Go vs Rust since the tradeoffs between product development and performance is great
One thing I don’t think I mentioned in the article is that I actually quite like typescript. I hate javascript intensely (hate is not too strong a word for it), but typescript is not so bad. It still has a lot of issues with numbers, date/timezones, weird (unusable) classes and so on. But I have done a fair bit of typescript code without feeling the need to chew off my arms 🙂
this guy writes some good sh..t i mean he explains it all though i dind t get how you wouldnt use c# however you forgot to mention that c# ties you toa given stack adn limits you with environments altthough theres kubernetes docker i really want to be as free as python and php and nodjs guys bu guess al have to stick to the stack if you ever want to see how hard it goes…… try to use c# in linux you wil understand why God hid himself up
We actually have a C# based project for one customer. It’s entirely done on Linux, and the developers on it are not unhappy. When I have done C# stuff, I have been on Windows and the customer deployed it on Windows servers (their choice, not mine), so I don’t have any personal experience with C# on other systems.