Ruby on Rails and Elixir Together

Your Rails app is doing its job. Customers use it, the business depends on it, and your team knows the code. But now you need live updates, more connections, or background workflows that stay responsive when traffic spikes. Does that mean starting over?
Often, you can keep Rails and bring in Elixir where it helps most. Rails continues to handle business logic, admin tools, payments, and everyday product features. Elixir takes on a specific workload, such as chat, live dashboards, or coordinating many tasks at once.
This is a hybrid architecture: two technologies working together, each with a clear role. It gives you room to improve the product without putting years of working code through a full rewrite.
The potential benefits are practical:
- Keep existing Rails features, gems, and business rules.
- Move a demanding workload without rebuilding the whole application.
- Add real-time features with Phoenix Channels or LiveView.
- Isolate failures and define how individual processes recover.
- Scale the busy part of your system separately.
The key word is “potential.” A second runtime adds work, too. The goal is to solve a real problem well enough to justify that extra complexity.
How do Ruby on Rails and Elixir differ?
Rails is a web framework built on Ruby. Elixir is a programming language; Phoenix is its main web framework. Comparing Rails with Elixir usually means comparing Rails with an Elixir/Phoenix stack.
Rails makes common product work straightforward. Its conventions and libraries help teams build accounts, billing, forms, and APIs without assembling everything themselves. Elixir runs on the BEAM, the runtime behind Erlang, with a model built around lightweight processes that exchange messages.
| Area | Ruby on Rails | Elixir / Phoenix |
|---|---|---|
| Programming style | Object-oriented Ruby and Rails conventions | Functional code, pattern matching, message passing |
| Concurrency | Threads, operating-system processes, and job workers | Lightweight processes managed by the BEAM |
| Real-time features | Action Cable and the wider Rails ecosystem | Phoenix Channels and LiveView |
| Data access | Active Record | Ecto, with explicit queries and changesets |
| Everyday strengths | Business apps, admin tools, commerce, APIs | Connected clients, live interfaces, concurrent workflows |
| Team considerations | Familiar tools for an existing Rails team | New language, runtime, and operational skills |
Concurrency is where the difference often matters. Think of thousands of users staying connected while the application receives events and sends updates. Elixir gives developers a natural way to organize these separate activities.
Phoenix famously demonstrated two million WebSocket connections on one server in 2015. That was a specific benchmark with limited message activity, not a promise that any production app can support two million active users.
Rails also supports WebSockets through Action Cable. For interactive pages, Phoenix LiveView keeps application state on the server and sends compact updates to the browser. It can reduce custom frontend code, though network latency and application design still affect responsiveness.
Practical ways to connect Rails and Elixir
Start with one feature that has a clear boundary. A notification service is easier to separate than a workflow that touches accounts, billing, inventory, and permissions at every step.

