This debate just never dies. Every time we kick off a new project, someone throws the “Which backend language should we use?” grenade into the group chat and logs off. Classic.

So we decided to stop arguing and actually build with all three—Go, Python, and NodeJS. And I don’t mean hello-world APIs or todo apps. We built proper stuff. Background services, APIs that talk to Postgres and Redis, and even a WebSocket-based pub-sub system. Some of it for internal use, some real production code.

Starting with Go

Go is boring in the best way possible. It’s the closest thing to writing backend infrastructure that just works. The language is strict. The compiler is opinionated. And the standard tooling feels like it was written by people who actually built servers for a living.

Go doesn’t try to be clever. You’ll write more lines of code, but you’ll also sleep better knowing that your app won’t randomly choke under load.

What worked for us:

  • Fast compilation and fast runtime. Feels like C without footguns.
  • Goroutines and channels make concurrency less terrifying.
  • We could ship a single binary, copy it to the server, and it ran. No VM, no venv, no node_modules.

What made us roll our eyes:

  • Error handling is repetitive. There’s a lot of if err != nil everywhere.
  • Generic support is new and sometimes awkward.
  • Some libraries are barebones. Expect to DIY a bit more.

Go shines when you care about performance and reliability. But yeah, it’s a bit stiff compared to the others.

Moving to Python

Python feels like cheating, especially after Go. You can knock out features way faster. Django, Flask, FastAPI—there’s a framework for every mood.

Where it won:

  • Syntax is clean. You can read old code and still understand it.
  • Tons of libraries. You almost never need to reinvent the wheel.
  • FastAPI is a serious contender now. Async support is real and very usable.

Where it lost:

  • Python’s performance is just okay. You won’t notice for small projects, but at scale it starts to show.
  • Typing is optional and inconsistent. Type hints help, but they aren’t enforced unless you go out of your way.
  • The GIL limits how much true concurrency you get with threads.

We still love Python, especially for quick experiments and data-centric stuff. But we wouldn’t throw it at a high-performance pub-sub system.

And then there’s NodeJS

JavaScript on the backend used to sound like a bad joke. Now it’s kind of hard to ignore. Node is fast when it comes to handling I/O. It’s not CPU-efficient like Go, but it’s great at juggling hundreds of simultaneous API calls without falling over.

And if you’re doing anything with WebSockets or real-time updates, Node still feels like the most natural fit.

Why it was fun:

  • async/await makes async logic pretty readable now.
  • npm has everything. You want a Redis wrapper with TypeScript support and native retry logic? Done.
  • Using the same language across frontend and backend is weirdly satisfying.

Why it wasn’t all roses:

  • There’s too much choice. You Google “best Node framework” and find 15 with comparable stars and a Medium article defending each one.
  • Some packages are abandoned. You’ll find something great, only to discover the last commit was in 2018.
  • TypeScript helps a lot, but adds another layer of setup and tooling to care about.

The biggest upside of Node is that it handles real-time stuff beautifully. We built a WebSocket server with Redis pub-sub in a few days and it ran surprisingly well even under traffic spikes. If your app is chat-heavy, needs instant updates, or is all about event-driven workflows, Node is honestly hard to beat.


So, which one should you use?

  • Go is for performance, scale, and long-term sanity. Use it for microservices, APIs that need speed, and anything you’d write in Java if you had to.
  • Python is for speed of development and readability. Great for internal tools, dashboards, ML backends, and glue code.
  • NodeJS is for real-time services, or when you already have JavaScript talent on the team.

We didn’t pick a winner because there isn’t one. We use all three—Go for our core services, Python for quick tools and automation, and Node for things like our internal chat layer and dashboard push updates.

Use what your team is comfortable with, what the problem actually needs, and what you’ll still enjoy working with a year from now. Shipping beats debating.

If you’ve had a different experience with these, or landed on something else entirely like Rust or Elixir, we’d love to hear how that’s going too 🙂

Ashish Saxena Profile Picture
Ashish Saxena

Clearing up the bushes on the road less travelled. Loves driving, cold coffee and simulators.