0

Ruby Không Chậm. Framework Của Bạn(Rails) Mới Chậm

Bài viết này là phần 1 trong series về Rage.rb. Phần 2 sẽ đi sâu vào kiến trúc fiber-based và cơ chế coroutine bên dưới.


Nếu bạn là Ruby developer, câu hỏi "ngoài Rails ra thì dùng gì?" thường chỉ có vài đáp án quen thuộc: Sinatra nếu cần nhẹ, Hanami nếu muốn thử nghiệm, hoặc... vẫn Rails nhưng API mode.

Rage.rb không nằm trong danh sách đó — không phải vì nó kém, mà vì nó mới đủ để nhiều người chưa để ý.

Bài này không giải thích Rage hoạt động thế nào bên trong. Bài này trả lời câu hỏi đơn giản hơn: Rage là gì, nó làm được gì, và tại sao bạn nên quan tâm?


Rage.rb là gì?

Rage là một API-first Ruby web framework được xây dựng để giải quyết một vấn đề cụ thể: Ruby applications cần handle high concurrency mà không phải trả giá bằng infrastructure phức tạp.

Nó được tạo bởi Roman Samoilov, open source theo MIT license, và đang ở phiên bản 1.22+ với release cycle đều đặn hàng tháng.

Một dòng mô tả chính xác nhất từ repo của họ:

"Rails ergonomics with a runtime designed for modern API systems."

Nói cách khác: bạn viết code giống hệt Rails, nhưng engine bên dưới hoàn toàn khác.


Trông như thế nào trong thực tế?

Nếu bạn đã viết Rails API, code Rage sẽ trông quen đến mức gần như không có gì mới để học:

# routes
Rage.routes.draw do
  resources :posts
  namespace :api do
    resources :users
  end
end

# controller
class PostsController < RageController::API
  before_action :authenticate!

  def index
    posts = Post.published.order(created_at: :desc)
    render json: posts
  end

  def create
    post = Post.new(post_params)
    if post.save
      render json: post, status: :created
    else
      render json: { errors: post.errors.full_messages }, status: :unprocessable_entity
    end
  end

  private

  def post_params
    params[:post].slice("title", "content", "status")
  end
end

# model — y hệt ActiveRecord Rails
class Post < ApplicationRecord
  validates :title, presence: true
  scope :published, -> { where(status: "published") }
end

Migrations, validations, callbacks, scopes, associations — tất cả đều là ActiveRecord quen thuộc. Không có DSL mới nào để học.


Những con số đáng chú ý

Đây là phần thuyết phục nhất.

TechEmpower Framework Benchmarks Round 23 — benchmark industry-standard cho web frameworks — cho thấy:

  • Rage vượt Rails 81–219% trên tất cả database test scenarios
  • Rage vượt Sinatra 31–100% trên cùng điều kiện

Để hình dung rõ hơn, đây là kịch bản thực tế với 1,000 concurrent requests, mỗi request cần query database:

Rails + Puma (5 threads):
  Throughput:     ~850 req/s
  P99 latency:    ~180ms
  Memory:         ~512MB

Rage + Iodine:
  Throughput:     ~2,100 req/s
  P99 latency:    ~42ms
  Memory:         ~128MB

Throughput tăng 2.5x, latency giảm 4x, memory giảm 4x — trên cùng một codebase, chỉ đổi framework.

Con số này không phải benchmark nhân tạo. Đây là workload phổ biến nhất của bất kỳ web API nào: nhận request, query DB, trả JSON.


Rage gộp cả stack vào một process

Điểm thú vị thứ hai không phải về performance raw — mà về operational simplicity.

Stack Rails thông thường cho một production app trung bình:

├── Rails app (Puma)
├── Sidekiq workers       ← cần Redis
├── Redis                 ← cho Sidekiq + Action Cable
├── Action Cable server   ← WebSocket
└── Cron/scheduler        ← scheduled jobs

5 thành phần, 5 thứ cần monitor, scale, và deploy riêng.

Rage gộp tất cả vào 1 process:

