Back
Tech 12 min read - 4 Feb. 26 - Julien Chapuy

Which language for a high-performance backend in 2026? Benchmark with Grafana K6

At Galadrim, we are used to working with many different Web languages and frameworks. While each team and each developer have their preferences, we are convinced that choosing the most suitable tool for the project is the best solution.
In this sense, we have been led to create numerous backends in TypeScript and Python -our most common stacks- but also in Go, Rust, PHP, or C#. Over time, we wondered if there were real performance differences between these languages and some of their respective frameworks at the scale of our projects. When and how to favour one technology over another?
To answer this question, we carried out an internal benchmark comparing 4 popular languages, Go, Rust, Python and JavaScript for a typical web project, a REST API for a mini social network.
Here is our feedback.

I. Grafana K6, a modern load testing tool

To perform this benchmark, we used Grafana K6, an open-source tool, written in Go, and designed by Grafana Labs which competes with tools such as JMeter built on the JVM (Java).

A game-changer

  • Simple to use : Designed for CLI use, K6 is very simple to use and test scenarios are simple scripts JavaScript (or TypeScript). Any developer on the team can read, write, and maintain the tests without specific training.
  • Performance and efficiency : Being written in Go, K6 consumes very little memory and performs very well. A single standard machine can thus simulate thousands of virtual users where other tools would require an entire cluster.
  • CI/CD Integration : As a scriptable CLI tool, it integrates natively into your pipelines (GitHub Actions, GitLab CI, etc.) to automate performance non-regression tests.

How does it work?

K6 orchestrates VUs (Virtual Users). Each VU acts as a user obeying a predefined script repeated indefinitely:
  1. It executes HTTP requests (or WebSocket, gRPC).
  2. It checks responses (status 200, JSON content...).
  3. It respects pause times (sleep) to simulate realistic human behaviour.
The tool then aggregates the results in real time and provides much more relevant metrics than a simple "average" to understand the latency experienced by users. An interesting metric is the 95th percentile or p95, which corresponds to the value such that 95% of observed latencies are below and 5% are above.

II. The test protocol: a mini social network

For the results to be relevant, we simulated a use case representative of the projects we develop for our clients: a mini social network. Thus, our test backends must implement the following features:
  • Authentication : Login, retrieval of the current profile.
  • User management : Creation, listing, profile modification.
  • Post management : Publication, feed reading, deletion.
  • Social network features : Comments, likes / unlikes.

Technical environment

We also wanted to limit the use of tools specific to each ecosystem as much as possible for two reasons: not to burden the tests with additional dependencies and to avoid introducing bias when comparing performance.
To this end, we decided to start from a simple OpenAPI file describing the API and then to implement the routes in a minimalist way in each language without using an ORM or a JSON mapping tool. We wrote our database manipulation queries directly in SQL, so that each backend executes exactly the same query with the same database, in the same way.
The tests were carried out on a MacBook Pro M3 (36 GB RAM) with Docker containers limited to 4 CPUs and 8 GB of RAM for each backend. The absolute values of requests per second (RPS) mentioned below are not to be taken as they are but rather to be compared with each other as they depend on your configuration.

The test scenario for each VU

Our test workflow doesn't just spam a route; it simulates a user's complete journey:
  1. Administrator login and new user creation.
  2. New user login.
  3. Publishing a post.
  4. Reading the feed.
  5. Adding a comment and liking a post.
  6. Data deletion (cleanup).
We varied the load from 50 VUs à 1000 VUs simultaneous to see when the backends buckle.
Below is an execution example for Express (Bun, 1000 VUs).

III. The learnings

RPS comparison across all scenarios
P95 response time per scenario

Raw performance: the Go vs Rust duel

If you're looking for pure performance for very high-traffic systems, the match is between Go and Rust. On the scale of our tests, there's no clear winner, and both languages achieve similar performance (> 20,000 RPS). These languages also shine with their resilience under heavy load, with p95s around 85ms, well below the 200ms accepted within the scope of this test.
Go (with Fiber) : Its simplicity and goroutine management make it a powerhouse of efficiency for web APIs.
Rust (with Axum) : With very solid performance, Rust also offers unparalleled memory safety and stability guarantees, despite a more complex learning curve.
Verdict: If you need raw performance, Go and Rust are solid choices. While the former focuses on developer experience, the latter excels in crafting robust systems.

Development speed: Python vs JavaScript (Node/Bun)

For the majority of projects (MVP, startups, internal tools), development speed often takes precedence over raw performance. Indeed, the chosen programming language is rarely the limiting factor for backend performance compared to optimising architecture, database, and network or system I/O.
Python (FastAPI) : Easy to pick up, with concise and clear syntax, excellent for Data, it shows limitations in terms of performance under heavy load. Furthermore, Python quickly has a significant impact on server-side memory usage and therefore may not be suitable for applications with high hardware constraints (e.g., embedded applications). In our tests, it handles 'average' load well but starts to fail under heavy load (500+ simultaneous users) with a p95 of 420ms for 1,000 VUs. It's an excellent compromise between productivity and performance, as long as traffic remains reasonable (~7,000 RPS).
JavaScript (Node vs Bun) : Node.js is the most popular JavaScript runtime, and it's based on Google's V8 engine. Bun is a newer JavaScript runtime, built on Apple's JavaScript engine. JavaScript (and TypeScript) is a programming language that allows for the development of web applications. It has the enormous advantage of being able to run client-side and server-side, enabling the development of full-stack web applications with a single language. This implies the ability to share common code between the client and server (business logic, data validation, types, etc.), but also to use and master only one language for application development. With approximately 10,000 RPS achieved in both cases, the JavaScript ecosystem offers solid performance while maintaining a p95 of ~170ms in the worst-case scenario.
Verdict: If you have a predominantly full-stack team, JavaScript/TypeScript is a very solid option for achieving excellent performance without changing languages. For purely backend use or Data Science with rapid iteration, Python is a very good alternative but will require a more robust architecture (caching, horizontal scaling) and more attention to code optimisation to achieve comparable performance.
If you wish to reproduce these tests, here is the GitHub link for this benchmark!

Do you want support to launch your digital project?

Submit your project now