I wish the author dove deeper into "does ruby scale" with hard numbers instead of pointing at big companies.
If Shopify, Github, or Gitlab wrote their code in golang or rust, would they need less CPU and memory? Would they have less bugs? Are refactors fast? How has RoR's ever changing JS ecosystem impacted these organizations?
If they’d written their code in golang or rust, they’d have been out-competed by a competitor who iterated faster and got better product-market fit. The only reason the three companies have the opportunity to suffer from scaling challenges is that they were wildly successful.
Your comparison does not really make sense to me or I am perhaps missing your point. PHP and Ruby are in the same category of fast response loop and ability to develop quickly.
Having worked for one of those company's, I think the productivity of Rails is overstated. Yes it's quick to get a rough demo and POC working (which is already plenty quick in many other frameworks) but once you get into the weeds of actually building and iterating the difference is not so great. I think particularly if you look at these established companies, what tech stack they are running often is just a matter of what the founders knew at the time. The business wasn't successful because they chose Rails, it was a successful business who happened to pick Rails to start with.
I don't even think that's it—as convenient it is to explain—if someone knew exactly what product they were building java would have done just fine. Realistically scaling just isn't a bottleneck for most companies at the beginning. Excepting maybe, maybe, twitter.
Looking at big companies is a bad metric if you're not a big company - or at least a rich one. Startups and in general smaller companies need to be very efficient with their developers, because they can't get many. Big companies have other issues, eg coordinating the work of thousands of developers, and choose their tooling accordingly.
Not that bad metric if you consider they had to start from something.
The argument on "rails dont scale" is that eventually you need to rewrite it. Which isn't actually true as there are many companies that continue to use it even though they've scaled, in product usage and employees.
We will never know. What we know is that it didn't harm them.
Add Twitter to the list. They started with Rails, then switched to something else. Too many background jobs, Ruby is not ideal for that. However they became Twitter and owned that space before having to switch so Rails didn't harm them too.
I worked in one product that a "simple" re-architecture from rails 3 to rails 5+(async-as-most-as-we-can) was more than enough to handle MAU into millions and simultaneous sessions in high thousands. Enough for a big exit for the founders indeed and having an edge against other players using golang, but with double the headcount than my case.
We also got 98~100 lighthouse by using pure JS with sprinkles of stimulus after the initial rendering.
Thousands of simultaneous sessions isn't all that many, if you are scaling your infra to dozens of servers. Can be handled by a single server, if code is optimized.
Doesn't matter. Whether you use Python, JS, PHP or Ruby, you will need to reach millions of users before perfs become a problem for a typical web app because the hot path are almost never coded in the language.
It's not a ruby thing, it's just that servers are beast nowadays, and cheap.
Servers cost, but server cost in absolute terms hit few people before you're big enough that the cost of capital to address it is far lower. And almost any money you invest in trying to minimise server costs at an early stage will end up going out the window because the features you end up needing at scale and that end up costing money to scale will tend to look entirely different from what you started with.
So even if you need to switch languages down the line, I'd argue you should pick your initial tools based on what lets you iterate fastest early on, not based on what will keep your server costs down the line. Assuming of course what you pick is fast enough for whatever you want to do.
Put in more concrete terms, based on the actual VC deals I've been on one or the other side of the table for, the cost of capital drops to anything from 1/2 to 1/10 per early round if you're doing well. If you do well enough that your server cost is becoming a problem, by the time you need to address it paying to address it ought to not be a problem unless your decisions were truly pathological.
Most companies don't survive long enough for this to become a problem.
In other words, while performance matters, the value of performance now to an early stage startup is often really low compared to speed of delivery that might improve your odds of actually surviving to a point where performance becomes a problem, and you might easily be willing to trade 2x, 5x, even 10x the total dev cost in cash to deliver faster if you can defer a significant portion of that cost a few years down the line assuming you survive that long and your cost of capital in terms of proportion of equity is a tiny proportion of what it is at the start.
This is not an argument for Rails, btw. This is an argument for whichever tool is fastest for YOU and YOUR team to deliver with. If you have multiple alternatives you're equally productive with and one of them is more performant than others, of course pick that one.
This debate has been going in circle over and over. It's the same arguments than 10 years ago, and the answers are the same.
No it's not saying bad performance doesn't matter.
Yes Go can make application more responsible.
But you have to balance out a lot of compromises in a project, and Pareto tend to favor those languages in the majority of situations because of cost, skills, resources and constraints.
> How has RoR's ever changing JS ecosystem impacted these organizations?
As much as I think RoRs initial love for coffee script was a mistake (although it certainly did help at a time when javascript was in a horrible, braindead place) - I'm not sure I'd like the js mess at Rails' feet.
I think that the team navigated js integration as well as could be expected - and everyone was happy in version 7 when js support in browsers had advanced to the point that most of the special handling could simply be ripped out.
The remaining issue IMNHO is that there's no browser support for typescript - and using ts dictates a build pipeline which would otherwise be needless complexity with modern js and js modules.
Before modules, "let"/"const", uniform APIs cross browsers (xmlhttprequest, anyone?) - js was much, much worse. Rails dates back to before 2005 - before chrome existed, and around the time Firefox emerged from Netscape.
I was serving a big database of information to up to 1000 concurrent users on a 10$ cloud server without bigger issues. I don't think many projects get to a 1000 concurrent connections point ever.
IMO when you work with it properly it's so little of an issue (especially compared to the Dev time saved) that most Rails Devs simply don't care about the 'ruby doesn't scale' talk
Because of my career path spent almost entirely as a consultant and now working with lots of startups, I must have seen 100+ web application builds.
The productivity of Rails absolutely trounces JS-framework-de-jour in my experience. It’s almost certainly the framework I would be recommending for a CRUD app, which covers the vast majority of business software.
A web framework can be conceived as a selection of design choices already taken for you. The choices RoR does for you are extremely successful and very simple to understand, hence the name: you are developing "on rails" and as such you build things much faster.
This was very true more than a decade ago before the Node revolution adn when the alternatives where Struts or Spring MVC in Java, or Zope with Python. Fast forward to 2023, I would say that other platforms have caught up a lot, but my personal opinion is that Rails still has the edge.
Sane defaults for most (all?) aspects of the run-of-the-mill CRUD app, a.k.a. "convention over configuration". Helps focus development energy on solving the problem at hand as opposed to on bike shedding or being slowed down due to decision fatigue.
AFAICT, one has to go with the conventions as far as possible. Straying off the beaten path can lead one to lose time fighting the framework.
Yeah that was first thing that struck me about Rails, I had kept hearing "batteries included", then DHH suggests rolling your own auth? Always seemed a strange gap.
Django provides built in auth that is pretty great and extensible. OAuth/SAML and canned or customized registration flows are just a matter of adding the django-allauth module.
No. My point isn’t about using devise (I’m almost certain that’s what ChaGPT recommended). My point is that if you actually attempt to do both (code a simple app using ROR vs. another framework), you’ll find ROR just works 95% of the time. You might not like Ruby, or the syntax, or how a lot of what’s actually happening isn’t obvious. But to people who need to standup and build an MVP in a weekend there’s nothing that allows you to do it as fast.
It makes doing the standard thing extremely easy. It also removes much of the repetition (problematically so at times!)
For example working on a typescript next.js app, you'll have definitions in your Prisma schema, you'll have some form of model wrapper to load and save your model instances, and you'll have front end code to render your model instances.
All of that is gone with rails. The default is that your schema defines the attributes of your model, and your model has no code. If you scaffold your controllers, your entire app consists of a set of routes, a schema file, some empty model files, a default controller, and generated views.
I am admittedly a rails expert, but I could redo most of the typescript apps I've worked on in a few weeks as rails apps, but not so vice versa.
That being said, these days I mostly choose Typescript because the long term sustainability of a flexible type system beats the short term productivity gains that rails builds in for you.
But if I was building a prototype or wanted an MVP as fast as possible because I was bootstrapping with my own money, I would reach for rails. There's no better framework for discovering what your customer actually wants to pay for.
You get built in support (and "couple of lines in config file" integrations with several popular options) for things like: auth, xsrf protection, database access, queues, logging, email, file storage, testing, cli tasks, and countless other things. There are other language ecosystems that have something comparable: notably Python with Django and PHP with Laravel. But most don't have anything nearly so complete.
Of course all of these things are achievable in other languages/frameworks. But they require quite a bit more setup, and those setups end up being much less standardised across projects. IMO this doesn't tend to make too much difference over the long term, but something like rails definitely makes it quicker to get started.
There's also the factor that while some of these things also exist sometimes in a more automated way than with Rails, the way Rails does them still seems to come out ahead.
The specific example I've got in mind is database migrations. The default with Rails is that you write them yourself, and the model then interpolates what it finds in the database at runtime. With Django, the pattern (again, by default - but defaults matter) is that you change the model and the migrations are generated automatically. The model is the source of truth.
I haven't figured out exactly why yet, but the way Rails splits the responsibilities seems to be much cleaner to me. I'm always slightly uncertain about what Django is going to do. With Rails the database feels closer to the surface, rather than something handed entirely over to the framework.
I really don’t follow this. It sounds like you are favouring what you are familiar with, and are back-solving a justification.
You’re essentially describing a declarative migration system which on the face of it sounds reasonable. It sounds like you’re dismissing it on this property. After all, the underlying DDL is…declarative, for the initial tables, anyway.
When you create a new migration, Django will tell you which actions it’s written into the migration file, i.e. the actions it thinks need to be taken to get from A to B. I don’t see anything opaque about that?
You can also look at the migration file yourself. It’s entirely readable. You could even write your own if you wanted to.
The Rails community seems to still be carrying a very peculiar compete-with-Django attitude from back in the heyday. I see it all the time here. It’s ridiculous.
Maybe I am? I'm not sure. But there is a philosophical difference here that has practical impacts. Django says "the model file is the source of truth". Rails says "the database is the source of truth". My gut feel is that the former creates a situation where you're more reliant on the quality of the abstraction, and putting the database entirely in the control of the framework is what you expect.
> When you create a new migration, Django will tell you which actions it’s written into the migration file
Yes, that's the point. With Rails, I tell it what to do, and if my start point is a specific change I want to make to the database, that's an easier starting point than having to first translate the problem from the database into the model, so that the abstraction can convert it back again, for me to double-check.
> The productivity of Rails absolutely trounces JS-framework-de-jour in my experience. It’s almost certainly the framework I would be recommending for a CRUD app, which covers the vast majority of business software.
Rails is certainly productive in the early days of building something, because so much of what you need is already built. But as time goes on that productivity edge vanishes.
It's far easier to build slick modern UIs in other frameworks, and there are now Typescript frameworks (e.g. Remix) where you can use the same types (and get type safety, IDE auto-completion, IDE warnings, etc.) across the entire stack (it's amazing!) The fact you don't need import statements to use code across a Rails app feels like a blessing at the start, but as the codebase grows, it can become a nightmare trying to figure out where something is defined or how something has been altered. The lack of typing leads to way more maintenance - I have Rails apps that are years old and I still get regular error notifications (method doesn't exist on nil is a particularly common one) whereas I have Typescript apps that I built a few months ago that have never triggered an error ever. The list goes on.
The world turns, frameworks come and go, and the heyday of Rails is over. I don't know why this is a problem for people, quite frankly. If you didn't want to learn new things, then being a software developer wasn't the right career choice, and you were probably told that on day 1!
Implying that anyone touting the benefits of an established technology is against learning is just intellectually dishonest. Being able to tell what is and what is not worth looking further into is a mark of a seasoned expert in any field.
And most of the newer things are more or less the same thing as the old, except different. Sometimes that's good, sometimes it's not, and often it either depends or doesn't actually matter all that much. The trade-offs are often different, but it's of course fanatically denied by the zealots who claim that the trade-off doesn't even exists in the first place.
> The world turns, frameworks come and go, and the heyday of Rails is over. I don't know why this is a problem for people, quite frankly. If you didn't want to learn new things, then being a software developer wasn't the right career choice, and you were probably told that on day 1!
Nobody asked your opinion on who could be a software developer. Stop being a gate keeper and let people make their choice on what technology works for them.
> The lack of typing leads to way more maintenance
Surely you are joking, maintenance is THE downside of the node ecosystem if I had to pick the biggest one.
At work we have a roughly 50/50 Rails/React app but on the maintenance side though it's 20% Rails / 80% React. The package churn in the node ecosystem is absolutely insane and just keeping up with it is almost a full time job. And to add even more to the maintenance burden, on the node world the packages are rarely tested well (if at all), you are building on moving sand and theoretically you would need even more testing than in the Rails part to compensate that.
I'm not saying Rails has the best maintenance story, far from it but it's not nearly as bad as anything JS based.
The fact you don't need import statements to use code
across a Rails app feels like a blessing at the start,
but as the codebase grows, it can become a nightmare
trying to figure out where something is defined or
how something has been altered
Are you willing to share examples?
I was a Rails developer for a long time and it certainly has its pitfalls. But I don't feel that this was one of them and I certainly don't think that explicit imports would solve this problem for you.
Do you have a bunch of global variables (or external data stores like Redis caches etc) being modified by only-God-knows-what? I don't know how explicit imports would solve that. I'm not sure how "import Foo" versus "Foo=42" is going to help you, unless perhaps if you've given your global thing an identifier that is impossible to grep for.
You can also have the behavior you want in Rails, anyway! You have full control over autoloads! Put your code in a non-autoloaded folder. Boom, now you have to explicitly `require` it before using it.
The lack of typing leads to way more maintenance - I
have Rails apps that are years old and I still get
regular error notifications (method doesn't exist on
nil is a particularly common one)
Static typing isn't your answer.
Unexpected nils/nulls/whatever are a runtime error, and are almost always caused by some external resource (typically, the results of a database query or maybe an external API call) being unexpectedly nil, coupled with a sloppy lack of proper exception handling.
I don't care how iron-clad your language's type system is, it won't magically help you handle unexpected external runtime data or make up for a lack of exception handling and/or testing.
> a CRUD app, which covers the vast majority of business software.
Saying that most business applications would be CRUD applications doesn't reflect the reality very well. While technically everything could be broken down to CRUD operations, this term becomes pointless once a relevant amount of business logic is needed to perform the final (database) insert, update or delete. There is a reason why Domain-Driven Design exists (and RoR is, by the way, not the best framework to apply it).
ruby is strongly typed, in that it doesn't allow you to implicitly coerce between types*: 1 + "1" will raise an error. (As opposed to weak typing in C or JS)
ruby however is not statically typed.
*(there are actually ways to implement certain types of coercions by defining to_ary, to_str, to_int)
Having seen how well typing works with python and FastAPI - I'm afraid the current path ruby is on isn't great, unfortunately. It feels extremely bolted on - but I hope something useful and enjoyable will come out of the various typing efforts.
There's no type annotations (outside of experiments), and thus no way for a "compiler" step to tell you if you're passing an array to a function that expects a string or something. The "strong" typing doesn't happen until runtime, so the closest you can get to this is writing a unit test that asserts on the behavior you want (assert that this method raises an exception when I pass an array, etc.) This is what people mean by "typed languages". Ruby isn't one of them.
> Well, if neither of them can differentiate between Ruby and Ruby on Rails, please bear with me; I might mix a few things up as well.
This made it sound like this was going to be a pretty detailed text, but instead it didn't say much of anything about Ruby or RoR. The author could have gone a lot deeper into what he loves about both.
I built my startup in Rails. I eventually re-wrote the entire application in Go as a monolith. In my experience, Go is just as productive if not more productive due to fewer errors at runtime. My day to day life is a lot better with Go-- no more exception emails, firefighting, etc.
I really liked Rails and used it for several years, but Go came when Rails was making things difficult.. Ruby's heap memory kept growing and not being released or released too slowly. My server was using 12 GB of RAM and could hardly handle 300 concurrent users.
The Go version uses 25 MB of RAM and can handle many thousands of concurrent users.
edit:
I understand the memory/concurrency issues are not Rails' fault entirely. It's likely ActiveRecord and Ruby as a VM that caused most issues, but it's part of the Rails deal. Getting good concurrency with Rails isn't easy, and memory issues are real.
Using github stars and some kind of proxy for popularity/usage, Beego looks to be number 2. Seems like it could be production worthy and probably is being used somewhere.
I've spent a lot of time doing Rails and Go, and I also find that on balance, it doesn't make that much difference. It's hard to measure though.
I'm not "against" frameworks, but there are up- and downsides. E.g. in Rails I had quite some trouble with complex forms, which eventually resulted in form_this[1], which actually worked pretty well for the application I was working on. For a lot of apps you don't need this kind of thing, but when you do, it's quite difficult to do something outside the Rails "happy path". Maybe newer versions of Rails handle this better; I haven't really kept up.
I found the Rails codebase rather tricky at times. You get things like:
[:method1, :method2, :method3].each do |name|
define_method name, [..]
define_method "#{name}=", [..]
define_method "#{name}_foo", [..]
end
And it's really neat you can do that in Ruby, but it can also make a codebase kind of tricky to debug – it's the old "you need to be twice as clever to debug code than to write it". While I generally found Rails to be pretty good, it does have bugs and quirks.
On the flipside with Go you spend a bit more time writing your own code, but that code will be better suited to what you're doing. Sometimes people seem to be afraid to write code, but I found it's not a bad thing and "do it yourself" can be quicker and better than "adapt existing thing to your needs".
On balance, it seems to more or less cancel out. Maybe there's some difference one way or the other, but it doesn't seem to be huge.
Rails form helpers really leave a lot to be desired because they’re difficult to customize without jumping through a lot of hoops.
I wrote a clean sheet Rails form helper library at https://github.com/rubymonolith/superform that’s completely customizable and even permits its own strong parameters.
If you measure productivity by how many features you can push in a week, Rails will probably win every time. I look at productivity in the long run. I have been running this product for seven years now and there's a lot of legacy business logic and cruft.
The Rails application was difficult to change (but easy to pump new things out). As the product matured, fewer new features were really needed so the edge Rails had was gone and all that was left was an application that was hard to change without breaking something.
Go's edge came in and reduced the server's memory footprint and was easy to maintain and make changes. If the Go code compiled, I was confident it would work (I never felt that way with Rails).
To answer your question directly: I didn't use any framework. My application only has two external dependencies: gorilla/securecookie (cookie encryption) and lib/pq (database driver for postgres).
I could probably do without securecookie, but I was hesitant to do anything encryption related on my own.
Rails in a way is built on top of ActiveRecord so if AR is the culprit Rails is the culprit too. 300 people working together on your server and almost taking it down seems too low. Maybe you didn't use Rails in the right way but you already found your way with Go, so all is good.
300 active users is hardly any-- but keep in mind my product had a very active API and a browser plugin (which was basically a Rails view in an iframe) that users used often. A single user could easily hit the server hundreds (or thousands) of times in a minute.
Ok, so it's not the typical Rails app. I was thinking about something with long CPU bound operations inside the controller or in background but a lot of hits per user is like having to serve at least 100 times more users.
what did you use for view layer with Go? whatever I could gather looking at the Go ecosystem it seems you have to go with a JS framework for view layer and write APIs in Go.
Rails' deep integration with view layer unlocks a great level of productivity.
Actually, just remembered why I haven't used it. Although it "Ships with IDE autocompletion", last time I checked that's only on the Go code, not the HTML. Usually I keep my templates as .html files, and find the IDE autocompletion and linter on the HTML more valuable
I don't want to say "there was something horribly wrong with your code" but "there was something horribly wrong with your code." I've worked on a lot of large rails codebases and never seen anything close to the performance numbers you're describing.
To each their own though. IMO Rails is significantly faster when it comes to being able to get a complete product to market with all of the trimmings. When it comes to specific programming problems here and there a lot of languages will be able to get the job done.
That holistic "get everything done well with a small team so we can be profitable" scenario is where Rails outshines most everything else.
Plus, if you're concerned about the runtime, just switch to JRuby.
The code itself wasn't very complicated but there was a fair amount (~15KLOC of Ruby). I'm sure there were issues in there, but I could never figure out what they were. I am not a terrible Rails developer either-- prior to building my product I had done Rails professionally for five years at a startup.
It's not like I was slinging Rails code like a bootcamp graduate :)
You probably wouldn't still have a startup if you started by building it in Go, though :)
The rewrite was definitely a good idea by the sound of it, but of course you had prototyped your way to a stable vision of what you actually want the monolith to do using RoR. Good Job!
Say what you want about RoR, but it’s certainly getting some of the most exciting updates as a framework. My favourite one is this https://hotwired.dev. DHH clearly wants to move away as much as possible from JS, and I love that.
Or, you could use Elixir/Phoenix/LiveView, and have a javascript-free interactive fullstack framework that can do everything rails can do, except it is faster, scales _much_ better and maintenance is easier.
For now Rails has more gems than Phoenix for a quickstart within the first days, but this quickly turns around when stuff gets complicated and you need to "optimize" ruby code instead of shipping more features, or when you want realtime that doesn't suck.
It's like where DHH wants to end up with Rails, but available here and now, with a better technical foundation.
I'd say there's pro and cons to each side. Rails is definitely easier to recruit for which is not negligible and while I really like Ecto changesets concept, ActiveRecord has a better mapping to complex queries.
On the plus side for LiveView though, to me it's the most productive web app technology in the world and there's just no match to it. It makes the hard things easy.
Unfortunately the Elixir ecosystem is a harsh dose of reality: only a handful of good 3rd party libraries that are well maintained outside of Phoenix, Ecto, and Oban. I say this as somebody who’s spent several years full time in Elixir on and off since 2017, including in my current role. A strong Elixir ecosystem has unfortunately never materialized.
In your experience, when is this really an issue? I don’t disagree with you, but I’ve never been that inconvenienced by lack of third party libraries. Most of the time I’m just using Elixir to call a REST API anyway.
While in general you are right, I'd strongly say "it depends".
The raw BEAM ecosystem (things that come ootb) is huge in itself, many things that would require additional machinery/libs/infra/... in other tech stacks are simply covered right away with stuff like OTP.
The machine-learning ecosystem is kinda thriving, not fully at python levels yet but catching up rapidly and already outshining most other tech stacks - especially factoring in again the BEAM underpinnings that allow stuff like https://elixir-broadway.org/ for data pipelines (which requires a lot of additional python machinery to even replicate), and I'd argue that iE LiveBook already is a much better story than Jupyter notebooks.
The web framework story is already excellent, as you mentioned with Phoenix/Ecto/Liveview/Oban/... which are kinda best-of-breed in the industry right now. Not only for the first few days into a project (lots of tech stacks are compelling here for one reason or another), but the scaling up capabilities are flat out amazing, you can get _so much_ mileage out of the stack before even looking into anything like k8s or whatever and can focus on iteration features instead of spending time in optimizations/infra/... even when traffic peaks occur.
What may be missing are some adjacent libs or QoL in many smaller places. But its getting better for a while... we now have a great storybook reimplementation that doesn't suck ass with nodejs ecosystem craziness/provisioning/slowness like the real storybook. We have usable solutions for i18n or auth that may not be fancy but do the job. And since being Elixir, many missing things are just a few macros away if you need it. Especially the last 2 years have been quite a ride, and I was a phoenix user since probably 1.2 years back, but recently things are stepping up.
Right now I am eagerly waiting for BeaconCMS to mature enough, thats an absolute pain point to get solved since nearly every web platform at some point needs some CMS style free-style pages and right now I have to always implement an integration to some external system... can't wait to have this as a lib mounted in my app like everything else. Oh, and types of course, one of the few points that keep people from trying elixir and I (coming from Rust, Go, Typescript) learned to love. But it looks like we're getting there.
Punk rock died when the first kid said
"Punk's not dead, punk's not dead"
You know Louisville is death, we've got to up and move
Because the dead do not improve.
I'll add my 2 pence for why Rails is still suitable for startups.
Rails is still the best framework for building web forms quickly.
Web apps are mostly web forms. It helps you get going with everything ready for you (validations, style, views, etc). If you follow the conventions, you get a significant boost in productivity.
I see people using other "modern" frameworks where they build api+validation, frontend+validation etc it is just a waste of time. Build the product, get it out there.
104 comments
[ 5.7 ms ] story [ 259 ms ] threadIf Shopify, Github, or Gitlab wrote their code in golang or rust, would they need less CPU and memory? Would they have less bugs? Are refactors fast? How has RoR's ever changing JS ecosystem impacted these organizations?
- Lyft is built in Python (which IMHO, is comparable to ruby).
Who out computed who?
- WooCommerce is written in PHP.
- Shopify is written in Ruby.
Who has more customers? hint: [0]
I do not think programming languages define a company's success.
[0] - https://6sense.com/tech/ecommerce-platform/woocommerce-vs-sh...
Just curious.
Add Twitter to the list. They started with Rails, then switched to something else. Too many background jobs, Ruby is not ideal for that. However they became Twitter and owned that space before having to switch so Rails didn't harm them too.
We also got 98~100 lighthouse by using pure JS with sprinkles of stimulus after the initial rendering.
2x8gb elasticsearch 1x512mb redis 1xRDS mysql 16gb
low thousands/year of cloudflare enterprise
half of the budget (personnel+infra) than the next competitor in the niche I worked
It's not a ruby thing, it's just that servers are beast nowadays, and cheap.
And devs are more expensive than ever.
I disagree….. see the other comment here who talks about moving to Golang.
Only today I rewrote a Python application in Golang and the result was dramatically more responsive.
Performance matters. Servers cost alot of money. You want to maximize that resource.
So even if you need to switch languages down the line, I'd argue you should pick your initial tools based on what lets you iterate fastest early on, not based on what will keep your server costs down the line. Assuming of course what you pick is fast enough for whatever you want to do.
Put in more concrete terms, based on the actual VC deals I've been on one or the other side of the table for, the cost of capital drops to anything from 1/2 to 1/10 per early round if you're doing well. If you do well enough that your server cost is becoming a problem, by the time you need to address it paying to address it ought to not be a problem unless your decisions were truly pathological.
Most companies don't survive long enough for this to become a problem.
In other words, while performance matters, the value of performance now to an early stage startup is often really low compared to speed of delivery that might improve your odds of actually surviving to a point where performance becomes a problem, and you might easily be willing to trade 2x, 5x, even 10x the total dev cost in cash to deliver faster if you can defer a significant portion of that cost a few years down the line assuming you survive that long and your cost of capital in terms of proportion of equity is a tiny proportion of what it is at the start.
This is not an argument for Rails, btw. This is an argument for whichever tool is fastest for YOU and YOUR team to deliver with. If you have multiple alternatives you're equally productive with and one of them is more performant than others, of course pick that one.
No it's not saying bad performance doesn't matter.
Yes Go can make application more responsible.
But you have to balance out a lot of compromises in a project, and Pareto tend to favor those languages in the majority of situations because of cost, skills, resources and constraints.
etc.
As much as I think RoRs initial love for coffee script was a mistake (although it certainly did help at a time when javascript was in a horrible, braindead place) - I'm not sure I'd like the js mess at Rails' feet.
I think that the team navigated js integration as well as could be expected - and everyone was happy in version 7 when js support in browsers had advanced to the point that most of the special handling could simply be ripped out.
The remaining issue IMNHO is that there's no browser support for typescript - and using ts dictates a build pipeline which would otherwise be needless complexity with modern js and js modules.
was?
The only thing that could have saved (maybe) is better tooling but the community had no interest in it (who knows why). Rust feels like this too.
I think the initial version was a moderate enhancement on js, fixing some things like global scope etc?
IMO when you work with it properly it's so little of an issue (especially compared to the Dev time saved) that most Rails Devs simply don't care about the 'ruby doesn't scale' talk
The productivity of Rails absolutely trounces JS-framework-de-jour in my experience. It’s almost certainly the framework I would be recommending for a CRUD app, which covers the vast majority of business software.
It’s hard for me to imagine what could be so much more productive than any number of other languages//frameworks.
What does ROR actually have that the next technology doesn’t?
This was very true more than a decade ago before the Node revolution adn when the alternatives where Struts or Spring MVC in Java, or Zope with Python. Fast forward to 2023, I would say that other platforms have caught up a lot, but my personal opinion is that Rails still has the edge.
AFAICT, one has to go with the conventions as far as possible. Straying off the beaten path can lead one to lose time fighting the framework.
Ask ChatGPT to create a basic Rails app that has authentication, routing, and a dashboard page only accessible after login.
Then ask ChatGPT to do the same thing, but with any other language/framework.
I can see why that would get you going quick. Certainly Django doesn’t provide that. Most other frameworks I know don’t provide that.
I know I’m dead sick of building my 50th user signup flow.
Having said that, once it’s built that’s done. What’s the ongoing productivity gain beyond that?
For example working on a typescript next.js app, you'll have definitions in your Prisma schema, you'll have some form of model wrapper to load and save your model instances, and you'll have front end code to render your model instances.
All of that is gone with rails. The default is that your schema defines the attributes of your model, and your model has no code. If you scaffold your controllers, your entire app consists of a set of routes, a schema file, some empty model files, a default controller, and generated views.
I am admittedly a rails expert, but I could redo most of the typescript apps I've worked on in a few weeks as rails apps, but not so vice versa.
That being said, these days I mostly choose Typescript because the long term sustainability of a flexible type system beats the short term productivity gains that rails builds in for you.
But if I was building a prototype or wanted an MVP as fast as possible because I was bootstrapping with my own money, I would reach for rails. There's no better framework for discovering what your customer actually wants to pay for.
Of course all of these things are achievable in other languages/frameworks. But they require quite a bit more setup, and those setups end up being much less standardised across projects. IMO this doesn't tend to make too much difference over the long term, but something like rails definitely makes it quicker to get started.
The specific example I've got in mind is database migrations. The default with Rails is that you write them yourself, and the model then interpolates what it finds in the database at runtime. With Django, the pattern (again, by default - but defaults matter) is that you change the model and the migrations are generated automatically. The model is the source of truth.
I haven't figured out exactly why yet, but the way Rails splits the responsibilities seems to be much cleaner to me. I'm always slightly uncertain about what Django is going to do. With Rails the database feels closer to the surface, rather than something handed entirely over to the framework.
You’re essentially describing a declarative migration system which on the face of it sounds reasonable. It sounds like you’re dismissing it on this property. After all, the underlying DDL is…declarative, for the initial tables, anyway.
When you create a new migration, Django will tell you which actions it’s written into the migration file, i.e. the actions it thinks need to be taken to get from A to B. I don’t see anything opaque about that?
You can also look at the migration file yourself. It’s entirely readable. You could even write your own if you wanted to.
The Rails community seems to still be carrying a very peculiar compete-with-Django attitude from back in the heyday. I see it all the time here. It’s ridiculous.
> When you create a new migration, Django will tell you which actions it’s written into the migration file
Yes, that's the point. With Rails, I tell it what to do, and if my start point is a specific change I want to make to the database, that's an easier starting point than having to first translate the problem from the database into the model, so that the abstraction can convert it back again, for me to double-check.
Rails is certainly productive in the early days of building something, because so much of what you need is already built. But as time goes on that productivity edge vanishes.
It's far easier to build slick modern UIs in other frameworks, and there are now Typescript frameworks (e.g. Remix) where you can use the same types (and get type safety, IDE auto-completion, IDE warnings, etc.) across the entire stack (it's amazing!) The fact you don't need import statements to use code across a Rails app feels like a blessing at the start, but as the codebase grows, it can become a nightmare trying to figure out where something is defined or how something has been altered. The lack of typing leads to way more maintenance - I have Rails apps that are years old and I still get regular error notifications (method doesn't exist on nil is a particularly common one) whereas I have Typescript apps that I built a few months ago that have never triggered an error ever. The list goes on.
The world turns, frameworks come and go, and the heyday of Rails is over. I don't know why this is a problem for people, quite frankly. If you didn't want to learn new things, then being a software developer wasn't the right career choice, and you were probably told that on day 1!
The half life of these backend frameworks is pretty short. Rails has built a lot of billion dollar businesses. Wake me up when Remix does that.
Nobody asked your opinion on who could be a software developer. Stop being a gate keeper and let people make their choice on what technology works for them.
Surely you are joking, maintenance is THE downside of the node ecosystem if I had to pick the biggest one.
At work we have a roughly 50/50 Rails/React app but on the maintenance side though it's 20% Rails / 80% React. The package churn in the node ecosystem is absolutely insane and just keeping up with it is almost a full time job. And to add even more to the maintenance burden, on the node world the packages are rarely tested well (if at all), you are building on moving sand and theoretically you would need even more testing than in the Rails part to compensate that.
I'm not saying Rails has the best maintenance story, far from it but it's not nearly as bad as anything JS based.
I was a Rails developer for a long time and it certainly has its pitfalls. But I don't feel that this was one of them and I certainly don't think that explicit imports would solve this problem for you.
Do you have a bunch of global variables (or external data stores like Redis caches etc) being modified by only-God-knows-what? I don't know how explicit imports would solve that. I'm not sure how "import Foo" versus "Foo=42" is going to help you, unless perhaps if you've given your global thing an identifier that is impossible to grep for.
You can also have the behavior you want in Rails, anyway! You have full control over autoloads! Put your code in a non-autoloaded folder. Boom, now you have to explicitly `require` it before using it.
Static typing isn't your answer.Unexpected nils/nulls/whatever are a runtime error, and are almost always caused by some external resource (typically, the results of a database query or maybe an external API call) being unexpectedly nil, coupled with a sloppy lack of proper exception handling.
I don't care how iron-clad your language's type system is, it won't magically help you handle unexpected external runtime data or make up for a lack of exception handling and/or testing.
Saying that most business applications would be CRUD applications doesn't reflect the reality very well. While technically everything could be broken down to CRUD operations, this term becomes pointless once a relevant amount of business logic is needed to perform the final (database) insert, update or delete. There is a reason why Domain-Driven Design exists (and RoR is, by the way, not the best framework to apply it).
I feel like there’s a real shift towards strong (er) typing.
What does this mean for Rails?
My main language has been Python for a long time now but I’m really coming to prefer typescript for certain applications.
Does Ruby remain relevant as the industry moves towards typed languages?
ruby however is not statically typed.
*(there are actually ways to implement certain types of coercions by defining to_ary, to_str, to_int)
This made it sound like this was going to be a pretty detailed text, but instead it didn't say much of anything about Ruby or RoR. The author could have gone a lot deeper into what he loves about both.
I really liked Rails and used it for several years, but Go came when Rails was making things difficult.. Ruby's heap memory kept growing and not being released or released too slowly. My server was using 12 GB of RAM and could hardly handle 300 concurrent users.
The Go version uses 25 MB of RAM and can handle many thousands of concurrent users.
edit:
I understand the memory/concurrency issues are not Rails' fault entirely. It's likely ActiveRecord and Ruby as a VM that caused most issues, but it's part of the Rails deal. Getting good concurrency with Rails isn't easy, and memory issues are real.
Haven't see anyone actually using them in production though.
Tried beego some time ago and everything felt out of place, websites not working, unresponsive dev's on github and so on.
Today i'am happy with the standard lib + mux + some otheer libs for other functionalities, it's just more work than rails but this also works!!
I'm not "against" frameworks, but there are up- and downsides. E.g. in Rails I had quite some trouble with complex forms, which eventually resulted in form_this[1], which actually worked pretty well for the application I was working on. For a lot of apps you don't need this kind of thing, but when you do, it's quite difficult to do something outside the Rails "happy path". Maybe newer versions of Rails handle this better; I haven't really kept up.
I found the Rails codebase rather tricky at times. You get things like:
And it's really neat you can do that in Ruby, but it can also make a codebase kind of tricky to debug – it's the old "you need to be twice as clever to debug code than to write it". While I generally found Rails to be pretty good, it does have bugs and quirks.On the flipside with Go you spend a bit more time writing your own code, but that code will be better suited to what you're doing. Sometimes people seem to be afraid to write code, but I found it's not a bad thing and "do it yourself" can be quicker and better than "adapt existing thing to your needs".
On balance, it seems to more or less cancel out. Maybe there's some difference one way or the other, but it doesn't seem to be huge.
[1]: https://github.com/bluerail/form_this
I wrote a clean sheet Rails form helper library at https://github.com/rubymonolith/superform that’s completely customizable and even permits its own strong parameters.
The Rails application was difficult to change (but easy to pump new things out). As the product matured, fewer new features were really needed so the edge Rails had was gone and all that was left was an application that was hard to change without breaking something.
Go's edge came in and reduced the server's memory footprint and was easy to maintain and make changes. If the Go code compiled, I was confident it would work (I never felt that way with Rails).
To answer your question directly: I didn't use any framework. My application only has two external dependencies: gorilla/securecookie (cookie encryption) and lib/pq (database driver for postgres).
I could probably do without securecookie, but I was hesitant to do anything encryption related on my own.
Everything else is standard library Go code.
Rails' deep integration with view layer unlocks a great level of productivity.
Yes. Unless you are builing a static site.
To each their own though. IMO Rails is significantly faster when it comes to being able to get a complete product to market with all of the trimmings. When it comes to specific programming problems here and there a lot of languages will be able to get the job done.
That holistic "get everything done well with a small team so we can be profitable" scenario is where Rails outshines most everything else.
Plus, if you're concerned about the runtime, just switch to JRuby.
It's not like I was slinging Rails code like a bootcamp graduate :)
Well said
The rewrite was definitely a good idea by the sound of it, but of course you had prototyped your way to a stable vision of what you actually want the monolith to do using RoR. Good Job!
For now Rails has more gems than Phoenix for a quickstart within the first days, but this quickly turns around when stuff gets complicated and you need to "optimize" ruby code instead of shipping more features, or when you want realtime that doesn't suck.
It's like where DHH wants to end up with Rails, but available here and now, with a better technical foundation.
On the plus side for LiveView though, to me it's the most productive web app technology in the world and there's just no match to it. It makes the hard things easy.
The raw BEAM ecosystem (things that come ootb) is huge in itself, many things that would require additional machinery/libs/infra/... in other tech stacks are simply covered right away with stuff like OTP.
The machine-learning ecosystem is kinda thriving, not fully at python levels yet but catching up rapidly and already outshining most other tech stacks - especially factoring in again the BEAM underpinnings that allow stuff like https://elixir-broadway.org/ for data pipelines (which requires a lot of additional python machinery to even replicate), and I'd argue that iE LiveBook already is a much better story than Jupyter notebooks.
The web framework story is already excellent, as you mentioned with Phoenix/Ecto/Liveview/Oban/... which are kinda best-of-breed in the industry right now. Not only for the first few days into a project (lots of tech stacks are compelling here for one reason or another), but the scaling up capabilities are flat out amazing, you can get _so much_ mileage out of the stack before even looking into anything like k8s or whatever and can focus on iteration features instead of spending time in optimizations/infra/... even when traffic peaks occur.
What may be missing are some adjacent libs or QoL in many smaller places. But its getting better for a while... we now have a great storybook reimplementation that doesn't suck ass with nodejs ecosystem craziness/provisioning/slowness like the real storybook. We have usable solutions for i18n or auth that may not be fancy but do the job. And since being Elixir, many missing things are just a few macros away if you need it. Especially the last 2 years have been quite a ride, and I was a phoenix user since probably 1.2 years back, but recently things are stepping up.
Right now I am eagerly waiting for BeaconCMS to mature enough, thats an absolute pain point to get solved since nearly every web platform at some point needs some CMS style free-style pages and right now I have to always implement an integration to some external system... can't wait to have this as a lib mounted in my app like everything else. Oh, and types of course, one of the few points that keep people from trying elixir and I (coming from Rust, Go, Typescript) learned to love. But it looks like we're getting there.
Indeed, and if Ruby did scale for them, they wouldn't be so invested into integrating JIT compiler infrastructure into CRuby.
Likewise there wouldn't exist so much research in TruffleRuby and JRuby.
Which is great from performance of dynamic languages point of view, and compiler nerds, but lets not pretend it doesn't matter.
I’ve heard this for years yet they both keep growing and the community is nowhere near dead.
It’s an endless argument.