6 ms·
So, I've used Rails (ruby), Django (python), Flask (python) Revel (go), Spring (java), Node.js (javascript), and even have used C, php and Go to roll my own web
by lettergram 9y ago
So, I've used Rails (ruby), Django (python), Flask (python) Revel (go), Spring (java), Node.js (javascript), and even have used C, php and Go to roll my own website from scratch[1].
The thing is, I've always scaled my website(s) to thousands or tens of thousands of requests and hour; with one website even getting close to a million an hour... all with no problem. In the case of Rails (as is discussed in the article), my bottleneck (from a usability perspective) is always bandwidth. Most applications (I build anyway), require a hefty amount of data. Waiting 200ms for the database + an additional 20ms for rendering, the 20ms is not noticeable. Scaling Rails (or any modern web app) is as easy as just launching another instance and load balancing.
Given that, I really don't see any advantage toward Phoenix. Plus, why I personally love rails is all the gems - which is super powerful. Most other frameworks simply don't have Rails simple logic, with the easily extendable gems.
[1] http://austingwalters.com/building-a-web-server-in-go-handling-page-requests/ http://austingwalters.com/building-a-web-server-in-go-handli...
- TomK32 9y agoTbh, 200ms for the db is massive. I have a 100ms limit at which my mongodb writes into the slow-log. It's an almost empty log. My point being, apps can have all sorts of bottlenecks and you only have to throw the right brain at the problem to fix it, no need to replace the techstack. Yes, gems. The ecosphere in ruby is superb. I'm started working with node a lot more these days and it's a) confusing and b) small packages for all those things whatevertheycallitthesedaysscript is missing. 243 gems in my 7yr old Ruby vs 918 node modules in an app we started this month. What's Elexir/Erlang like in this respect?
- merb 9y agoeven for "old databases" (mysql, postgresql) 200ms is huge or to it differently say probably his database is not the bottleneck. He probably fetches big lists, and even lists with over 100 entries are extremly slow on python/rails, whatever. on java/c++/go/rust these things are way faster.
- lettergram 9y agoThe database doesn't need to be an issue - it just currently is. We have a fairly complex query on a several terabyte large PostgreSQL database and didn't want to spend more money. Basically, we just haven't sharded it yet, and don't want to pay for a larger machine. The point is - typically the issue isn't the web app. Almost all web frameworks are designed to be scalable from the start. Just launch another instance. Also, we do about 99 writes for every 1 read, so query times don't matter as much. For the given app I was using as an example. Network I/O and large databases are usually the bottlenecks from what I've seen consulting and developing.
- ezekg 9y agoMySQL and PostgreSQL are considered “old” now? I’d guess that’s much like Rails being considered “old” and “legacy.”
- tychver 9y agoThis was probably true 10 years ago, but these days it's basically FUD. Since then Ruby improved performance something like 5-80x from 1.8 to 2.5 and moved from an interpreted language to a VM nearly as fast as LuaJIT. Go only has 3-5x the throughput for tasks like: grab 100 rows from PostgreSQL, serialize to JSON, respond via HTTP. Lots of the hot code in Ruby around fetching rows from the DB, serializing to JSON, and HTTP parsing have also since been implemented as native functions in C, massively improving performance with zero effort required by the developer.
- merb 9y agoyeah this is cool, until you make a single map...
- tychver 9y agoDo you mean: "take a few thousand rows and map them to a different data structure"? Because I benchmarked that recently and mapping 16,000 rows of GPS points using haversine distance in pure Ruby takes about 12ms, and about 5ms in Go. It's not that much slower. There are tasks where Ruby can be ~100x slower than Go, but a simple map isn't one of them.
- mrisoli 9y agoI share your opinion, if you have any bottlenecks which are unsolvable because of Rails or Ruby being slow your app probably scaled up to a point where you have the resources to make a creative solution that is not Phoenix/Elixir. Having said that, while I don't find any major reasons to opt for Phoenix instead of Rails, my main reason to work with Elixir/Phoenix right now on side projects is that it won't make me unlearn Rails which I can always go back to, in fact, using Phoenix for a while made me miss a lot of the available libraries, plug-in solutions and wide range of community knowledge. So ATM I have more reasons to choose Rails over Phoenix, but I suppose that's why these sorts of articles are important, publicity to increase a community and fulfill Elixir's biggest need right now.
- mooreds 9y ago> in fact, using Phoenix for a while made me miss a lot of the available libraries, plug-in solutions and wide range of community knowledge. This is my main reason for focusing on Rails rather than Elixir at present. The sheer breadth of gems available for rails to quickly build sophisticated applications is hard to beat for any up and coming language/framework. That said, my gut feel is that many of the developers who build and maintain these gems have moved on and that Elixir is the new hotness and will probably catch up in the next few years.
- regulation_d 9y agoI wonder if you might extrapolate on which libraries, plug-in solutions you missed in Phoenix.
- phamilton 9y agoI mean... 1 million requests an hour isn't that many. That's around 300 requests per second. Assuming 1000ms upper bound on requests, you need 300 workers to handle that load. Assuming 150MB per worker, that's 45 GB of memory required to handle the load. So like... 5 m4.xlarge instances on EC2 (to give redundancy and allow loss of 2 hosts). That's $700/month. That's not that much. We've got a Rails app that pushes 5000 qps. And to be fair, we just dial up the number of instances and it handles it fine. It runs on over 100 instances. It costs us around $10k/month. Not the end of the world, cost wise, but we have multiple Go services that handle similar levels of traffic and run on a dozen instances. Additionally, deploys take a long time (rolling restarts plus health checks on 100 machines takes time). Moving to Go (or Elixir) allows us to handle far more requests per unit of hardware. While latency would indeed improve, it's not the primary motivator for us moving away from Rails. I haven't even mentioned the websocket story on Rails. That's a whole new can of worms.
- meritt 9y agoDo rails apps actually use 150MB per worker or was that just a lofty ceiling estimate? Or is that with an app server that doesn't utilize process forking, and loses the benefit of shared libraries/heap/etc?
- gkop 9y agoYes, they often do :/
- tychver 9y agoYes, but you only need one process per core, just like NodeJS. Since 1.9 you can use real OS threads to achieve parallel IO, and certain parallel computations which can proceed without holding the Global Interpreter Lock. JRuby offers completely unrestricted threading with a single process, plus a 3x performance boost, plus the advantage of an incredible amount of work put into their VM and GC. It's a really underrated option these days. The problem with forking, is MRI Ruby is unaware what memory is actually inherited by forking, so eventually it causes the entire heap inherited from the parent to copy into the child. I'm actually working on a patch to fix this. The solution is simple, just don't mark, collect, or allocate into inherited pages, but the implementation itself is fiddly. What's really exacerbated this, is that most Linux distros now have Transparent Huge Pages turned on by default, and flipping a single bit in inherited causes a 2MB copy instead of a 4kb copy!
- sanderjd 9y agoMy bottleneck with Rails was always memory usage. Our concurrency was always limited by how many web and task workers we could run in the amount of memory we could afford, which was not very many. It was not straightforward to optimize this and ignoring it didn't work for us, so we put lots of time into it and it changed the whole productivity argument for Rails.
- 33degrees 9y agoAgreed. I have a sidekiq job that imports data into elasticsearch from a mysql database using activerecord, and it uses hundreds of megs of memory, which is ridiculous considering how little data is actually being imported.
- sanderjd 9y agoYeah we struggled to keep our memory usage under 500M per worker. Sidekiq helped because it was able to use threads effectively, but especially when we were running resque workers, we could only handle tens of tasks per second, and often fell behind. I think Rails' autoload-the-world philosophy was a big part of the problem and we spent some time trying to untangle dependencies, but it was swimming against the stream. I'm not sure if these same problems do or don't come up with Phoenix, but when I briefly used it, it did seem to have a smaller memory footprint.
- tychver 9y ago500MB per worker is totally standard. What happens is a job causes a huge array or hash to be allocated, and after it‘s finished the memory can’t be returned to the OS due to heap fragmentation. Java does some crazy stuff with compaction. C programs typically try and internally allocate into arenas to avoid it.
- 33degrees 9y agoThe thing is we're not even using rails, it's a simple Sinatra app with ActiveRecord, so there's not much being loaded that's not being used. Could be the ActiveRecord itself is the problem though.
- biokoda 9y ago> Waiting 200ms for the database + an additional 20ms for rendering Those are pretty awful numbers. https://blog.gigaspaces.com/amazon-found-every-100ms-of-latency-cost-them-1-in-sales/ https://blog.gigaspaces.com/amazon-found-every-100ms-of-late...
- qaq 9y agoWell there is always question of $ if running on Phoenix would let you save $100/month it's one thing if it's 100k/month things might look a bit differently and when it is 1 mil/ month things that will change equation even more. (This is not going into areas were Ruby is not a usable option such as massive real time apps etc.)