Writing about Rails, AI, and the messy parts of running real production software.
Long-form posts I write for my own future self. Two or three a week. If you're hiring TTB, this is the brain you'd be hiring.
Hotwire Native for Rails: Build iOS and Android Apps Without React Native or Flutter
Hotwire Native for Rails: ship native iOS and Android apps from your Rails views with bridge components, path configuration, and no React...
Postgres Logical Replication for Rails: Zero-Downtime Major Version Upgrades and Database Moves
Postgres logical replication for Rails: zero-downtime major version upgrades, provider moves, and database splits with publisher, subscri...
Sidekiq to Solid Queue Migration: A Zero-Downtime Guide for Production Rails Apps
Sidekiq to Solid Queue migration guide: dual-running, draining Redis queues, cron migration, monitoring, and a safe rollback plan for pro...
Rails Action Mailbox: Processing Inbound Emails in Production with Postmark, Mailgun and SendGrid
Rails Action Mailbox guide: process inbound emails in production with Postmark, Mailgun, SendGrid; route by domain, attach files, parse r...
Rails Claude Vision API: Extracting Data from PDFs, Receipts and Screenshots with Anthropic
Rails Claude Vision API guide: extract structured data from PDFs, receipts and screenshots with Anthropic, validate JSON output and ship ...
Rails Active Job Retries: Exponential Backoff, Circuit Breakers and Dead Letter Queues
Rails Active Job retries: exponential backoff, circuit breakers, dead letter queues, idempotency and production patterns for resilient ba...
Rails Stimulus Controllers: Production Patterns Beyond the Counter Tutorial
Rails Stimulus controllers in production: targets, values, outlets, lifecycle, debouncing, error handling, testing patterns and anti-patt...
Rails AI Agents: Multi-Step Autonomous Workflows with Claude and Tool Use
Rails AI agents that actually work in production — agent loop, tool registry, state machines, retries, cost control and observability wit...
Rails ViewComponent: Reusable UI Components, Testing and Performance Beyond Partials
Rails ViewComponent replaces partials with testable, reusable UI components. Setup, slots, previews, performance benchmarks and migration...
Rails 8 Solid Cable: ActionCable WebSockets Without Redis Using Postgres
Rails 8 Solid Cable replaces Redis for ActionCable WebSockets. Full setup, cable.yml config, LISTEN/NOTIFY internals, scaling limits and ...
Rails Read Replicas: Multiple Databases Setup with Automatic Connection Switching
Rails read replicas with multiple databases: full setup of database.yml, automatic connection switching, replica lag handling and product...
Senior Rails Engineer Interview: A Fractional CTO's Hiring Rubric for 2026
Senior Rails Engineer Interview rubric from a fractional CTO with 19 years of Rails. The questions, scoring, signals and red flags I use ...
Ruby MCP Server: Build a Model Context Protocol Server in Rails for Claude and Cursor
Ruby MCP Server in Rails: build a Model Context Protocol server, expose tools and resources to Claude and Cursor with auth and production...
Anthropic Message Batches in Rails: Cut Claude API Costs 50% with Async Batch Processing
Anthropic Message Batches in Rails: cut Claude API costs 50% with async batch processing, Solid Queue polling and idempotent result handl...
Rails 8 Authentication Generator: Build Production Sessions Without Devise
Rails 8 authentication generator in production: sessions, password reset, rate limiting, OAuth and the migration path from Devise after n...
Rails Postgres Table Partitioning: Time-Based Partitions for Large Tables in Production
Rails Postgres table partitioning for huge tables: time-based partitions, pg_partman, indexes, gotchas and a no-downtime migration playbo...
Anthropic Prompt Caching in Rails: Cut Claude API Costs with the Anthropic Ruby SDK
Anthropic prompt caching in Rails: cut Claude API costs up to 90% using the Anthropic Ruby SDK. Production patterns, traps and real numbe...
Rails Postgres Advisory Locks: Stop Cron Overlap and Race Conditions in Production
Rails Postgres advisory locks: stop cron overlap, race conditions and double processing. Production patterns and traps after nineteen yea...
Rails Pundit Authorization: Production Patterns for Multi-Tenant SaaS Apps
Rails Pundit authorization for multi-tenant SaaS: scopes, policies, role-based access, and the production traps that bite teams in their ...
Rails Puma Tuning: Workers, Threads, Memory and Concurrency for Production Performance
Rails Puma tuning in production: picking worker counts, thread pool size, memory budgets, and the copy-on-write settings that actually mo...
Rails Solid Cache: Database-Backed Caching in Rails 8 Without Redis or Memcached
Rails Solid Cache in production: disk-backed caching in Postgres, encryption, eviction, trimming, sizing, and when it beats Redis or Memc...
Rails RAG: Build a Production Retrieval Augmented Generation System with Claude and pgvector
Rails RAG guide: build a production retrieval augmented generation pipeline with pgvector, Claude and streaming. Real code, real chunking...
Postgres Autovacuum Tuning for Rails: Stop Table Bloat and Transaction ID Wraparound in Production
Postgres autovacuum tuning for Rails in production. Stop table bloat, prevent transaction ID wraparound and tame lock storms with practic...
Rails Solid Queue: Background Jobs in Postgres Without Redis or Sidekiq
Rails Solid Queue in production: Postgres-backed background jobs, configuration, concurrency, scheduled tasks, and when to stay on Sideki...
Rails Postgres JSONB: Query Patterns, Indexing and Production Best Practices
Rails Postgres JSONB in production: query patterns, GIN indexes, store_accessor, safe migrations, and when to choose JSONB over normalize...
Rails Full-Text Search: pg_search, tsvector and Postgres Without Elasticsearch
Rails full-text search with pg_search: tsvector indexes, ranked results, trigram similarity, and why Postgres replaces Elasticsearch for ...
Rails Active Storage S3: Direct Uploads, Variants and Production Configuration
Rails Active Storage S3 direct uploads: image variants, background processing, presigned URLs, virus scanning and a complete production c...
Rails Webhook Processing: Signature Verification, Idempotency and Background Delivery
Rails webhook processing done right: HMAC signature verification, idempotent handlers, Stripe and GitHub examples, background jobs and er...
Ruby on Rails Feature Flags: Complete Guide with Flipper, Rollout and Custom Redis Implementation
Ship Rails features safely with feature flags. Flipper setup, custom Redis flags, percentage rollouts, CI/CD integration, testing strateg...
What I Do First When I Inherit a Legacy Rails Codebase
A fractional CTO's practical framework for the first 30 days taking over someone else's Rails app. Where to look, what to fix, how to wri...
LLM Function Calling in Rails: Teaching the Model to Use Your App
Function calling lets LLMs invoke your Rails code directly. Here's how to build reliable tool-use integrations that hold up in production.
PgBouncer and Rails: Connection Pooling That Doesn't Blow Up Your Database
Most Rails apps eventually hit Postgres connection exhaustion. Here's how to configure PgBouncer correctly—and the transaction-mode gotch...
Technical Due Diligence on a Rails Codebase: What I Actually Check
Before you acquire a company or sign on as fractional CTO, here's the Rails codebase audit I run every time — and what the findings usual...
Streaming LLM Responses in Rails: Stop Making Users Stare at a Spinner
Add real-time streaming to your Rails LLM features using Action Controller::Live and Server-Sent Events. Practical code, Puma thread setu...
How to Upgrade a Rails App Without a Big-Bang Rewrite
An incremental strategy for upgrading legacy Rails apps from 6.1 to 8.0 in production — without burning it down or blocking your team for...
Semantic Search in Rails with pgvector: From Zero to Production
Add semantic search to your Rails app using pgvector and OpenAI embeddings. Real code, real migrations, and production tuning with HNSW i...
Rails ActiveRecord Callbacks: When They Help and When They'll Burn You
ActiveRecord callbacks save time until they create untraceable bugs. Learn which callbacks are safe, which to avoid, and what to use inst...
Build Custom Rails 8 Generators to Eliminate Repetitive Boilerplate
Stop copying and pasting the same service object scaffolding. Write a custom Rails generator in under 30 minutes that enforces your team'...
Ruby Ractors: Real Parallel Processing Without the GVL
Ruby’s Global VM Lock (GVL, formerly GIL) has been the standard excuse for reaching for Go or Elixir when you need true parallelism. Ract...
Debug Memory Leaks in Ruby on Rails: A Production Hunting Guide
Memory leaks in Rails apps are rarely actual leaks — they're unbounded growth from caches, string retention, and forgotten callbacks. Her...
Rails Credentials: Managing Secrets in Production Without Losing Your Mind
Rails credentials offer built-in encrypted secrets management. Here's how to set them up per-environment, rotate keys, and avoid the pitf...
Kamal 2 Deploy Rails: Zero-Downtime Deployments Without Kubernetes
Kamal 2 gives Rails teams zero-downtime deployments on bare metal or VPS without the complexity of Kubernetes. This guide walks through s...
Rails N+1 Queries: How to Find, Fix, and Prevent Them in Production
N+1 queries are the most common Rails performance killer. Here's how to detect them with Bullet and strict_loading, fix them with include...
Ruby method_missing: When to Use It and When to Run Away
method_missing is Ruby's most powerful and most abused metaprogramming tool. Here's how to use it correctly in production, with real exam...
Rate Limiting in Rails with Rack::Attack: A Production Configuration Guide
Set up Rack::Attack in Rails 8 to throttle abusive requests, block bad actors, and protect your API endpoints. Includes production-tested...
Ruby Refinements: Scoped Monkey Patching That Won't Blow Up Your App
Ruby refinements let you modify classes within a controlled scope instead of globally. Learn when to use them, how they work under the ho...
Rails 8 load_async: Run Database Queries in Parallel and Cut Response Times
How to use load_async, async_count, and async_sum in Rails 8 to parallelize database queries, with benchmarks showing 40-60% faster contr...
Fast Rails Tests: How Minitest and Fixtures Outperform Factory-Heavy Suites
Speed up your Rails test suite by switching from factories to fixtures and using Minitest effectively. Includes benchmarks, migration str...
AI Code Review for Rails: Tools and Workflows That Actually Catch Bugs
How to set up AI-assisted code review in Rails projects using GitHub Copilot, Claude, and custom prompts. Real examples of bugs caught, f...
Ruby Struct vs Data: Choosing the Right Value Object in Ruby 3.2+
A practical comparison of Ruby's Struct and Data classes for building value objects. Benchmarks, use cases, and migration patterns for Ru...
Rails 8 Propshaft: How to Migrate from Sprockets (Step by Step)
Propshaft replaced Sprockets as the default asset pipeline in Rails 8. If you’re upgrading an existing app, the migration isn’t automatic...
Ruby Lazy Enumerators: Process Million-Row Datasets Without Blowing Up Memory
Learn how Ruby's Lazy Enumerators let you process enormous datasets line by line, keeping memory flat. Includes benchmarks, real producti...
Rails Concerns: When They Clean Up Code and When They Create Hidden Complexity
A practical guide to Rails ActiveSupport::Concern with real examples of good and bad uses. Learn when concerns reduce duplication, when t...
Rails 8 Multiple Databases: Read Replicas, Sharding, and Automatic Role Switching
How to configure multiple databases in Rails 8 with read replicas, horizontal sharding, and automatic connection switching. Includes prod...
Custom Rack Middleware in Rails 8: A Practical Guide with Real Examples
How to write, test, and deploy custom Rack middleware in Rails 8. Covers request timing, tenant detection, request ID propagation, and th...
Rails 8 Solid Cache: Drop Redis and Memcached for Good
Solid Cache stores your Rails cache in the database instead of Redis or Memcached. If you’re running Rails 8, you can cut an entire infra...
Docker Multi-Stage Builds for Rails 8: Cut Your Image Size by 60%
Step-by-step guide to building production Docker images for Rails 8 using multi-stage builds. Reduce image size from 1.2GB to under 500MB...
Ruby Proc vs Lambda: The Real Differences and When to Use Each
A practical comparison of Ruby Procs and Lambdas covering argument handling, return behavior, and real-world use cases in Rails applicati...
Ruby Pattern Matching: From Basic case/in to Production Use Cases
Ruby’s pattern matching, introduced in Ruby 2.7 and stabilized in Ruby 3.0, gives you a way to destructure and match complex data structu...
How to Prioritize Technical Debt: A Framework That Actually Works
A practical framework for prioritizing technical debt in startups and growing teams. Covers scoring methods, real examples, and how to se...
Ruby frozen_string_literal: What It Does and How to Use It in Production
Learn what Ruby's frozen_string_literal magic comment does, how it reduces memory allocation and prevents mutation bugs, and how to adopt...
Ruby YJIT in Production: How to Enable It and What Performance Gains to Expect
A practical guide to enabling YJIT in Ruby 3.3 for production Rails apps. Covers configuration, memory trade-offs, real benchmarks, and m...
OpenTelemetry in Rails 8: Set Up Production Observability in 30 Minutes
A step-by-step guide to instrumenting a Rails 8 application with OpenTelemetry for traces, metrics, and logs. Includes gem configuration,...
Rails Turbo Frames: Build Dynamic UIs Without Writing JavaScript
How to use Turbo Frames in Rails 8 to create fast, dynamic interfaces with lazy loading, inline editing, and frame navigation — no custom...
Ruby Memoization Patterns: Beyond the Basic ||= Operator
Production-tested Ruby memoization patterns including ||=, fetch-based caching, multi-argument memoization, and thread-safe approaches. I...
Rate Limit Your Rails API With Rack::Attack (Step-by-Step)
How to add rate limiting to a Rails 8 API using Rack::Attack. Covers throttling, blocklists, custom responses, and production configurati...
Rails Database Indexing: Fix Slow Queries With the Right Index Strategy
Practical guide to database indexing in Rails. Covers composite indexes, partial indexes, expression indexes, and how to find missing ind...
ActiveRecord Encryption in Rails 7+: Encrypt Sensitive Data Without Leaving Your ORM
A practical guide to encrypting database columns with ActiveRecord Encryption in Rails 7 and 8. Covers setup, key rotation, querying encr...
Rails 8 Solid Cable: Drop Redis for WebSockets and Save Yourself a Dependency
How to set up Solid Cable in Rails 8 for Action Cable over SQLite or PostgreSQL. Covers configuration, performance characteristics, migra...
Ruby Delegation: Forwardable vs SimpleDelegator vs Rails delegate
A practical comparison of Ruby's three main delegation approaches. When to use Forwardable, SimpleDelegator, or Rails delegate — with ben...
Deploy Rails 8 with Kamal 2: A Production-Ready Setup From Scratch
Step-by-step guide to deploying Rails 8 with Kamal 2. Covers server setup, Docker configuration, SSL, database migrations, and the gotcha...
Ruby GC Tuning: Cut Rails Memory Bloat and Response Times in Production
Practical Ruby garbage collection tuning for Rails apps. Real RUBY_GC_* environment variables, before/after benchmarks, and the settings ...
Ruby Fiber Scheduler: Fast Async I/O Without Callbacks or Threads
How to use Ruby's Fiber Scheduler interface for non-blocking I/O in Ruby 3.3+. Real benchmarks, practical examples, and production patter...
Rails Service Objects: Patterns That Actually Work in Production
How to build Rails service objects that stay maintainable. Real patterns, naming conventions, error handling, and testing strategies from...
Rails 8 Authentication: The Built-in Generator That Replaces Devise
How to set up authentication in Rails 8 using the new built-in generator. Step-by-step guide covering sessions, password resets, and when...
Ruby Struct vs Data: Which Value Object Fits Your Code?
A practical comparison of Ruby's Struct and Data classes for building value objects. When to use each, performance differences, and real ...
Building Pixevo: Engineering Challenges Behind an AI Image Platform
How we built a multi-model AI image generation platform with Rails — workflow engines, real-time processing, and the architecture decisio...
Rails Strict Loading: How to Catch N+1 Queries Before They Hit Production
Enable strict loading in Rails 6.1+ to detect and prevent N+1 queries at development time. Configuration options, per-model and global se...
AI Coding Assistants for Rails: What Actually Works and What Wastes Your Time
A practical breakdown of using AI coding assistants (Copilot, Cursor, Claude) in Rails projects. What tasks they handle well, where they ...
Ruby Ractors: Actual Parallel Processing Without Fighting the GVL
How to use Ruby Ractors for true parallel CPU-bound work in Ruby 3.3+. Practical examples, benchmarks, and pitfalls from production use.
Fractional CTO: When Your Startup Needs One (And When It Doesn't)
Every startup hits the same inflection point. Your Rails app works, your first customers are paying, and suddenly everything is on fire. ...
GitHub Actions for Rails in 2026: A CI/CD Pipeline That Actually Works
A complete GitHub Actions CI/CD pipeline for Rails: parallel tests, service containers, lint-first strategy, and deployment. Under 5 minu...
Ruby Pattern Matching: Stop Writing Nested if/elsif Chains
Ruby pattern matching with case/in replaces nested conditionals for destructuring hashes, validating API responses, and parsing webhooks....
Multi-Tenancy in Rails: Three Approaches and When Each One Breaks
Scoped queries, schema-per-tenant, or database-per-tenant? A practical comparison of Rails multi-tenancy approaches with real-world break...
Rails Logging You Can Actually Debug With
Default Rails logs are verbose and useless under pressure. Here's how to set up structured logging that helps you find problems fast — wi...
Background Jobs in Rails: Choosing Between Solid Queue and Sidekiq in 2026
A practical guide to picking the right background job backend for your Rails app. When Solid Queue makes sense, when Sidekiq still wins, ...
Rails Caching: What They Don't Tell You in the Tutorials
Fragment caching, Russian Doll patterns, cache invalidation that actually works, and the debugging tricks I've learned from production in...
Feature Flags in Rails: Ship Faster, Break Less
How to implement feature flags in Rails applications for safer deployments, gradual rollouts, and the ability to kill a bad feature witho...
Database Migrations That Won't Wake You at 3 AM
Practical techniques for zero-downtime Rails database migrations. Stop locking tables, start sleeping through the night.
It's a phone call. That's the worst it can get.
No discovery deck. No 45-minute "qualification" call. 30 minutes, your problem, my opinion. If we're a fit, you'll know by minute 12.