Hono vs Express: Performance Benchmarks on Cloudflare Workers and Node

Published: (April 20, 2026 at 11:01 PM EDT)
4 min read
Source: Dev.to

Source: Dev.to

Benchmark Overview

All tests were run with wrk (12 threads, 400 connections, 30‑second duration) on the same hardware (M3 Pro, 36 GB RAM) using a shared Postgres connection pool (pg, 10 connections) and a single SELECT by primary key per request.

Test route

GET /users/:id – validates a UUID param, runs a single SELECT by primary key, returns JSON.

Results

FrameworkReq/secp50 Latencyp99 Latency
Express 412,40028 ms94 ms
Fastify 431,20011 ms38 ms
Hono 428,60012 ms41 ms
Hono 4 + Bun41,8008 ms27 ms

Note: Express does not run on Cloudflare Workers (no Node.js runtime). Hono was designed for that environment.

Workers vs. Node

Configuration & Cold Starts

EnvironmentSimulated Req/secCold‑start latency
Hono on Workers~45,000see example below
// Example cold‑start handler (Express‑style)
const { id } = req.params;
if (!isValidUUID(id)) {
  return res.status(400).json({ error: 'Invalid ID' });
}

const user = await db.users.findById(id);
if (!user) return res.status(404).json({ error: 'Not found' });

res.json(user);
});

app.listen(3000);

Hono (TypeScript)

import { Hono } from 'hono';
import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';

const app = new Hono();

app.get(
  '/users/:id',
  zValidator('param', z.object({ id: z.string().uuid() })),
  async (c) => {
    const { id } = c.req.valid('param'); // typed & validated

    const user = await db.users.findById(id);
    if (!user) return c.json({ error: 'Not found' }, 404);

    return c.json(user);
  }
);

export default app; // Works on Workers, Bun, Node, Deno

Key Difference

  • c.req.valid('param') returns typed, validated data.
  • In Express, req.params is just Record; validation must be performed manually.

This pattern mirrors the type‑safety of tRPC but for classic REST endpoints.

Middleware Landscape

FeatureHono (official)Express (npm ecosystem)
CORS, compression, logger, JWT auth, rate limiting, cache headers✅ (via third‑party)
Zod / TypeBox validator✅ (via third‑party)
Static file serving
OpenAPI spec generation✅ (via swagger-ui-express, etc.)
Passport.js❌ (no clean port)
express-session❌ (use Workers KV / Durable Objects)
Specialized OAuth middleware❌ (some missing)

For greenfield projects, Hono’s official middleware covers ≈ 90 % of typical use cases. When migrating an existing Express app that heavily relies on passport.js or other niche middleware, factor the migration cost.

Portability Example

// src/app.ts – write once
import { Hono } from 'hono';
export const app = new Hono();

app.get('/health', (c) => c.json({ ok: true }));
export default app;

Cloudflare Workers

# wrangler.toml
# point `main` to src/app.ts
// Workers entry (no extra code needed)
export default app;

Node.js

import { serve } from '@hono/node-server';
import { app } from './app';

serve({ fetch: app.fetch, port: 3000 });

Bun

import { app } from './app';
Bun.serve({ fetch: app.fetch, port: 3000 });

The same codebase can run on edge runtimes (Workers, Pages Functions) and on traditional servers, simplifying deployment pipelines.

Decision Guide

  • Existing Express app with heavy middleware → Migration cost may outweigh performance gains.
  • Team unfamiliar with the Web Request/Response API (Hono’s c.req/c.res) → Consider training overhead.
  • Need for Passport.js or other Express‑specific plugins → Stay with Express or find alternatives.
  • Greenfield TypeScript API → Use Hono.
  • Deployments targeting Cloudflare Workers, Pages Functions, or other edge runtimes → Hono is a natural fit.
  • Desire for end‑to‑end type safety without full tRPC adoption → Hono + Zod validator.
  • Bun runtime → Hono + Bun currently yields the fastest numbers in our tests.

Performance Considerations

The performance gap between Hono and Express on Node matters only at high concurrency. At a typical production load of ≈ 100 req/sec, user‑facing latency differences are negligible. Choose Hono for its superior developer experience and type safety rather than raw benchmark numbers.

Hono vs. Fastify

Fastify is slightly faster than Hono on pure Node environments, but it does not run on Workers and has a more complex plugin system. When multi‑runtime portability (Workers ↔ Node ↔ Bun) is a priority, Hono is the clear winner.

0 views
Back to Blog

Related posts

Read more »

Data Transfer Object (DTO) in NestJS

What is a Data Transfer Object DTO? A Data Transfer Object DTO is a design pattern used in NestJS to define how data is structured and transferred between diff...