Express has 70 million weekly downloads but its synchronous middleware model costs you throughput on every request. Fastify claims a 2x speedup with schema validation baked in. Here is the real benchmark under load, the migration strategy that avoids a full rewrite, and the one scenario where Express stays the better choice.
Your API reads an entire file into memory on every download request, crashes the server when users download multiple large files simultaneously, and cannot resume interrupted transfers. Here is how to build a Node.js download endpoint that streams, supports Range headers for pause/resume, and throttles bandwidth per connection.
Your API returns JSON for everyone, but mobile clients on slow networks want MessagePack, internal services negotiate Protobuf, the browser cache serves HTML for a JSON request because Vary is missing, and the fix is three request headers and one response header you have been ignoring.
REST and GraphQL both leak a type gap between server and client that costs you a production bug every few sprints. tRPC eliminates that gap entirely. Here is how to build a production tRPC API with authentication, error handling, middleware, and rate limiting, without a code generator or a spec file.
WebSocket connections live longer than HTTP requests, which means your JWT that was valid at connect time may be expired or revoked while the socket is still open. Here is how to authenticate WebSocket handshakes, validate authorizations per-message, and handle token rotation without killing active connections.
Your JSON API serves 400KB responses, the mobile clients on 3G wait five seconds for a full payload, and compressing everything with Brotli at level 11 looks like an easy win. The benchmark says it cuts bytes by 30%. The CPU flame graph says it adds 80ms of overhead per request. Here is the compression strategy that actually improves p95 latency without turning your Node.js process into a compression farm.
One wrong file can crash your Node.js process, fill your disk, or expose your internal network. Here is the upload pipeline that validates content, streams to storage, and rejects everything dangerous before it touches your application memory.
Your service works in isolation but breaks when paired with a different version of its upstream. That is not a bug in either service. It is a contract nobody wrote down. Here is how to catch every breaking API change before deploy using consumer-driven contract tests with Pact, with working Node.js examples.
Stop hand-writing fetch wrappers that drift from the spec. Here is how to generate fully typed API clients from OpenAPI specs, catch breaking changes in CI, and never debug a "but the API returned field X" production issue again.
Your mobile app is three times slower than your web app because your API was designed for a desktop browser. The BFF pattern gives each client its own backend layer, cutting payloads in half and eliminating client-side joins. Here is how to build one without duplicating business logic.
Your API returns ad-hoc error objects with no structure, no standard fields, and no documentation. Every client has to guess what the response shape means. RFC 9457 (Problem Details) gives you a machine-readable, standardized error format that works with any HTTP API, and this post shows you the Express and Fastify middleware to adopt it in under 50 lines.
The implicit grant is deprecated. The authorization code flow with PKCE is the only secure way to authenticate users in SPAs, mobile apps, and server-side integrations. Here is the complete Node.js implementation with code verifiers, token exchange, refresh token rotation, and the three mistakes that still leak tokens.
Stop storing password hashes. Here is a working WebAuthn / passkey implementation for Node.js that replaces passwords with biometric or device-bound credentials using the FIDO2 standard, with server-side validation, credential storage in Postgres, and a minimal client implementation.
Your API endpoint builds a full JSON array before sending anything, so the first byte arrives after the last database query. Switch to newline-delimited JSON streaming and get the first item to the client in milliseconds, with backpressure handling, proper error recovery, and no extra dependencies.
Your SPA works fine in development and then every cross-origin request fails in staging with a cryptic CORS error. Here is what the preflight, the three response headers, and the credential flag actually do under the hood, plus a test harness that lets you verify CORS behavior before you deploy.
Every API eventually breaks its clients. The difference between a controlled upgrade and a fire drill is how you version it. Here is the real trade-off between URL, header, and query-parameter versioning, the backward-compatibility rules that actually hold, and the sunset playbook that keeps mobile clients from breaking at 2 a.m.
You cannot revoke a JWT without a database round-trip, so stop pretending it is stateless. Build a secure session model with short-lived access tokens, httpOnly refresh cookies, rotation, and reuse detection in Node.js.
A single unhandled promise rejection took down your Node.js server at 2 AM. Here is how to build a global error boundary that catches uncaught exceptions, unhandled rejections, and async failures, logs actionable context, and keeps the process alive or exits cleanly without losing the trail.
Your /health endpoint returns 200 OK while your database is unreachable. Kubernetes keeps routing traffic. Users see 500s. Here is how to build dependency-aware health checks that actually protect your uptime.
JSON.stringify is the default for every internal service call, but on high-throughput RPC it burns CPU and inflates payloads. Here is how MessagePack replaces it, with Node.js benchmarks, Express middleware code, and the migration path that does not break your public API.
Depth limiting does not stop expensive GraphQL queries. A shallow query with wide list arguments can still exhaust your database and OOM your API. Here is a practical complexity-scoring implementation that rejects abusive queries before they touch a resolver, plus the adversarial test cases that prove it works.
A malformed request slipped past JSON parsing and wrote a null into a required column, causing a cascade of 500s that took two hours to clean up. Here is the Zod validation layer that stops bad input at the API boundary, with the TypeScript integration, custom refinements, and error formatting that makes client integrations painless.
Offset pagination looks fine on page one and falls apart on page two hundred. Here is the exact SQL and Node.js code to replace it with cursor-based pagination that stays fast, avoids duplicate rows, and survives concurrent writes.
Your "just POST to the callback URL" webhooks are creating angry customers, retry storms, and silent data loss. Here is the architecture (queue, circuit breaker, dead-letter, and backoff) that turns fire-and-forget HTTP into a delivery system you can monitor and trust.
A valid webhook signature only proves who signed the payload, not that the request is fresh. Build a replay-safe Node.js webhook handler with raw-body verification, timestamp windows, idempotency, and atomic Redis locks.
Webhook retries silently double-charge customers, double-create resources, and turn one ticket into a refund spreadsheet. Here is the 30-line Postgres-backed middleware that makes any handler safe to retry, plus the hammer-test that proves it works.
gRPC is faster, smaller, strongly typed, and has worse browser support and harder debugging. The decision is workload-specific. Here is the honest comparison: where gRPC genuinely wins, where REST stays the right choice, and the connect-rpc middle ground that resolves most of the trade-offs.
Most teams write the API, then write the OpenAPI spec, then watch them diverge until the docs are useless. The fix is to make the spec the source of truth: generate types, validation, mocks, and clients from it. Here is the workflow that survives, and the tools that make it tractable.
Server-sent events are a 1.5KB drop-in for streaming notifications, progress, and live updates, and they work through every proxy and CDN that already handles HTTP. WebSockets are the right tool for genuine bidirectional, low-latency traffic. Here is the decision tree and the implementation patterns for each.
The “sliding window” rate limiter every tutorial shows you breaks at scale. Token bucket is the algorithm real APIs use because it allows bursts without exceeding the average rate. Here is a 30-line Lua-on-Redis implementation, the failure modes to test for, and the headers you should be returning to clients.
Most API developers think “HTTP caching” means putting things in Redis. The browser, the CDN, and your reverse proxy already implement a four-decade-old caching protocol; you just have to set the right headers. Here is the cheat-sheet of Cache-Control, ETag, Last-Modified, and the conditional-request flow that makes JSON endpoints feel instant.