Skip to content
STACK IT FAST

Ruby on Rails + PostgreSQL + Redis + Sidekiq

Curated rule SaaS / Web App Updated Oct 2026 Which file does my tool read?
rails-postgres-redis.md

Production guidelines for Ruby on Rails monoliths, ActiveRecord pool tuning, Redis Sidekiq background jobs, and modern Hotwire or React UI architecture.

Formats
4 files
AGENTS.md
52 lines
CLAUDE.md
15 lines
Languages
Ruby
Updated
Oct 2026
Used by
3 projects
Install

Writes .claude/skills/rails-postgres-redis/SKILL.md

$ curl -s --create-dirs -o .claude/skills/rails-postgres-redis/SKILL.md https://stackitfast.com/rules/rails-postgres-redis/SKILL.md

Rule files

AGENTS.md· 52 lines · 3.3 KB
1# Project Architecture & Guidelines (Ruby on Rails + PostgreSQL + Redis + Sidekiq)
2
3## 1. System Architecture
4- **Framework**: Ruby on Rails 8.1+ (Puma web server). Rails 8 ships Solid Queue and Solid Cache on the database by default; this rule keeps Redis and Sidekiq on purpose, for teams that need Sidekiq's throughput and tooling at scale.
5- **Database**: PostgreSQL with ActiveRecord ORM.
6- **Caching & Job Store**: Redis for Rails cache store and Sidekiq background job broker.
7- **Background Worker**: Sidekiq for asynchronous job processing.
8
9## 2. Database Connection Pool Sizing (ActiveRecord & Puma)
10- Ensure database connection pool in `config/database.yml` matches Puma thread count and Sidekiq concurrency:
11 ```yaml
12 default: &default
13 adapter: postgresql
14 encoding: unicode
15 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
16 timeout: 5000
17 ```
18- When configuring Sidekiq workers, ensure the process pool size is at least equal to the Sidekiq concurrency setting (`concurrency: <%= ENV.fetch("SIDEKIQ_CONCURRENCY") { 10 } %>`).
19
20## 3. Redis & Sidekiq Configuration
21- Initialize Sidekiq in `config/initializers/sidekiq.rb` with dedicated connection pools:
22 ```ruby
23 Sidekiq.configure_server do |config|
24 config.redis = { url: ENV.fetch("REDIS_URL", "redis://localhost:6379/1"), size: ENV.fetch("SIDEKIQ_CONCURRENCY", 10).to_i + 5 }
25 end
26
27 Sidekiq.configure_client do |config|
28 config.redis = { url: ENV.fetch("REDIS_URL", "redis://localhost:6379/1"), size: ENV.fetch("RAILS_MAX_THREADS", 5).to_i }
29 end
30 ```
31
32## 4. Safe Database Migrations (Zero-Downtime)
33- Use the `strong_migrations` gem to prevent dangerous DDL locks in production.
34- Adding Columns with Defaults: In PostgreSQL 11+, `add_column` with default values is instant and safe.
35- Creating Indexes: Always use `algorithm: :concurrently` and `disable_ddl_transaction!` when adding indexes to live tables.
36
37## 5. Common Pitfalls to Avoid
38- ❌ Passing ActiveRecord Objects to Sidekiq: Pass only record IDs (`user_id`), never entire serialized objects.
39- ❌ N+1 Queries: Use `includes(:relation)` or `strict_loading` in ActiveRecord queries.
40- ❌ Redis Memory Leaks: Use separate Redis database numbers (`db/0` for cache, `db/1` for Sidekiq) to prevent cache evictions from clearing job queues.
41
42## 6. Testing Conventions
43- Use RSpec with `factory_bot` for model/request specs; avoid Rails fixtures, which rot as schemas evolve.
44- Test Sidekiq jobs with `sidekiq/testing` in fake mode by default; use `Sidekiq::Testing.inline!` only for explicit integration specs that need real execution.
45- Use `strict_loading` in test environments to fail fast on N+1 queries instead of catching them in production APM.
46- Run request specs (not just model specs) for every controller action — RSpec model coverage alone misses routing and serialization bugs.
47
48## 7. Git Workflow & PR Conventions
49- Conventional Commits (`feat:`, `fix:`, `refactor:`) scoped to the Rails resource, e.g. `fix(invoices): correct Sidekiq retry backoff for failed charges`.
50- Migrations ship in the same PR as the model change; run through `strong_migrations` locally before pushing.
51- Require `bundle exec rspec` and `bin/rails db:migrate:status` clean before merge.
52- Squash-merge; concurrent-index migrations get their own PR, never bundled with unrelated schema changes.

Works with Cursor · Claude Code · Windsurf · AGY

Architecture notes

Architecture Overview

Production conventions for scalable full-stack web applications and monoliths with Ruby on Rails, PostgreSQL, Redis, and Sidekiq.

Verified Real-World Adoption

This architecture is deployed by high-growth platforms including Maybe Finance, Chatwoot, and Lago.

Key Architectural Nuances

  • Thread & Pool Synchronization: Aligns Puma concurrency and Sidekiq worker pools with PostgreSQL maximum connections.
  • Zero-Downtime Schema Evolution: Employs concurrent indexing and lock-safe migrations for high-availability databases.

Frequently asked questions

Does this AGENTS.md work with Cursor, Claude Code, and Windsurf?

Yes — AGENTS.md is the open, cross-tool standard read by Cursor, Claude Code, Windsurf, and 30+ other agents. A dedicated .mdc file is also included for Cursor's native .cursor/rules format.

Why pass record IDs instead of ActiveRecord objects to Sidekiq?

Sidekiq serializes job arguments to JSON and stores them in Redis until a worker picks them up, sometimes minutes later. A serialized ActiveRecord object becomes a stale snapshot the instant it's enqueued, so passing the ID and re-fetching inside perform guarantees the job always operates on current data instead of an outdated copy.

Why does adding a database index need algorithm: :concurrently?

A standard PostgreSQL CREATE INDEX takes an exclusive lock on the table for the duration of the build, which blocks all writes on a live production table. The CONCURRENTLY algorithm builds the index without that exclusive lock, trading a slightly longer build time for zero write downtime — essential on any table receiving production traffic.

Used in production

Explore all stacks
Where this stack fits

Stack It First recommends it at:

Walk the backend roadmap