A founder asked me to settle an argument. Their CTO wanted Go for "performance", a contractor wanted Django because it would be "twice as fast to build", and they wanted me to say who was right.
I asked what the product did. It was a B2B dashboard with maybe two hundred users, talking to a Postgres database and three third-party APIs. At that shape, all three options are fast enough by an enormous margin, and the entire performance argument was about a bottleneck that did not exist. What actually mattered was that their two existing engineers both wrote JavaScript.
Almost every framework argument is like this — conducted in terms of benchmarks when the real variables are the team, the problem shape, and what you will still be able to hire for in three years.
The Performance Question, Settled
Let me deal with this first because it dominates the conversation and deserves the least of it.
For a typical API request — parse, authenticate, query the database, serialise, respond — the vast majority of the time is spent waiting on the database and the network. The language's share of that is usually single-digit milliseconds.
A rough sense of where they differ:
Go is genuinely faster at CPU work and uses less memory. Real goroutine concurrency, so CPU-heavy work does not block everything else. Fast startup, which matters for serverless.
Node is excellent at I/O concurrency, which is what most APIs do. Falls over on CPU-bound work because a single thread serves every request — one 300ms parse blocks the whole process.
Python/Django is the slowest of the three per request, and for the overwhelming majority of applications this is still irrelevant next to the database.
The honest summary: if your bottleneck is the database — and it nearly always is — swapping frameworks changes very little. If you have genuine CPU-bound work, that is a real reason to choose Go, or to move that specific work out of Node rather than rewriting everything.
Node: Pick It for the Shared Language
The strongest argument for Node is rarely stated as the main one: your frontend is already JavaScript.
One language across the stack means shared types, shared validation schemas, shared business logic in a package both sides import. When a field changes shape, the compiler tells you about the mobile screen someone forgot. That coordination benefit is worth more on most teams than any runtime difference.
Add NestJS if the project is more than a handful of endpoints. Express gives you no structure, and a large Express codebase becomes whatever each developer felt like that week. NestJS brings modules, dependency injection and conventions — more ceremony up front, considerably less archaeology later.
Where Node genuinely struggles: heavy computation, and the ecosystem's dependency sprawl. A modest project pulling in eight hundred transitive packages is a supply chain surface, and it needs actual attention rather than a shrug.
Django: Pick It for What Comes Free
Django's advantage is not the language. It is that a large amount of what you were about to build already exists and is battle-tested.
The admin interface alone is worth choosing it for in some projects. If your product needs internal staff to manage records — a marketplace, an internal tool, anything with operational staff — Django gives you a real admin panel in an afternoon that would take weeks to build well. I have seen teams pick Django for that reason alone and be right.
You also get authentication, permissions, an ORM with genuinely good migrations, forms, and an established way to structure things. The framework has opinions, and for a small team those opinions substitute for decisions you would otherwise argue about.
And if the product does anything with data science or machine learning, being in the Python ecosystem removes a whole category of integration work.
Where it struggles: high-concurrency workloads and real-time features. Async Django exists and is improving, and the ecosystem around it is still less mature than the synchronous path.
Go: Pick It for Operational Simplicity
The reason I would choose Go is not speed. It is that a Go service compiles to a single static binary with no runtime to install, starts in milliseconds, and uses a predictable amount of memory.
That matters for infrastructure components, CLI tools, high-throughput services, and anything where you are running many instances and paying per megabyte. It is also a genuinely small language — a new team member can be productive in it quickly, because there is not much to learn.
The costs are real. You write more code for the same feature — explicit error handling on every call, less magic, thinner standard framework support. There is no Django admin. There is no equivalent of npm's breadth. Development is slower, deliberately, and that trade is right for some projects and wrong for most early-stage products still working out what they are.
The Questions That Actually Decide It
In the order I would ask them:
What does your team already know? This dominates everything else. A team productive in one stack will out-ship the same team learning a "better" one for at least six months, and the learning cost is paid on every ticket, not once.
What can you hire for, locally? Not globally — in your actual market, at your actual budget. A stack with a thin local talent pool is a constraint on the company, not just the codebase.
Does the product need an admin interface? If yes, Django is doing real work for you that the others are not.
Is your frontend JavaScript? If yes, and the team is small, sharing the language has a compounding benefit.
Do you have genuine CPU-bound work? Video processing, heavy computation, cryptography at volume. If yes, Go — or keep your main stack and move that one workload.
How long must this run? A two-year contract and a ten-year platform justify different levels of care about ecosystem stability.
What I Told the Founder
Node with NestJS, because both their engineers wrote JavaScript, their frontend was React, and their product had no CPU-bound work anywhere in it.
Not because Node is better. Because for a two-person team building a dashboard, the ability to share types between frontend and backend and to have either engineer work on either side was worth far more than any benchmark on the table.
The framework arguments that go on for weeks are almost always about the wrong variable. The ones that matter — who is on the team, what the product actually does, who you can hire — usually resolve it in about ten minutes.