Before choosing the connection method, decide which application owns the data and business rules. Otherwise, a small service can turn into two applications that constantly depend on each other.
APIs for direct requests
HTTP APIs are a sensible starting point when Rails needs an immediate answer from Elixir, or the other way around. They are familiar, easy to inspect, and usually enough for an initial integration.
Consider gRPC if your team needs typed contracts or streaming and can support the tooling. Either way, define authentication, timeouts, error responses, and retry behavior. A fast service still needs a plan for slow or unavailable dependencies.
Events for background work
When Rails does not need an immediate response, it can publish an event for Elixir to process. For example, an order update might trigger notifications or refresh a live dashboard.
Use durable delivery where losing an event would matter. Make consumers safe to retry, so receiving the same event twice does not send two invoices or apply a change twice. An outbox pattern can help connect database changes with reliable event publication.
A shared PostgreSQL database
Both applications can access the same PostgreSQL database. This can make an early integration easier because the data is already available, but it also couples the services to the same schema.
Give one application ownership of migrations and define who can write to each table. Remember that Rails callbacks and validations do not run when Elixir writes directly to the database. Important rules need protection wherever writes happen.
Ecto’s create_if_not_exists only skips creating an existing object. It does not coordinate two migration systems or prevent incompatible schema changes. Keep changes backward-compatible while both applications are running.
Keeping a Ruby component callable
Sometimes a useful Ruby library or custom rules engine needs to stay. Calling it through a small service is one option; a process bridge may also be worth evaluating.
Keep the runtime boundary clear: an external Ruby interpreter remains an operating-system process, not a lightweight Elixir process inside the BEAM. Its memory use, crashes, and lifecycle still need deliberate handling.
What changes for developers and operations?
The biggest adjustment is learning a different way to structure code. Ruby developers will recognize many web concepts, but immutable data, pattern matching, Ecto changesets, and process supervision take practice.
Start with a small service and pair newcomers with someone experienced in Elixir. Clear examples and code reviews help the team build good habits before the new service becomes business-critical. Avoid setting a fixed “productive in two weeks” expectation; the learning curve depends on the people and the workload.
AI coding tools can help explain unfamiliar code, draft tests, or suggest translations between Active Record and Ecto. Treat their output as a starting point. Check library versions, queries, transaction boundaries, and process behavior, especially when generated code looks convincing but skips an important edge case.
Testing needs to cover the connection between applications. Check request formats, event payloads, permissions, and failure cases. What happens if Elixir restarts halfway through a task? Can Rails keep serving customers? What happens when the same message arrives twice?
Deployment also becomes a shared responsibility. Each service needs a repeatable build, monitoring, logs, and a rollback plan. Containers can help package the runtimes, but adding Elixir does not require Kubernetes. Use infrastructure your team can comfortably operate.
Elixir’s supervision trees let you configure how child processes restart after failures. They do not automatically restore lost in-memory state or finish interrupted business operations. Durable jobs, persisted data, and recovery logic still matter.
How do you know the hybrid approach is working?
Measure the current problem before moving anything. Useful baselines include response time under load, queue delay, memory use, connection count, infrastructure spend, and time spent handling incidents.
Then compare the new service against the same workload. A lower server bill is useful, but so is a feature that stays responsive during busy periods or takes less effort to maintain. Include the cost of running and supporting both stacks in the comparison.
For example, a SaaS product might keep subscriptions and account management in Rails while Elixir handles live notifications. A manufacturing tool might preserve its Ruby pricing rules while moving connection handling and update coordination into a separate service. These are possible designs, not guaranteed performance outcomes.
Roll out gradually. Send a small share of traffic to the new service, watch the results, and expand when behavior is predictable. Test rollback with real data changes in mind: sharing a database does not make every change reversible.
If slow SQL queries are the real bottleneck, moving the application code may achieve very little. Fix the constraint you can measure, then decide whether another runtime is the right next step.
Key takeaways
Rails and Elixir can work well together when they have clear responsibilities. Keep the parts that already serve your product well, and introduce Elixir where its concurrency model or real-time tooling solves a specific problem.
Start small, define data ownership, plan for failures, and measure the result. A successful hybrid system should make the product easier to grow and support, with benefits that outweigh the extra operational work.
Need help deciding where to start? Elixirator can help you assess your Rails app, identify a suitable first service, and plan an Elixir integration around your existing product. Feel free to contact us!
FAQ
Can I add Elixir without rewriting my Rails app?
Yes. Keep Rails running and introduce Elixir for one feature or service. Connect them through APIs, events, or carefully managed database access, then expand only if the results justify it.
Is Elixir always faster than Rails?
No. Elixir is particularly useful for many concurrent activities and long-lived connections. Actual performance depends on the workload, database, external services, and implementation. Benchmark the feature you plan to move.
Can Rails and Elixir share a database?
Yes. Active Record and Ecto can use the same PostgreSQL database. Agree on migration ownership, table access, and validation rules so changes in one application do not break the other.
Will Elixir replace Sidekiq?
It does not have to. Keep existing jobs in Sidekiq unless there is a reason to move them. A BEAM process alone does not provide durable job storage or guaranteed completion.
When should we stay with Rails alone?
When Rails meets your needs and the team can maintain it comfortably. Improve queries, caching, job design, and existing real-time features before adding another stack without a clear benefit.

