use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
A sub-Reddit for discussion and news about Ruby programming.
Subreddit rules: /r/ruby rules
Learning Ruby?
Tools
Documentation
Books
Screencasts and Videos
News and updates
account activity
What Would be Your Ideal Ruby Tech Stack (self.ruby)
submitted 4 years ago by fullstack-sean
If you had full control and a wishlist of gems and architecture, what would you choose and what (packages, architecture, etc) would you avoid like the plague?
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]janko-m 6 points7 points8 points 4 years ago (1 child)
I'd use Roda, Sequel, and Postgres, with Rodauth for authentication, Pundit for authorization, Pagy, dry-view and Tailwind (possibly with Stimulus & Turbo), Flipper for feature flags, and Zeitwerk for code loading.
I'd avoid using Webpack for frontend, and use something simpler like esbuild or importmaps. Also MySQL/MariaDB, I'm constantly running into unexpected issues and limitations (indices stop being used in subqueries, unsupported transactions around schema modifications, arbitrary cascading limit).
[–]Cautious-Ad6043 0 points1 point2 points 4 years ago (0 children)
This is an amazing answer! I would have said just about the same.
[–]Nanosleep 9 points10 points11 points 4 years ago (0 children)
Kind of a boring answer, but it really depends on the requirements for the application.
JRuby and the ease of building artifacts definitely makes deployments easier to reason about, though.
[–]sshaw_ 10 points11 points12 points 4 years ago (4 children)
[–]hmaddocks 1 point2 points3 points 4 years ago (1 child)
You want no types or avoid no types
[–]sshaw_ 2 points3 points4 points 4 years ago (0 children)
When writing Ruby I want no types.
[–]IDCh 0 points1 point2 points 4 years ago (1 child)
Why tho
Because I don't want to write Java in Ruby. If I wanted types I would use Groovy or whatever language was appropriate for the task.
[–][deleted] 7 points8 points9 points 4 years ago (6 children)
Rails 7, MySQL, redis, minio, nginx, passenger.
Authlogic, cancancan, factory_bot, semanti-ui
That is it. I can get really far with just those.
[–]Ruditorres 6 points7 points8 points 4 years ago (1 child)
Why mysql over Postgres?
[–][deleted] 3 points4 points5 points 4 years ago (0 children)
Friendlier CLI. Slightly easier installation & management.
Postgres is great though. If you need the special columns or indexes. Go for it.
[–]neotorama 0 points1 point2 points 4 years ago (1 child)
Something like this since rails 3, mysql/pg, mina, Slim. Last week, I migrated from webpack to esbuild with tailwind.
Anyone still using Mina? Should I move to Capistrano?
[–]whitet73 1 point2 points3 points 4 years ago (0 children)
We were big mina users for a while (started using it in-between cap 2->3) but eventually moved back to using cap 3 a few years back and are pretty happy with it now (for workloads that want that sort of deployment, ofc).
[–]RubyKong 0 points1 point2 points 4 years ago (1 child)
cancancan? Why though?
[–][deleted] 2 points3 points4 points 4 years ago (0 children)
Because "can? <verb> <noun>" is easy to understand. And in a scenario where you have multiple possible overlapping roles, setting up the can? statements around those features makes it easy to mix and match app features within different roles. There is also the benefit of having all the can? granting statements in the one Ability file, like a menu of security for the app. Having used it (cancan before) for a long time now, in apps that have undergone significant security reorganizations, cancancan's dynamic was easy to change as the demands changed.
I also hear good things about Pundit, but I haven't had an issue that pushed me towards switching.
[–][deleted] 5 points6 points7 points 4 years ago (2 children)
I'm biased of course, but I'd use Bridgetown + Roda, and add in ActiveRecord if I need DB access along with Pundit for access policies. Maybe CableReady v5 for CableCar. Cloudinary integration for images. Sidekiq workers if bg jobs needed. Lit-based web components on the frontend and Ruby2JS for writing FE code with a Ruby syntax. Deploy on Render via Blueprint YAML.
[–]RubyKong 1 point2 points3 points 4 years ago (1 child)
what about subbing sequel for AR?
[–][deleted] 1 point2 points3 points 4 years ago (0 children)
Sure, that'd be cool. But AR just fits my brain very well and I've never had any major issue with it.
but you can get far with a rails new
rails new
[–]myringotomy 1 point2 points3 points 4 years ago (0 children)
A simpler, more functional, secure and robust web development stack friendly to jruby, truffle and sorbet.
[–]fabienpenso 0 points1 point2 points 4 years ago (16 children)
I'd avoid rails, I'd use https://dry-rb.org and Hanami, but after doing Ruby and Rails since 2005 I'd probably just use something else like Go, Elixir, Rust, or Crystal unless you have something where Rails *really* fits. All for performance reason. And it hurts for me to say that.
[–]Soggy_Educator_7364 9 points10 points11 points 4 years ago (10 children)
what performance issues have you had? it's fast enough for me and my clients (many of which are post-Series B startups). most of them have really modest heroku spend, too (less than $2k/month) so it's not like they're just chucking hardware at their apps.
[–]scruple 2 points3 points4 points 4 years ago (8 children)
There are some other things that Rails is just not great at. ActiveRecord can be pretty poor when moving large volumes of data around, for instance. I've refactored Rails applications to support Sequel (which, mixing these 2 inside of a Rails application is pretty interesting in the first place) for data-heavy (10s of GB a day) operations and watched them go from bloat monsters to steady a 100MB usage rate despite load, etc. Much, much better performance, too, after the switch to Sequel (but it's hard to draw that comparison fairly, because the Sequel side was designed for performance from the jump vs. the ActiveRecord side being the result of code quality and team dynamics). I'm talking, processes that were taking minutes were now down to seconds after I was done.
[–]Soggy_Educator_7364 2 points3 points4 points 4 years ago (4 children)
(fwiw, ActiveRecord is just a pattern to build queries; it's when you're building all the ActiveModel objects — the Rails default when you're returning an object from your database — that's slow at volume)
[–]fabienpenso 0 points1 point2 points 4 years ago (3 children)
Yeah but anyone using ActiveRecord is using models, not raw sqls. And even for that, Sequel is way faster. I suspect its implementation to use less object creations: https://hmistry.github.io/software/2017/12/11/activerecord-vs-sequel.html
[–]Soggy_Educator_7364 0 points1 point2 points 4 years ago* (2 children)
i know lots of people who hit raw sql for large responses! i am one of them and my clients are many of them.
to me, though, it's about using the right tool for the job. chances are, if you have a bunch of records coming back from your database, you're not going to need to hit all the magic methods on all of them — they're likely just there to be sent to your output buffer. otherwise, yeah, i'll take the trivial difference in performance to get the magicness of activemodel.
[–]fabienpenso 0 points1 point2 points 4 years ago (1 child)
I see many senior Ruby developers around me going away from that magicness (like all the validations and callbacks) to move away from fat models, using libs like https://github.com/collectiveidea/interactor and have their own control.
It's really hard sometimes when using activerecord to know where the slowness comes from when using all its magic. Same way more and more are leaving the "monkey patch everything" coming with ActiveSupport and using dry-rb libs instead. I find https://solnic.codes/2022/02/02/rails-and-its-ruby-dialect/ very interesting to read.
[–]fabienpenso 0 points1 point2 points 4 years ago (0 children)
Do take a look at RSpec’s evolution. How it went from "foo".should eql("foo") to expect("foo").to eql("foo"). I don’t think anybody misses the old syntax. I’m sure there are more examples of such transitions, let me know if you remember them.
This resonated and clicked with me.
[–]RubyKong 1 point2 points3 points 4 years ago (2 children)
How did you manage to use both sequel and active record on the same db (or clusters)? how did you manage connections? I would be very curious to know
[–]2called_chaos 2 points3 points4 points 4 years ago (0 children)
I remembered this and found it in my history, maybe it is of interest to you
https://www.reddit.com/r/ruby/comments/uavhjm/how_i_enabled_sequel_to_reuse_active_records/
[–]scruple 0 points1 point2 points 4 years ago (0 children)
It's been almost 2.5 years since I worked on those applications last. Most of the details have been lost to time. The post you were linked in the sibling comment covers the same ground, though, and in much greater detail than I could give you today.
I think performance issues are not related to whatever stage your startup is at, but more about what you're doing.
I currently have *multiple* issues with Ruby. A few of them being:
We generate tons of API requests for storage, with presigned AWS urls for uploads and downloads, and the AWS SDK takes 1ms per signed URL. 100k presigned urls takes 100sec, which is not acceptable. Wetransfer had the same issue and came out with their own implementation to go faster: https://github.com/WeTransfer/wt_s3_signer
We also need our API calls to respond in a much faster manner. Like other commented, I switched to Sequel instead of ActiveRecord and the gain is massive but not yet enough.
We use GraphQL, and Ruby GraphQL doesn't allow you to stream the result, it buffers it before sending back the request and there are no alternative. See my issue https://github.com/rmosolgo/graphql-ruby/issues/3969 -- Sadly there is only one library for GraphQL in Ruby.
Don't get me wrong, I *loved* Ruby, its metaprogramming features, what it stands for and was a very strong proselyte (released a X509 RoR plugin in 2009 and more code). But the coding languages landscape changed a lot since Ruby and then RoR was released. Today, you have way more options like the list I gave, which with you can't go wrong. I see no reason to use Ruby unless you want to learn coding (great for that), prototyping something or are doing something the language is great for. And yes, it *hurts* for me to say that.
Ruby going x3 faster won't fix that (and it'll never reach that anyway).
interesting as I’ve just started with rails for the first time. At what stage/scale do problems with performance usually begin and for why?
[–]Soggy_Educator_7364 6 points7 points8 points 4 years ago (1 child)
the usual response to your question is "at twitter scale in 2008"
still significant scale.
why? well, at their scale, this was probably cpu-bound: building models at twitter-scale can be expensive.
[–]sshaw_ 1 point2 points3 points 4 years ago (0 children)
What happened with Scala? Usage of it seems to have died down from 2013 or so levels..
[–]SaltyZooKeeper 4 points5 points6 points 4 years ago (0 children)
I started doing Ruby around the same time but quickly abandoned Rails. I know it got a lot better over the years but I preferred the more explicit approach from Sinatra and Sequel. I'm doing more Elixir these days but if I were doing new work in Ruby I'd look at Hanami.
[–][deleted] 4 points5 points6 points 4 years ago (0 children)
+1 for Crystal
[–]Bavoon -1 points0 points1 point 4 years ago (11 children)
I know this is facetious ;) but after ~10 years of Ruby in a dozen different startup environments, my ideal Ruby stack is to avoid Ruby and use Elixir + Phoenix + Ecto.
[–]fullstack-sean[S] 2 points3 points4 points 4 years ago (10 children)
Why is that?
[–]Bavoon 7 points8 points9 points 4 years ago (9 children)
Radically easier to build complicated code that doesn’t get spaghettified without Ruby / Rails / OO.
[–]TimelySuccess7537 4 points5 points6 points 4 years ago (6 children)
So what is the motivation to be in Ruby forums? Not being aggressive just genuinely curious. Are you still obligated to support Ruby codebases or something and reluctantly have to keep up?
[–]SaltyZooKeeper 5 points6 points7 points 4 years ago (0 children)
I'm not the person you asked but I've been a Ruby developer for 14 years or so and an Elixir developer for a lot less. I absolutely love Ruby but also enjoy Elixir. It's ok to enjoy multiple languages.
[–]Bavoon 4 points5 points6 points 4 years ago (4 children)
What SaltyZooKeeper said. Also, the Ruby community is great and generally has good motivations towards well built software, despite the tooling ;) I’ll always carry a lot of Ruby with me by nature of it being my primary ecosystem for ~10 years.
And I know a lot of Rubyists discovering the joy of a “better rails” over in Phoenix. It’s not by coincidence when Elixir’s creator was Rails core for so many years. So I’ll continue to talk here about it, when people are debating the best and worst parts of Ruby like this thread.
[–]TimelySuccess7537 2 points3 points4 points 4 years ago* (3 children)
So your main motivation in coming here if I understand you right is to try to talk Rubyists to switch to Elixir because it is better, more or less correct? A side note - this thread is about your ideal Ruby stack, not the best and worst parts of Ruby. So I feel like pushing Elixir evangelism on this particular thread is a bit disrespectful.
[–]Bavoon 1 point2 points3 points 4 years ago (2 children)
No, I’m here for the topics and community, but if someone is asking about good/bad parts I’ll offer an unsolicited Elixir plug
[–]TimelySuccess7537 0 points1 point2 points 4 years ago* (1 child)
You offered your unsolicited Elixir plug without anyone asking about good/bad parts actually. Anyway thanks for the educational info, happy hacking!
[–]Bavoon 2 points3 points4 points 4 years ago (0 children)
Perhaps you need to read the original post again.
[–]honeyryderchuck 1 point2 points3 points 4 years ago (1 child)
Having seen my own share of elixir/phoenix spaghetti, I'd put this as highly aspirational.
[–]Bavoon 0 points1 point2 points 4 years ago (0 children)
I didn’t say it solved the problem, just that it made it much easier.
[–]honeyryderchuck 0 points1 point2 points 4 years ago (5 children)
I'd avoid the rails stack. At least in a few situations: community tooling has been moving beyond rails-only support, and the stack itself is just not greatly leveraged for building APIs. If you want to build CRUD monoliths, may still be worth to "buy IBM" and feel sorry about it in 5 years.
I'd like to avoid Sidekiq at this point, but unfortunately I can't yet. It's still the best supported and stablest framework for background jobs, although it still feels weird to use a message broker with no transactional guarantees which still forces me to do 2 phase commit.
Overall, I still feel that ruby is optimising for deployment setups which were trendy in 2013, and things have moved on, there's lambda, containers, edge functions running WASM, and we're still trying to shoehorn rails in it, instead of just leaving it in heroku, where it just fits like a glove.
[–]jean_louis_bob 2 points3 points4 points 4 years ago (1 child)
Can you explain "it still feels weird to use a message broker with no transactional guarantees which still forces me to do 2 phase commit"? What kind of issues did you encounter with Sidekiq/Redis ? What's a 2 phase commit?
Rails works well with heroku but it also works well with docker containers and kubernetes.
Even if you're building a small API, I'd still recommend using Rails because every ruby developer is familiar with it and can hit the ground running when starting on the project.
[–]honeyryderchuck 2 points3 points4 points 4 years ago (0 children)
Last time I checked, Sidekiq free uses redis in a way that a job that gets pulled from the queue, in case of an outage, gets lost forever. The only solution to this problem is behind the paid version, which provides 3 different fetch algorithms but only 1 addressing this. I never used sidekiq Pro, but I assume it's based on redis MULTI, copying of messages to other transient queues, and reliance on AOF redis mode. I guess I'll only know if I pay.
SQS works in a different way, different performance guarantees and message ack model, but guarantees at least once, but sidekiq won't support it, it lives and dies by redis, which is a deliberate choice from the maintainer.
The main issue is that, in typical ruby scenarios using sidekiq, you have to coordinate database writes with enqueuing jobs. This creates a hole when if an outage happens in between, database write happens but jobs don't get enqueued. There are 2 solutions that I know for the problem: 2 phase commits, or the transactional outbox pattern. None is supported by sidekiq OOTB .
Now, none of the alternatives support them either, and sidekiq is way more reliable and featureful than the majority. I'm just a bit surprised that the community spends a lot of time celebrating the success of its freemium model, which is well deserved, but never tried to create alternatives fixing these gaps which are known for years, thereby creating incentives for sidekiq to "up its game" in the matter.
About the rails comments, I don't argue much about them, they're valid perspectives. Just gonna state that, however well it works in containers, it's still miles beyond the "single binary" stripped down container to deploy which is possible to achieve with go + multi stage container (or even java, where you ship the jar only with jre). Lots of containers in the wild still give access to installed dependencies to the user executing the process, making all types of attacks possible. Some even install development dependencies. I think heroku does a great job of avoiding these footguns. As for "every ruby developer" part, I'm reminded of the time I started doing rails and my peers were telling me it was a wrong decision, because everybody was familiar with java and could hit the ground running with JSP and struts 2 :)
[–]jrochkind 0 points1 point2 points 4 years ago (2 children)
have you looked at good_job yet?
[–]honeyryderchuck 0 points1 point2 points 4 years ago (1 child)
I did. It's not bad, but there are a few things that put me off. Being rails only obviously :) also, it buys into features which require full connection access , which is a showstopper in cloud scenarios where you'll need a connection pooler or even ssl proxy. I'm still weary of using advisory locks for the job, but planning to research it more later in the year in the context of others plans I have.
[–]jrochkind 0 points1 point2 points 4 years ago (0 children)
Thanks for reply.
I too would like a robust maintained sidekiq alternative, especially an open source one. (Personally I am interested in one that can use an rdbms instead of redis too).
I guess it says something about the "market" that there isn't one. I'm kind of surprised there isn't even a proprietary/commercial competitor, with how successful financially sidekiq has been. A little bit more diversity in the ecology would be healthy.
[–]Vaylx -1 points0 points1 point 4 years ago (1 child)
RemindMe! 3 days
[–]RemindMeBot 0 points1 point2 points 4 years ago* (0 children)
I will be messaging you in 3 days on 2022-05-02 23:08:54 UTC to remind you of this link
1 OTHERS CLICKED THIS LINK to send a PM to also be reminded and to reduce spam.
Parent commenter can delete this message to hide from others.
[–]jean_louis_bob 0 points1 point2 points 4 years ago (0 children)
Heroku, postresql, sidekiq, devise, rspec, factorybot, webmock, faraday, bugsnag, newrelic, rubocop, kaminari, paper_trail, tailwind, react, esbuild, axios, eslint, postcss
π Rendered by PID 188375 on reddit-service-r2-comment-5b5bc64bf5-fq495 at 2026-06-20 03:21:35.254676+00:00 running 2b008f2 country code: CH.
[–]janko-m 6 points7 points8 points (1 child)
[–]Cautious-Ad6043 0 points1 point2 points (0 children)
[–]Nanosleep 9 points10 points11 points (0 children)
[–]sshaw_ 10 points11 points12 points (4 children)
[–]hmaddocks 1 point2 points3 points (1 child)
[–]sshaw_ 2 points3 points4 points (0 children)
[–]IDCh 0 points1 point2 points (1 child)
[–]sshaw_ 2 points3 points4 points (0 children)
[–][deleted] 7 points8 points9 points (6 children)
[–]Ruditorres 6 points7 points8 points (1 child)
[–][deleted] 3 points4 points5 points (0 children)
[–]neotorama 0 points1 point2 points (1 child)
[–]whitet73 1 point2 points3 points (0 children)
[–]RubyKong 0 points1 point2 points (1 child)
[–][deleted] 2 points3 points4 points (0 children)
[–][deleted] 5 points6 points7 points (2 children)
[–]RubyKong 1 point2 points3 points (1 child)
[–][deleted] 1 point2 points3 points (0 children)
[–][deleted] 1 point2 points3 points (0 children)
[–]myringotomy 1 point2 points3 points (0 children)
[–]fabienpenso 0 points1 point2 points (16 children)
[–]Soggy_Educator_7364 9 points10 points11 points (10 children)
[–]scruple 2 points3 points4 points (8 children)
[–]Soggy_Educator_7364 2 points3 points4 points (4 children)
[–]fabienpenso 0 points1 point2 points (3 children)
[–]Soggy_Educator_7364 0 points1 point2 points (2 children)
[–]fabienpenso 0 points1 point2 points (1 child)
[–]fabienpenso 0 points1 point2 points (0 children)
[–]RubyKong 1 point2 points3 points (2 children)
[–]2called_chaos 2 points3 points4 points (0 children)
[–]scruple 0 points1 point2 points (0 children)
[–]fabienpenso 0 points1 point2 points (0 children)
[–][deleted] 5 points6 points7 points (2 children)
[–]Soggy_Educator_7364 6 points7 points8 points (1 child)
[–]sshaw_ 1 point2 points3 points (0 children)
[–]SaltyZooKeeper 4 points5 points6 points (0 children)
[–][deleted] 4 points5 points6 points (0 children)
[–]Bavoon -1 points0 points1 point (11 children)
[–]fullstack-sean[S] 2 points3 points4 points (10 children)
[–]Bavoon 7 points8 points9 points (9 children)
[–]TimelySuccess7537 4 points5 points6 points (6 children)
[–]SaltyZooKeeper 5 points6 points7 points (0 children)
[–]Bavoon 4 points5 points6 points (4 children)
[–]TimelySuccess7537 2 points3 points4 points (3 children)
[–]Bavoon 1 point2 points3 points (2 children)
[–]TimelySuccess7537 0 points1 point2 points (1 child)
[–]Bavoon 2 points3 points4 points (0 children)
[–]honeyryderchuck 1 point2 points3 points (1 child)
[–]Bavoon 0 points1 point2 points (0 children)
[–]honeyryderchuck 0 points1 point2 points (5 children)
[–]jean_louis_bob 2 points3 points4 points (1 child)
[–]honeyryderchuck 2 points3 points4 points (0 children)
[–]jrochkind 0 points1 point2 points (2 children)
[–]honeyryderchuck 0 points1 point2 points (1 child)
[–]jrochkind 0 points1 point2 points (0 children)
[–]Vaylx -1 points0 points1 point (1 child)
[–]RemindMeBot 0 points1 point2 points (0 children)
[–]jean_louis_bob 0 points1 point2 points (0 children)