· frameworks  · 7 min read

Express.js vs. Fastify: An In-Depth Performance Showdown

A practical, hands-on comparison of Express.js and Fastify focused on real-world performance, developer experience, and community support - with a clear methodology, representative benchmark guidance, migration advice, and recommendations for when to choose each framework.

A practical, hands-on comparison of Express.js and Fastify focused on real-world performance, developer experience, and community support - with a clear methodology, representative benchmark guidance, migration advice, and recommendations for when to choose each framework.

Outcome first: after reading this you’ll know whether Fastify’s speed claims translate to an actual win for your project, how to run repeatable benchmarks yourself, and what tradeoffs (developer ergonomics, ecosystem, migration cost) matter most when choosing between Express and Fastify.

Why this matters. Pick the wrong HTTP framework and you pay with extra CPU, latency, and engineering friction - at scale. Pick the right one and you gain headroom, fewer servers, and easier scaling. The difference can be meaningful. Read on to learn how meaningful.

Quick verdict (short)

  • For raw throughput and low latency on high-concurrency JSON APIs: Fastify usually wins. Fast. Reliable. Optimized.
  • For maximum middleware availability, broad familiarity, and the lowest friction for small teams: Express remains an excellent, pragmatic choice.

Now the long answer.

What are we comparing?

  • Express.js - a minimal, unopinionated, and widely-adopted Node.js web framework with a huge middleware ecosystem and simple API. Official site.
  • Fastify - a newer framework designed for speed and low-overhead, with a plugin-first architecture, built-in schema support, and opinionated performance optimizations. Official site.

Both are production-ready. Both power real systems. But they approach design differently: Express favors minimalism and ecosystem flexibility; Fastify favors measured structure and runtime optimizations.

What affects web-framework performance (brief primer)

  • Route handling overhead: how many JS calls and allocations happen per request.
  • JSON serialization and parsing: often the bottleneck for APIs.
  • Middleware/plug-in layers: each layer adds work.
  • Logging and instrumentation: synchronous logging can kill throughput.
  • Node.js event loop saturation and CPU-bound work.
  • Network and kernel limits: connections, TCP, keep-alive, TLS.

Optimizing framework overhead only matters when your app is CPU-light (I/O-bound) and you need to squeeze latency/throughput. If your app is dominated by DB queries, database tuning will usually buy more than switching frameworks.

Benchmarking methodology (how you should test - repeatable)

If you want credible numbers for your app, follow these basics:

  1. Keep the environment stable: same machine, disable unrelated services, use identical Node.js versions.
  2. Use realistic payloads: craft JSON shapes that match your API.
  3. Include representative middlewares/plugins you actually use (auth, validation, logging).
  4. Test multiple patterns: simple JSON route, DB-backed route (simulate DB latency), CPU-bound route (e.g., hashing), and streaming/static-file routes.
  5. Use a load tool like autocannon (fast, Node-friendly) - autocannon on npm - and run multiple trials, discard the first run, and report medians.

Example autocannon command (simple JSON route):

# on the client machine
npx autocannon -c 100 -d 20 -p 10 http://localhost:3000/json

Parameters: 100 connections (-c), 20 seconds (-d), 10 pipelining (-p). Adjust to match expected production concurrency.

Representative results and published comparisons (what the community reports)

A lot of public comparisons focus on simple microbenchmarks (a route that returns a small JSON object). In these tests, Fastify tends to show substantially higher throughput and lower latency than Express, often by a factor of 2x–3x in many setups. Fastify publishes benchmark details showing significant gains for JSON microservices; see their benchmarks page for examples: Fastify benchmarks.

Independent, broader framework comparisons like the TechEmpower Framework Benchmarks also illustrate that Node frameworks vary widely in performance depending on workload and configuration - see: TechEmpower Framework Benchmarks.

Important caveat: microbenchmark wins (e.g., raw requests/sec for a tiny JSON response) don’t always translate directly into proportionally lower hosting costs or better application-level response times, especially if your app spends most time querying databases, external services, or doing CPU work. Always benchmark using realistic scenarios.

Why Fastify is often faster (technical reasons)

  • Lower per-request overhead: Fastify compiles route handlers and does less work per request.
  • Schema-driven serialization: Fastify can use JSON schema to serialize faster than JSON.stringify in some cases, reducing CPU work for responses.
  • Optimized logging: Fastify’s recommended logger (pino) is designed for speed with asynchronous, low-overhead logging.
  • Plugin architecture: isolates features so unused features don’t add runtime cost.

See Fastify’s docs for more on the performance design: Fastify plugins & architecture.

Why Express can still be the right choice

  • Ecosystem breadth: decades of middleware and examples; almost any third-party middleware exists or has an analog.
  • Simplicity and familiarity: easy to onboard new developers quickly.
  • Minimalistic core: express itself is intentionally small and flexible.

Express documentation and middleware list: Express official site.

