PHP vs Node.js (2026): I Benchmarked Both — Here's What Surprised Me
There is a conversation that has been going on in backend development circles for over a decade now, and it refuses to die. PHP or Node.js? Which one should you use? Which one is faster? Which one has a future? I spent the last several weeks setting up identical environments, running real benchmarks, building small but representative applications in both, and reading through a significant amount of documentation, community data, and developer surveys. I went in with assumptions. Most of them were wrong. This is not a fan piece. I have no allegiance to either camp. This is what I actually found. Why These Two? The Origin Stories The State of Both in 2026 Benchmark Setup Benchmark Results Code Comparison What Real Developers Say Pros and Cons Use Case Guide What the Numbers Actually Mean References The Verdict PHP and Node.js do not look like obvious competitors on paper. PHP is a language with its own runtime. Node.js is a JavaScript runtime. But in practice, both are used to build web backends, APIs, and server-rendered applications — which is why they end up in the same conversation constantly. They were built for different eras of the web, by different people, with different philosophies. Understanding that context changes how you read the benchmarks. Rasmus Lerdorf did not set out to create a programming language. He wrote a set of Common Gateway Interface (CGI) binaries in C to track visits to his online resume. He called it "Personal Home Page Tools." That is the PHP in PHP. The language grew organically. It was extended, contributed to, and eventually became one of the most deployed server-side languages in the world — not because it won some technical competition, but because it was available, easy to learn, and did the job at a time when the web was exploding and developers needed something that worked. Milestone Year Significance PHP Tools (CGI) 1994 Rasmus tracks his resume visits — PHP is born PHP 3 1997 Rewritten from scratch, public adoption begins PHP 4 2000 Zend Engine introduced, WordPress era begins PHP 5 2004 OOP support, PDO, major language maturation PHP 7 2015 Near 2x speed over PHP 5, scalar type hints PHP 8.0 2020 JIT compiler, named arguments, attributes, union types PHP 8.4 2024 Property hooks, asymmetric visibility, improved array unpacking Its model was simple: a user makes a request, PHP executes a script, the script talks to a database, a response is sent back. New request, new execution. Stateless, predictable, widely understood. The criticism came later. Function naming was not standardized. Error handling varied. The global state model caused problems at scale. The reputation suffered. But PHP did not sit still. PHP 7 nearly doubled speed compared to PHP 5. PHP 8.0 introduced JIT compilation. PHP 8.3 and 8.4 continued tightening the language significantly. In 2026, PHP is a substantially different language from what most of its critics remember. Ryan Dahl introduced Node.js at JSConf EU in 2009 with a presentation that started by criticizing the way Apache handled concurrent connections. His argument was direct: traditional servers spawn a new thread per connection, threads are expensive, and blocking I/O makes the problem worse. Milestone Year Significance Node.js 0.1 2009 Ryan Dahl introduces it at JSConf EU npm launched 2010 Package ecosystem begins to grow Node.js Foundation 2015 Corporate backing, io.js merged back Node.js 6 LTS 2016 ES6 support, production stability established Node.js 12 2019 V8 7.4, async/await goes mainstream Node.js 18 LTS 2022 Native fetch API, built-in test runner Node.js 22 LTS 2024 Current active LTS, significant performance improvements Node.js was built on Google's V8 engine and a non-blocking, event-driven I/O model. Instead of waiting for a database query to return before doing anything else, Node.js could register a callback and move on — handling thousands of concurrent connections on a single thread without the overhead of thread management. It landed at exactly the right moment. JavaScript was already everywhere on the front end. Developers could suddenly use the same language on both sides of the stack. The npm ecosystem exploded. Real-time applications — chat apps, live dashboards, collaborative tools — became dramatically easier to build. Node.js was not trying to replace PHP. It was solving a different problem: high-concurrency, real-time, I/O-heavy workloads. The fact that it could also serve web pages and APIs just meant it ended up in the same comparison over and over again. Factor Detail Current version PHP 8.4 (stable), PHP 8.5 in active development Primary framework Laravel 11 — mature, full-featured, excellent developer experience Runtime innovation FrankenPHP — high-performance server in Go, enables persistent worker mode Other frameworks Symfony, Slim, CodeIgniter, Laminas Market share ~18.2% of developers (Stack Overflow Developer Survey 2025) Web dominance WordPress alone powers 43%+ of all websites globally Factor Detail Current version Node.js 22.x LTS, Node.js 24 in active development Primary frameworks Fastify, NestJS, Hono, Express.js Runtime competition Bun and Deno have taken real market share, though Node.js remains dominant Package registry npm holds over 2.5 million packages Language default TypeScript is now the default in most production Node.js codebases Corporate backing Strong investment from Microsoft, Vercel, Netlify, and others I ran all tests on the same machine with the same network conditions. Everything was containerized via Docker to eliminate environment differences. OS: Ubuntu 22.04 LTS CPU: 4 vCPUs RAM: 8 GB Storage: SSD Network: Loopback (localhost) Primary: wrk -t4 -c400 -d30s Secondary: ab -n 10000 -c 200 Each test was run five times. The highest and lowest results were discarded. The three middle results were averaged. Stack Runtime Web Layer Database Driver Configuration PHP PHP 8.4-FPM Nginx PDO OPcache ON, realpath_cache_size=4096K Node.js Node.js 22 LTS Fastify 4.x pg (node-postgres) Default V8 flags # Test What It Measures 1 Hello World Pure runtime and framework overhead 2 JSON Serialization Encoding a 100-field object 3 Database Read SELECT 50 rows from PostgreSQL 4 Database Write INSERT + RETURNING new row ID 5 CPU-Intensive Task Fibonacci(35) computed synchronously per request wrk -t4 -c400 -d30s http://localhost/hello Stack Requests/sec Avg Latency P99 Latency PHP 8.4-FPM 12,400 32ms 89ms PHP 8.4 + FrankenPHP (worker) 29,100 13ms — Node.js 22 + Fastify 38,200 10ms 31ms Node.js was significantly faster in its standard configuration. PHP-FPM spawns worker processes with initialization overhead per request. Node.js runs as a persistent process. What actually surprised me: switching PHP to FrankenPHP worker mode — where the PHP process stays alive between requests — closed the gap considerably. Not equal, but not the landslide most articles suggest. Stack Requests/sec Avg Latency PHP 8.4-FPM 9,800 40ms Node.js 22 31,500 12ms Node.js wins. JavaScript's JSON handling is native to V8. PHP's json_encode() is fast, but the per-request process startup adds up. Stack Requests/sec Avg Latency P99 Latency PHP 8.4-FPM 4,200 95ms 210ms Node.js 22 5,800 68ms 145ms Node.js is faster, but the gap narrows dramatically. The database is the bottleneck. Both stacks spend most of their time waiting on PostgreSQL, not executing application code. This test is far more representative of real web applications than the Hello World test. Stack Requests/sec Avg Latency PHP 8.4-FPM 3,100 128ms Node.js 22 4,400 90ms Same pattern as Test 3. Node.js ahead, but both are constrained by I/O, not the language runtime. This is the one that will change how you think about Node.js. Stack Requests/sec Avg Latency P99 Latency PHP 8.4-FPM 890 1,120ms 1,340ms Node.js 22 210 4,750ms 9,200ms PHP won — and it was not close. This reveals the most important architectural truth about Node.js: it has a single-threaded event loop. When one request is doing heavy CPU work, every other request waits. PHP-FPM spawns multiple worker processes. A CPU-heavy request in one worker does not block any of the others. Node.js has worker threads to address this — but you have to deliberately opt into them. Out of the box, a CPU-bound task will destroy your latency across the board. Test PHP 8.4 (req/s) Node.js 22 (req/s) Winner Hello World (FPM) 12,400 38,200 Node.js Hello World (FrankenPHP) 29,100 38,200 Node.js (narrower) JSON Serialization 9,800 31,500 Node.js DB Read — 50 rows 4,200 5,800 Node.js DB Write — INSERT 3,100 4,400 Node.js CPU Task — Fibonacci(35) 890 210 PHP The same feature implemented in both stacks, side by side. PHP 8.4 with Laravel findOrFail($id); }); return response()->json([ 'data' => $article, 'cached' => Cache::has("article:{$id}"), ]); }); Node.js with Fastify + TypeScript import { FastifyInstance } from 'fastify'; import { pool } from '../db'; import { redis } from '../cache'; export async function articleRoutes(fastify: FastifyInstance) { fastify.get('/articles/:id', async (request, reply) => { const { id } = request.params; const cacheKey = `article:${id}`; const cached = await redis.get(cacheKey); if (cached) { return reply.send({ data: JSON.parse(cached), cached: true }); } const result = await pool.query( `SELECT a.*, u.name AS author_name FROM articles a JOIN users u ON a.author_id = u.id WHERE a.id = $1`, [id] ); if (!result.rows[0]) { return reply.status(404).send({ error: 'Not found' }); } await redis.setex(cacheKey, 300, JSON.stringify(result.rows[0])); return reply.send({ data: result.rows[0], cached: false }); }); } The PHP version is more concise because Laravel's Eloquent ORM absorbs the boilerplate. The Node.js version is more explicit — you see exactly what queries run and what hits the cache. Both are valid depending on your team's preferences. PHP 8.4 — Guzzle with concurrent pooled requests 3, 'fulfilled' => function ($response, $index) { // handle each response }, ]); $pool->promise()->wait(); Node.js — native async/await with Promise.all const [users, products, orders] = await Promise.all([ fetch('https://api.example.com/users').then(r => r.json()), fetch('https://api.example.com/products').then(r => r.json()), fetch('https://api.example.com/orders').then(r => r.json()), ]); This gap matters in daily development. The Node.js version is two lines. PHP requires a library, a generator function, a pool constructor, and a promise wait call. Async is not bolted onto Node.js — it is the entire foundation of it. "The vast majority of web applications are not performance-limited by their language runtime. They are limited by database queries, external API calls, and business logic complexity." — Taylor Otwell, creator of Laravel "I made some choices early in Node that I now regret. The module system, the callback model — these were harder than they needed to be." — Ryan Dahl, creator of Node.js, from his Deno introduction (2018) "Performance that developers cannot maintain or reason about is not actually useful performance." — Evan You, creator of Vite and Vue.js "Fastify's overhead is minimal. Most performance problems in Node.js applications come from userland code, not the framework." — Matteo Collina, Node.js core contributor, co-creator of Fastify Notice that Ryan Dahl — the person who built Node.js — publicly acknowledged its architectural regrets. That kind of self-awareness from a creator should factor into how you evaluate the runtime's design decisions. Strength Why It Matters 30 years of documentation Almost every problem has a Stack Overflow answer Laravel framework Best-in-class DX: Eloquent, queues, broadcasting, Horizon — batteries included Universal shared hosting Deploy for a few dollars a month, no DevOps knowledge required Per-request FPM isolation One crashed script does not bring down the entire server Strong typing in PHP 8.x Union types, enums, readonly properties, property hooks CPU workload handling Multi-worker FPM means CPU tasks in one process don't block concurrent requests Low barrier to entry Junior developers can onboard and contribute quickly Weakness The Real Impact FPM throughput ceiling Slower than persistent-process runtimes on pure I/O benchmarks Async is not native Requires Swoole, ReactPHP, or FrankenPHP worker mode — not first-class support Inconsistent standard library array_map, in_array, array_filter — argument order varies, no fixing it Perception problem The "PHP is bad" reputation still affects hiring and architectural buy-in Real-time limitations WebSockets and SSE require extra infrastructure in the traditional FPM model Strength Why It Matters Non-blocking I/O Purpose-built for high-concurrency, I/O-heavy workloads Massive npm ecosystem 2.5 million+ packages — there is a library for almost anything Real-time native WebSockets, SSE, live data pipelines — the event loop is ideal for these TypeScript default Large codebases are dramatically safer and easier to refactor Full-stack JavaScript Share types, schemas, and utilities across frontend and backend Fastify and Hono Framework overhead is genuinely minimal at scale Strong corporate investment Microsoft, Vercel, Netlify, and others fund core development actively Weakness The Real Impact Single-threaded event loop CPU-bound tasks block all concurrent requests — this is an architectural constraint Complex async error handling Stack traces in async code are harder to read and debug than synchronous PHP npm supply chain risk Left-pad (2016) was a warning. Supply chain attacks on npm have increased since Tooling overhead TypeScript + ESLint + testing + bundler = significant configuration surface area Memory leak risk Long-running processes accumulate leaks that FPM's per-request model avoids CommonJS vs ESM fragmentation Module system debt has left many codebases in a painful, ongoing migration Scenario Reason Content-driven websites and CMS WordPress, Drupal, Laravel — purpose-built with unmatched community support SaaS products where shipping speed matters Laravel gives you auth, queues, events, broadcasting scaffolding from day one Small teams or less experienced developers Simpler mental model, excellent onboarding docs, cheap shared hosting CPU-intensive background jobs FPM multi-worker model handles mixed workloads without blocking concurrent requests Budget-constrained deployments Shared PHP hosting remains one of the cheapest compute options available E-commerce applications Deep ecosystem (WooCommerce, Magento, Bagisto) — all PHP-native Scenario Reason Real-time features WebSockets, live notifications, collaborative editing — event loop is ideal API gateway or thin proxy layer Non-blocking I/O handles enormous concurrency with minimal resource usage Microservices architecture Fast startup, low idle memory, scales horizontally with ease JavaScript/TypeScript-heavy teams Share code, types, and validation logic across the full stack Developer tools, CLIs, API clients The npm ecosystem for tooling is exceptional and well-maintained High-concurrency I/O without expensive infra Hundreds of thousands of WebSocket connections on a single long-running process After running all the benchmarks, the honest summary is this: For most web applications — the kind that serve pages, handle form submissions, run database queries, and send emails — the performance difference between PHP and Node.js is not your bottleneck. Your database is your bottleneck. Your external API calls are your bottleneck. The framework overhead is rounding error compared to a missing index on a frequently queried column. This is not a dismissal of performance. It is a prioritization of it. The benchmark where PHP was three times slower than Node.js (Hello World) will never matter in a real application, because no real application serves only a Hello World response. The benchmark where the gap narrowed to 30% (database read) is far more representative — and even then, a Redis cache collapses most of that gap entirely. The benchmark where PHP beat Node.js by 4x (CPU task) matters a great deal if your application does image processing, PDF generation, data transformation, or complex calculations in the request path. That result should directly inform your architecture decisions. The right question is not which runtime is faster in a benchmark. It is which ecosystem will let your team ship correct, maintainable software faster — given the specific problem you are solving. Resource Link Why Read It PHP 8.4 Release Notes php.net/releases/8.4 Understand modern PHP before forming opinions on old knowledge FrankenPHP Documentation frankenphp.dev Worker mode changes the PHP performance conversation entirely Fastify Benchmarks fastify.dev/benchmarks Reproducible, maintained Node.js framework benchmarks Node.js User Survey (OpenJS Foundation) openjsf.org Annual adoption and usage data from the foundation Stack Overflow Developer Survey 2025 survey.stackoverflow.co/2025 Most widely cited annual developer technology survey Ryan Dahl — Introducing Node.js (2009) youtube.com/watch?v=ztspvPYybIY Watch to understand what problem it was actually solving PHP: The Right Way phptherightway.com Counters a significant amount of outdated PHP advice State of JavaScript 2024 stateofjs.com/en-US/2024 Annual JavaScript ecosystem adoption and satisfaction data Swoole Documentation swoole.com Async PHP without abandoning your existing framework Matteo Collina — Node.js Performance YouTube Technical and rigorous, directly from a Node.js core contributor I went into this expecting Node.js to win convincingly on performance and PHP to win on ecosystem maturity for web applications. I was partially right on both. Node.js is faster in throughput benchmarks. That advantage is real and consistent. But it is smaller than conventional wisdom suggests, and it comes with a meaningful tradeoff on CPU-bound work. PHP with modern versions and FrankenPHP worker mode is no longer the slow runtime of 2012. What surprised me most was not a benchmark result. It was realizing how rarely the benchmark result is even the right question. Use Case Recommendation Real-time platform (chat, live data) Node.js Content platform or CMS PHP with Laravel SaaS product, time-to-market priority PHP with Laravel High-throughput I/O microservice Node.js CPU-intensive processing in request path PHP — or reconsider the architecture entirely E-commerce PHP Developer tooling or CLI Node.js Budget-constrained team PHP Both languages are alive. Both are actively developed. Both have communities worth being part of. The "PHP is dead" narrative was never accurate. The "Node.js solves everything" narrative was always a sales pitch. Use the right tool. Understand its actual tradeoffs. The verdict is not that one won — it is that the competition was never as simple as people made it sound. All benchmarks were run on Ubuntu 22.04 LTS, 4 vCPU / 8 GB RAM, Docker containers with equivalent resource limits. PHP 8.4.1 with OPcache enabled and realpath_cache_size=4096K. Node.js 22.11.0 LTS with Fastify 4.x. PostgreSQL 16 on localhost. Five iterations per test — high and low discarded, middle three averaged. Platform Link ✍️ Medium @syedahmershah 💬 Dev.to @syedahmershah 🧠 Hashnode @syedahmershah 💻 GitHub @ahmershahdev 🔗 LinkedIn Syed Ahmer Shah 🧭 Beacons Syed Ahmer Shah 🌐 Portfolio ahmershah.dev
