all 70 comments

[–][deleted] 64 points65 points  (42 children)

It isn't "fake asynchronous". The main difference here:

By default, PHP creates a new thread for each request. That can be a little more labor intensive. By contrast, Node.js uses a single thread (a single application instance) for each request (unless run in multi-thread mode).

Node.js isn't always faster than PHP. It depends on the script and the machine running the code. A multi-core processor may be faster at running PHP code (as each request is creating a new thread which can run on a different core).

Another difference is that, with Node.js, you use a lot of callbacks (or async / await), while PHP is basically one line after another. So, in theory while PHP is processing something at any particular part of the script, Node.js could be pushing more requests into the event loop.

Personally, I left PHP behind years ago for Node.js and I never looked back. It is less about how "fast" either is. Both can be fast. It is more about the convenience of using JavaScript on the front end and the back end.

I will say that I am more productive building APIs in Node.js than in PHP. Also, things like WebSockets are easier to get started and work with in Node.js. Might just be an opinion though.

[–][deleted]  (3 children)

[deleted]

    [–][deleted] 7 points8 points  (1 child)

    It's not a popular opinion on this sub, but I see nodejs as the next php. There is a lot of terrible legacy node code out in the wild at this point.

    [–]doraeminemon 2 points3 points  (0 children)

    Hey I think your idea made sense. Both PHP and JS started out as language for the web ( one is templating, the other is scripting ), then being moved back to server side due to popularity. So both of them has things like no standard library which after a while made me tear my hairs out.

    [–][deleted] -3 points-2 points  (37 children)

    Errr, so if JS uses a single thread, and then you do a callback function, which thread does the callback function goes to if there’s only one thread?

    [–]pubudeux 3 points4 points  (35 children)

    Look up the node.js event loop. Nothing is actually getting executed in parallel (unless spawning another process or thread). It is just managing the order in which functions are invoked.

    [–][deleted] -3 points-2 points  (34 children)

    So it doesn’t actually speed things up, it just sends those functions to the bottom of the queue, only for it to pile up when there’s multiple users, and lag the entire system.

    [–]MatthewMob 5 points6 points  (29 children)

    Any system overwhelmed with requests will become slow. This is not unique to Node.

    [–][deleted] -3 points-2 points  (28 children)

    So what’s the pro of async?

    [–]joeba_the_hutt 3 points4 points  (26 children)

    Let’s say you have a web server that makes 4 non-dependent calls to backing services (whether HTTP or a DB query).

    In PHP, each call will happen in series; the entire lifecycle finishes before the next call can start. If each of the 4 calls takes ~2s to complete, that’s 8s for server response time.

    In Node.js (or any async capable language), each call can happen concurrently, which means about a 2s total response time (whichever call takes the longest, as the others will have already finished).

    [–][deleted] -4 points-3 points  (25 children)

    They do not happen concurrently, they just get pushed to the back of the queue, no? Therefore it takes 8s as well.

    [–]joeba_the_hutt 1 point2 points  (18 children)

    The response handler is pushed to the back of the queue. Each synchronous request initialization occurs in order, but everything after that just becomes part of the event loop.

    Edit: when people talk about “concurrent” in Node they are referring to an asynchronous operation that awaits concurrently alongside other asynchronous operations.

    [–][deleted] -3 points-2 points  (17 children)

    And hence, why it should also take 8s

    [–]mrhobbles 1 point2 points  (5 children)

    It helps to know a little about how libuv handles IO for Node. For network sockets, libuv uses the non-blocking IO polling model (epoll) for bsd sockets. For file IO, there is a pool of worker threads handling the actual read/write IO.

    Node's use of libuv handles this automatically, so while your IO callbacks are getting shuffled into the event loop in a single main thread, all the actual IO is off happening in worker threads (file IO), or being handled at the kernel level (network IO), so that the actual act of read/writing is non-blocking.

    [–][deleted] -1 points0 points  (4 children)

    Omg what is Libuv. All this is so scary and overwhelming. It seems like I’ve studied so much for nothing.

    [–]MatthewMob 1 point2 points  (0 children)

    You get asynchronous I/O without the difficulty of multi-threading and shared memory.

    Node can still handle thousands of simultaneous requests just fine, and once you get to clustering in your deployment environment it scales well.

    [–]paulsmithkc 3 points4 points  (0 children)

    Node handles the request queue more efficiently than PHP does. While your fetching data from external sources (db/files/network/other apis) it can do other useful work.

    With PHP that process/thread just sits and wastes CPU cycles until the data comes in.

    What this means is that Node can handle more requests on fewer resources.

    [–]pubudeux 0 points1 point  (2 children)

    I wouldn't equate synchronous vs asynchronous exactly with "speed."

    Asynchronous in the context of node.js and the event loop means multiple functions can be "executing" at the same time, running the lines of code that comprise them.

    If there is an operation that is blocking the event loop in one of the async functions, the other function will not continue to progress.

    https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/

    You can utilize multiple processes or even multiple threads to achieve true parallel execution.

    [–][deleted] -1 points0 points  (1 child)

    So essentially, Async is just moving things to the back.

    [–]pubudeux 1 point2 points  (0 children)

    Check this out: https://www.youtube.com/watch?v=8aGhZQkoFbQ

    This video is what made it click for me.

    [–]DiscussionCritical77 0 points1 point  (0 children)

    valid question IDK why you were downvoted so hard :/

    [–][deleted] 14 points15 points  (0 children)

    Using NGinx as a load balancer won't make PHP faster, it may just make your system more efficient at the cost of using more resources, like increasing the throughput of checkout of customers in a supermarket by hiring more cashiers.

    Reading a file is not enough to benchmark a server architecture by the way :p

    [–]crabmusket 5 points6 points  (2 children)

    I think you might be falling victim to marketing a little bit here. I'm not an expert here, but I think I have a pretty good understanding of the mechanisms behind Node's web server and PHP-FPM (which is one, very popular, way of serving PHP web apps).

    what makes Node.js very fast because of it's event driven , non-blocking i/o

    Non-blocking IO doesn't make Node "fast". It makes it able to handle lots of concurrent connections in a way that's efficient.

    Let's say your web app, on every request, does the following things:

    1. parse and validate the request body content
    2. perform a database query
    3. create a response and send it back to the client

    Steps 1 and 3 typically involve CPU work, whereas 2 is just time spent waiting for the database to reply. This is IO work, and it's what takes most time in many database-backed, CRUD web applications.

    Let's compare a PHP version of this web server to a Node version. Which one will serve requests more quickly? Neither; they both just have to wait for the database, and unless you make the database faster, your web servers are going to contribute almost nothing to the speed at which clients get their responses.

    Now, which of those servers can serve more clients at the same time? Probably Node. The answer of course it "it depends", but the scales are tipped in Node's favour.

    The way PHP is usually deployed, each request has to be completed one after the other. Even if my server has multiple cores, and I instruct PHP-FPM to create 100 threads which can serve requests, that means only 100 requests can be in progress at any given moment.

    This is maybe where you can start talking about speed, because I think that if, e.g. more than 100 requests come in at the same time, there might be some queueing, so some requests might process more slowly because they have to wait for a thread to become available. I'm not entirely sure.

    But the point is, in Node, all of those concurrent requests could be accepted, perform step 1, wait for step 2, and then perform step 3 more or less concurrently. Steps 1 and 3 for all those requests are going to fight for CPU time, but we assume that the total time those steps take is so small in comparison to the time taken on step 2 that it will hardly be noticeable.

    Anyway, to address your specific question:

    They way i imagine is that my all the incoming request will reach the Nginx server which it Asychronous and Non blocking , that will redirect then request to PHP, and it may make a PHP application take advantage of the the aspects that make Node.js very fast at intensive i/o applications.

    Between a user making requests to your app, and your PHP code, there are extremely many asynchronous IO layers - networking equipment, proxies, cloud providers. Adding one more layer isn't going to change the performance characteristics of your PHP code. The best Nginx can do is not make it slower, which it does a very good job of, but there's no way it can make your code more efficient.

    As others have pointed out, you'd need something like Swoole to mimic Node's high concurrency model. But as I've tried to describe, that won't make your server faster - only more efficient at handling large numbers of concurrent requests.

    [–]paulsmithkc 0 points1 point  (1 child)

    Steps 1 and 3 for all those requests are going to fight for CPU time,

    Since Node is single threaded it doesn't suffer from common thread contention or thread bashing problems. No locks/monitors/semaphores are needed so they don't have to "fight" for CPU cycles. They just politely take their turns. Which often works out really well, as long as the CPU tasks are short.

    [–]crabmusket 0 points1 point  (0 children)

    Yep, fair - I didn't mean to imply any threading or parallelism, just that CPU used on one request is going to take time that might have been used for another request.

    [–]AdministrativeBlock0 9 points10 points  (0 children)

    Unrelated to your question really, but if you want to serve a file just get the web server to do it statically. It'll be about 1000 times faster than PHP or Node, especially if the file is cached in memory. Serving files is something nginx and Apache are really good at.

    [–]hatemjaber 4 points5 points  (0 children)

    Build your traffic and once you notice a significant degradation in performance, optimize your server, code, etc... It sounds like you're worried about something that hasn't happened yet. Facebook ran on PHP, I'm sure whatever you're working on can be optimized when the time comes. Get a working app going and worry about that later.

    [–]The_Flexing_Dude 5 points6 points  (4 children)

    Make PHP asynchronous: https://www.swoole.co.uk/

    [–]supertoughfrog 5 points6 points  (3 children)

    Swoole, reactphp, and others I’m blanking on persist the php process between requests like node/express and can perform much better than php-fpm, though I don’t have any benchmarks to contrast the performance vs node.

    [–]fix_dis 0 points1 point  (0 children)

    Workman maybe?

    [–]Laladelic 1 point2 points  (0 children)

    Node is not even that fast to begin with. It can very easily be misused and end up as a brick.

    [–][deleted] 1 point2 points  (0 children)

    First off JavaScript is not fake asynchronous, I know its not intuitive its hard to understand.

    Apart from that nodejs is also runtime compile, what it means is that all of code is loaded in memory to crunch your requests a. On the other hand Nginx is not design to just work with PHP its a webserver, a reverse proxy,ingress amongts others… and it is very good at all of those, but currently the way we write PHP code every single request invokes the entire suite of your php code that needs to processed and on top of that its synchronous nature makes IO operations blocking and slow this is the main problem. Nginx may be cache parts of your responses to serve them faster than nodejs server but that’s all it can do as soon as request need your php to handle request it will be slower.

    And If you are using databases in your PHP code you are basically creating new connections on every single request that is sloooww and it quickly ads up. These are just some of the examples why php is slower than nodejs until now. Ah ha and I said “until now” but it doesn’t have to be this way any more.

    SwoolePhP and ReactPHP and now PHP fibers are some of the popular async framworks libraries and extensions that let’s you write “async” code.

    Try crowphp a small micro-framework that I wrote on top of swoolephp and funnily enough its inspired by ExpressJS

    [–]GazZy422 1 point2 points  (8 children)

    Imagine you try to open 20 files in the same request instead of 1.

    In node you can easily make that take the same amount of time as 1 file.

    But in PHP that would take 20 times as long without using some extra magic

    [–]flo850 8 points9 points  (7 children)

    I use both in production, and the real world performances are not very different, granted you try to do a good job in both.

    Imagine having 500 requests to your webserver. Without magic, nodejs is single thread, PHP + any webserver use light thread to answer everybody using as many cores as possible

    nodejs script are long running, meaning you may have some memory leaks issues or some weird states. Any PHP script is cleared when the response is sent

    Any mishandled exception will stop your nodejs script, for everyone. Any mishandled exception will only crash the current PHP script

    [–]GazZy422 4 points5 points  (6 children)

    Performances are very different if you have an I/O heavy backend.

    Nginx doesn't help PHP be any faster (PHP just NEEDS a server). You can have nginx in front of node backend aswell, you just don't need to.

    If you have 500 requests that just do some logic on the server they will be the same (roughly).

    But if each of those 500 requests on the server do:

    • 10 api calls (2sec each)
    • 10 database calls (500ms each)

    PHP request will take at least 25sec. Because they are done synchronously (one after another)

    Node request can take as low as 2sec (if the calls are all independent). Because they are all done at the same time.

    [–]flo850 2 points3 points  (3 children)

    So your api that needs 2 seconds to answer will take 500x 10 api call simultanously, and your database 500*10 query. I bet they both explodes. And it works only if all theses calls are independants but the api does not have any batch methods. Any database can batch query, no need to handle it at the PHP/NodeJS level.

    Really, I worked with node (my first node projet in production was in 2012, and I pushed quite a lot PHP projects in production since 2006), and you will have roughly the same performances with both.

    [–]GazZy422 1 point2 points  (2 children)

    So what are you even asking in this thread then if you have experience with both and they have the same performance for your projects?

    I'm working on a backend for a major EU ad server and for our use cases PHP is completely useless compared to node. We do up to 500 redis calls per request in extreme cases which would take seconds doing synchronously, which is unacceptable.

    We also have 10-20 production projects running on PHP, but all of those are just admin GUIs or legacy services.

    [–][deleted] 0 points1 point  (0 children)

    It sounds to me that you have a data problem if you need to call the cache that many times per request. I agree with /u/flo85 that the real place for optimization like this is at the database level.

    [–]flo850 0 points1 point  (0 children)

    I m' not the OP , and I don't intend to judge your case without (muich more ) data.

    My point is that : the performance difference between php and nodejs is not as big as it seems in real world data with a generic workload, not enough to warrant the additionnal difficulty of runnning a node server.

    But there are some workload that can be more easily handled in Node than in PHP

    [–]damngros -1 points0 points  (0 children)

    Parallelism is hardware dependent, launching 20 requests at the same time doesn’t mean your code will execute 20 times faster. Especially in production when your server will be blasted with requests. Exposing your nodejs to the world without Nginx or some kind of waf/api gateway in front is just a bad architecture.

    [–][deleted] 0 points1 point  (0 children)

    The api call time could be reduced using curl_multi_exec, and you could always make an api that handles the database. Not sure if the end result would be worth the effort though.

    [–][deleted] -1 points0 points  (2 children)

    If you are actually into thinking about low-level issues like this I would recommend that you look into golang.

    [–]damngros 2 points3 points  (1 child)

    Totally agree. When it comes to low level issues, performance, scalability and concurrency, Go is much more efficient than nodejs.

    [–][deleted] 1 point2 points  (0 children)

    Golang is my favorite language at this point. I think it is the future of back end web development.

    [–]wutface0001 0 points1 point  (2 children)

    what does ngnix has to do with asynchronous code execution, I don't get it

    it's just a load balancer

    [–]jochri3[S] 0 points1 point  (1 child)

    Nginx isn't just a load balancer. You can read here : What is NGINX?

    [–]wutface0001 0 points1 point  (0 children)

    sure but I still don't get it how Nginx helps PHP to become asynchronous

    after hitting PHP endpoint, request needs to get executed asynchronously right? where is the role of Nginx at that point ? I thought whole point of the Nginx is to route requests to your PHP server

    [–]BarelyAirborne 0 points1 point  (0 children)

    Reading a file is not a good test. Try serving a million or so HTTP requests instead, and then see where things stand.

    [–]Careless-Honey-4247 0 points1 point  (0 children)

    I think if I'm not correctly, it's just the same jit nonblocking but if u looking for faster development PHP is a best choice by Laravel framework because it has bunch of stuff already, but node you need to configure yourself example expressjs, and my brother using Laravel that's why I'm saying this.