class OrdersController < RageController::API
  def create
    order = Order.create!(order_params)

    # Background job — chạy in-process, không cần Redis/Sidekiq
    SendConfirmationEmail.enqueue(order.id)

    # WebSocket broadcast — không cần Action Cable, không cần Redis
    Rage::Cable.broadcast("orders", { id: order.id, status: "created" })

    # Domain event — typed, object-oriented
    Rage::Events.publish(OrderPlaced.new(order: order))

    render json: order, status: :created
  end
end

Không có Redis để cấu hình. Không có worker process riêng để quản lý. Không có deployment unit thứ hai để lo.

Stack tương đương với Rage:

└── Rage app (1 process)
    ├── HTTP requests
    ├── Background jobs
    ├── WebSockets
    └── Domain events

Với team nhỏ hoặc startup, đây là sự khác biệt lớn giữa "ship nhanh" và "dành tuần đầu setup infrastructure."


Khả năng tương thích với Rails

Rage không yêu cầu bạn rewrite từ đầu. Nó hỗ trợ Rails Integration mode — Rage xử lý HTTP requests, Rails vẫn lo phần còn lại:

# Gemfile — thêm vào Rails app hiện có
gem "rage-rb"

# config/application.rb
require "rage/rails"

# Xong. Rage bắt đầu xử lý requests,
# ActiveRecord, code loading, middleware vẫn của Rails.

Đây là con đường migrate ít rủi ro nhất: test Rage trên production traffic thật, với codebase thật, không cần commit toàn bộ.


Ai đang dùng Rage?

Rage còn khá mới — phiên bản 1.0 production-ready ra mắt đầu 2024. Nhưng một số tín hiệu đáng chú ý:

  • Tháng 7/2025: Được nhận vào Cloudflare Project Alexandria — initiative của Cloudflare để hỗ trợ các open source projects chiến lược
  • ~1,100 GitHub stars với commit activity đều đặn
  • 40+ releases trong chưa đầy 2 năm — team đang build nghiêm túc

Không phải con số của một framework dominant, nhưng đủ để nói rằng đây không phải side project bỏ dở.


Rage phù hợp với ai?

Phù hợp nếu bạn:

  • Đang build API-only backend (không có server-side rendering)
  • App chủ yếu là I/O-bound: database queries, external API calls
  • Muốn giảm infrastructure overhead: bỏ Redis, Sidekiq, separate cable server
  • Cần handle lượng lớn concurrent connections: WebSocket, long-polling, real-time features
  • Là Ruby developer muốn performance cao mà không phải học paradigm mới

Chưa phù hợp nếu:

  • App có nhiều CPU-bound processing nặng
  • Đang dùng nhiều Rails-specific gems chưa được test với fiber scheduler
  • Cần full Rails stack: views, helpers, assets, ActionMailer với attachments phức tạp

Điểm khởi đầu

Cài đặt và tạo project mới chỉ mất vài phút:

gem install rage-rb
rage new my_api -d postgresql
cd my_api
rage s

Hoặc nếu muốn thêm vào Rails app hiện có:

# Gemfile
gem "rage-rb"
# config/application.rb
require "rage/rails"

Documentation đầy đủ tại rage-rb.dev và source code tại github.com/rage-rb/rage.


Kết

Ruby đã có tiếng là chậm so với Go hay Node.js. Rage là một trong những bằng chứng rõ nhất rằng phần lớn "sự chậm" đó đến từ cách framework xử lý concurrency — không phải từ bản thân ngôn ngữ.

Với syntax quen thuộc của Rails, con số benchmark đáng chú ý, và mô hình infrastructure đơn giản hơn đáng kể, Rage là framework Ruby đáng để bỏ ra một buổi chiều thử nghiệm.

Phần tiếp theo của series này sẽ giải thích tại sao Rage nhanh — đi sâu vào kiến trúc fiber-based, coroutine, và cách Iodine event loop hoạt động bên dưới hood.


Phần 2: Rage.rb — Khi Ruby Học Cách Không Chờ Đợi (fiber-based architecture, coroutine, non-blocking I/O)


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí