Back to articles
Performance
4 min
January 4, 2026
Translated with AI

Node.js vs Go: Complete Benchmark with NestJS, Gin and PostgreSQL

I tested 800 simultaneous connections, database operations, CPU-bound tasks, and more. The numbers don't lie.

Every discussion about "which language is better" usually ends in opinions. I decided to put an end to the guesswork by creating two identical APIs, one in NestJS (Node.js) and one in Gin (Go), using PostgreSQL, and running real production benchmarks.


The Setup

  • Hardware: MacBook Pro M1, 16GB RAM
  • Database: PostgreSQL 16 (Docker)
  • Tool: wrk (HTTP benchmark)

Both APIs implement the following requirements:

  • CPU Endpoints (JSON, hash, fibonacci)
  • Database Endpoints (CRUD, aggregation)
  • Connection pool with 20 max connections

The Results

πŸš€ Pure Performance (No Database)

TestNestJSGinGo Advantage
Health Check16k req/s93k req/s5.8x
JSON (100 obj)4.3k req/s28k req/s6.4x
Fibonacci (n=30)96 req/s1.8k req/s19x
Bcrypt Hash64 req/s91 req/s1.4x

Highlights:

  • Go is 19x faster in pure CPU-bound processing.
  • In bcrypt, the difference drops to 1.4x, as Node uses C bindings.

πŸ”₯ Stress Test (800 connections, 45 seconds)

MetricNestJSGin
Requests/sec16k90k
p99 Latency63ms15ms
Timeouts4810

The most critical data point: NestJS exhibited 481 timeouts, while Gin had zero. In production, timeouts represent clients receiving direct errors.

πŸ—„οΈ With PostgreSQL (200 connections)

OperationNestJSGinGo Advantage
SELECT 1 row7.7k req/s18.7k req/s2.4x
SELECT 100 rows4.7k req/s9.3k req/s2.0x
Aggregation7.7k req/s13.4k req/s1.7x

Insight: The difference dropped from a 5-19x scale to a range between 1.7x and 2.4x. This indicates that the database becomes the system's main bottleneck.

The p99 latency, however, remains very different:

  • List 100 rows: NestJS 158ms vs Gin 33ms (a 4.7x lower latency).

πŸ’Ύ Memory Usage

MomentNestJSGin
Startup68 MB11 MB
After stress85 MB52 MB

Go consumes between 40% and 80% less memory than Node.js in similar scenarios.


What This Means in Practice

βœ… Use Go (Gin) when:

  1. Performance is critical: APIs that need to sustain volumes exceeding 10k req/s.
  2. The domain is CPU-bound: intense data processing and transformation tasks.
  3. p99 latency is a priority: cases with very tight SLAs (Service Level Agreements).
  4. Resources are limited: Kubernetes environments with strict memory caps.
  5. Stability under load is necessary: situations where avoiding timeouts is essential.

βœ… Use Node.js (NestJS) when:

  1. Development speed is the priority: leveraging features like TypeScript, Dependency Injection, and decorators.
  2. The team is focused on JavaScript: drastically reducing the learning curve.
  3. The domain is I/O-bound: situations where the database performance difference is acceptable for the business.
  4. Reliance on the NPM ecosystem: needing specific libraries already consolidated within the community.

Reproduce It Yourself

# Clone the repository git clone https://github.com/zghost10/go-vs-node.git # Start PostgreSQL docker-compose up -d # Start the APIs cd nestjs-api && npm install && npm run build && node dist/main.js & cd gin-api && go build && ./gin-api & # Benchmark wrk -t8 -c800 -d45s --latency http://localhost:3000/health wrk -t8 -c800 -d45s --latency http://localhost:8080/health wrk -t4 -c200 -d15s --latency http://localhost:3000/db/users/active wrk -t4 -c200 -d15s --latency http://localhost:8080/db/users/active