You are building a Node.js backend and the framework choice seems obvious. Express is everywhere, historic, billions of downloads. But if your service handles hundreds of requests per second, every extra millisecond of latency turns into lost clients and costlier servers. At Meteora Web, we have worked with both on real projects — proprietary platforms, public APIs, billing systems. And the difference is tangible. In this guide we show you not just the numbers, but the structural reasons behind the performance gap, and when it makes sense to choose Fastify over Express.
Performance: Myth and Reality
You often read that Fastify is 2–3× faster than Express. Is it true? It depends on the workload. We ran a simple test: a JSON endpoint returning a static object. With 100 concurrent connections and 10 seconds, Fastify handled 220% more requests than Express, with half the average latency. Why? Three deep reasons:
- Native JSON serializer — Fastify uses
fast-json-stringifybased on schema, while Express uses the slower built-inJSON.stringify. - Routing with find-my-way — a C-based routing library, whereas Express has a more generic router.
- Built-in schema validation — the JSON Schema is compiled once, avoiding runtime checks.
Hands-on Benchmark with autocannon
Here are two minimal servers. Install autocannon globally. Then create the two files and compare.
// express-server.js
const express = require('express');
const app = express();
app.get('/hello', (req, res) => {
res.json({ message: 'Hello World' });
});
app.listen(3000);
// fastify-server.js
const fastify = require('fastify')();
fastify.get('/hello', async (request, reply) => {
return { message: 'Hello World' };
});
fastify.listen({ port: 3001 });
Then run: autocannon -c 100 -d 10 http://localhost:3000/hello and autocannon -c 100 -d 10 http://localhost:3001/hello. Look at the Req/Sec and Latency columns. In real-world scenarios, when you add middleware, authentication, and database calls, the gap shrinks (the bottleneck is often the DB), but it remains significant.
When to Choose Fastify
It’s not just about raw speed. Fastify is designed for projects where performance is a requirement, not an afterthought.
High-concurrency public APIs
If your endpoint will be hit by thousands of simultaneous clients (e.g., payment gateways, third-party APIs), lower latency means fewer servers and more savings. We migrated a reactive billing system from Express to Fastify and the AWS cluster cost dropped by 35% at the same load.
Containerized microservices
In Kubernetes every millisecond matters. Fastify has a smaller memory footprint (~10–15% less) and starts faster, which makes a difference in horizontal scaling scenarios.
Projects requiring strict validation
If you work with OpenAPI contracts or JSON Schema, Fastify gives you integrated validation without extra plugins. Every route can declare an input/output schema, and the framework applies it automatically. Zero runtime type errors.
When to Stick with Express
Express remains a solid choice — and we still use it — in these cases:
- Small projects or prototypes — if load is low and development speed matters more than runtime speed.
- Legacy dependencies — many middleware (passport, session, compression) have decades of testing on Express.
- Team already familiar with Express — migrating for the sake of it without a real bottleneck is wasted time.
- Applications using patterns Fastify does not support — e.g., Express allows modifying the response after headers have been sent (not recommended but sometimes present in old code).
Ecosystem and Plugins: Two Different Philosophies
Express is minimal and everything is middleware. You can stack any function, but without isolation. A bug in one middleware can contaminate the whole app. Fastify, on the other hand, has a plugin system with encapsulation based on context: each plugin has its own scope, its own dependencies, and cannot affect others. This makes code more predictable and safer, especially in team projects.
If you need to create a reusable plugin (e.g., authentication, logging), Fastify forces you to declare dependencies, which is a win for long-term maintainability.
Schema Example with Fastify
const fastify = require('fastify')();
const schema = {
schema: {
response: {
200: {
type: 'object',
properties: {
id: { type: 'integer' },
name: { type: 'string' }
}
}
}
}
};
fastify.get('/user/:id', schema, async (request, reply) => {
const id = request.params.id;
// you could do a DB query here
return { id: Number(id), name: 'Mario' };
});
fastify.listen({ port: 3000 });
With Fastify, the response is automatically serialized according to the schema and validated before being sent. If the DB returns an unexpected field, the framework throws an error. In Express, you would have to handle that manually.
Summary — What to Do Now
- Benchmark with your real load — don’t trust generic numbers. Take your most critical endpoints, measure with autocannon on Express and on Fastify (using a small POC).
- For new projects — if you expect high traffic, microservices, or public APIs, start directly with Fastify. The learning curve is low if you already know Express (similar API).
- For existing Express projects — don’t migrate everything at once. Identify bottlenecks (e.g., an endpoint that saturates) and rewrite only those in Fastify, exposing them on a separate port or as a microservice.
- Invest in validation — whether you choose Express or Fastify, always use a schema validator (Joi, Zod, JSON Schema). You’ll reduce production errors.
- Remember: performance is not just the framework — caching, optimized queries, CDN, and good data architecture matter much more. Fastify shaves off milliseconds, but it won’t fix a slow database.
At Meteora Web we use Fastify for our high-traffic platforms, but we still use Express for quick plugins and prototypes. The right choice depends on context. Now you have the tools to decide.
Sponsored Protocol