Developer experience: code examples (concise)

Minimal Express server:

const express = require('express');
const app = express();
app.get('/json', (req, res) => res.json({ hello: 'world' }));
app.listen(3000);

Minimal Fastify server:

const fastify = require('fastify')();
fastify.get('/json', async (request, reply) => ({ hello: 'world' }));
fastify.listen({ port: 3000 });

Both are small and readable. Fastify encourages registration of plugins and schema declarations; Express encourages incremental middleware composition. Which style you prefer affects developer velocity.

TypeScript support and developer tooling

If strong compile-time types and inference for route schemas matter, Fastify provides an edge.

Logging, metrics, and observability

  • Fastify often pairs with pino (extremely fast JSON logger). pino’s design avoids blocking the event loop under load.
  • Express apps often use winston, bunyan, or other loggers; they work fine but choose asynchronous and non-blocking patterns to avoid latency surprises.

Remember: synchronous console.log or heavy synchronous transforms on each request will dominate any framework-level differences.

Plugin & middleware ecosystem

  • Express: enormous ecosystem. If you depend on many existing middleware packages, Express gives the fastest path to integration.
  • Fastify: growing plugin ecosystem; many adapters exist to use express-style middleware when needed. The plugin model improves isolation and performance.

If your project uses many legacy middleware packages that expect Express middleware signatures, migration can be more work.

Resource usage: memory and CPU

Fastify is designed to be low-overhead and frequently consumes less memory per connection than Express in microbenchmarks. Less memory per connection can translate into more concurrent connections on the same host and lower cloud costs. Again: profile your real app.

Real-world scenarios - which to pick

When Fastify is the better fit:

  • You operate high-throughput, low-latency JSON APIs where framework overhead matters.
  • You want strong TypeScript schema safety and faster serialization.
  • You’re building greenfield microservices and want a plugin-first, opinionated performance-oriented base.

When Express is the better fit:

  • You need broad middleware compatibility and want the shortest learning curve.
  • Your traffic profile is modest and bottlenecks are external services (DB, third-party APIs).
  • You’re migrating or extending legacy apps already built on Express.

Migration considerations

  • Evaluate your middleware: does it depend on Express-specific behavior? Some middleware can be adapted or replaced.
  • Map error handling and request lifecycle: Fastify’s lifecycle hooks differ in shape.
  • Test thoroughly under load: run the same synthetic and real traffic tests before and after migration.
  • Consider an incremental approach: rewrite hot paths to Fastify where performance matters, keep the rest on Express behind an internal proxy if useful.

How to run a meaningful microbenchmark (step-by-step)

  1. Create two minimal apps (Express and Fastify) that implement the same API and middleware.
  2. Run them on the same machine, same Node.js version, with production flags (NODE_ENV=production).
  3. Warm up each server for a minute to let JIT optimizations settle.
  4. Use autocannon with real concurrency and pipelining values representative of your production load.
  5. Repeat 5–10 times and report median throughput (requests/sec), p50/p95 latency, and max memory use (process RSS) after a 60s run.

Example commands (on the server):

# server side
NODE_ENV=production node server-express.js &
NODE_ENV=production node server-fastify.js &

# client side
npx autocannon -c 200 -d 30 -p 10 http://SERVER:3000/json

Adjust -c (connections) and -p (pipelining) to match expected load.

Community & maintenance

  • Express has been around longer and therefore has broader adoption, lots of tutorials, and many third-party packages. That often translates to faster developer onboarding and abundant examples.
  • Fastify is newer but actively developed and has an engaged community focused on performance and plugins.

Check package pages and download stats for up-to-date signals: express on npm and fastify on npm.

Final recommendations (practical)

  • If your primary goal is the highest possible throughput for JSON APIs and you’re starting a new project or can invest in migration: choose Fastify.

  • If you need immediate compatibility with a large set of middleware, or your team is heavily familiar with Express and your bottlenecks are elsewhere: choose Express.

  • In any case: measure. Run the benchmark recipe above using realistic payloads and middleware from your actual app. Optimize the real bottlenecks first - database, caches, network.

Summary

Fastify gives you lower overhead, faster serialization, and better out-of-the-box throughput for microservices and high-concurrency APIs. Express gives you familiarity, massive ecosystem support, and rapid time-to-productivity. Both are stable choices; the right one depends on where your real bottlenecks and team constraints lie. Test with real workloads. Optimize where it actually matters. The fastest framework on paper is useless if it breaks your delivery cadence; but when performance matters, Fastify gives you more headroom for the same hardware.

References

Back to Blog

Related Posts

View All Posts »
Fastify vs. Express: The Ultimate Efficiency Showdown

Fastify vs. Express: The Ultimate Efficiency Showdown

A practical, opinionated comparison of Fastify and Express focused on performance. Learn how they differ under load, how to benchmark them yourself, and when Fastify's design gives it a real advantage for high-throughput Node.js services.