# Solid Queue y Solid Cache en Rails 8: Guía completa para entrevistas técnicas 2026 > Análisis profundo de Solid Queue y Solid Cache, los componentes por defecto respaldados por base de datos en Rails 8. Arquitectura, configuración, controles de concurrencia y conocimientos clave para entrevistas técnicas en 2026. - Published: 2026-05-13 - Updated: 2026-05-13 - Author: Anthony Fillion-Maillet - Tags: ruby-on-rails, solid-queue, solid-cache, rails-8, background-jobs, caching, interview - Reading time: 10 min --- Solid Queue y Solid Cache representan el cambio de infraestructura más significativo en la historia de Rails. Ambos componentes se incluyen por defecto en Rails 8, reemplazando Redis para trabajos en segundo plano y almacenamiento en caché con alternativas respaldadas por base de datos que eliminan una capa completa de complejidad operacional. > **La triada Solid** > > Rails 8 utiliza por defecto tres componentes respaldados por base de datos: Solid Queue (trabajos en segundo plano), Solid Cache (caché) y Solid Cable (WebSockets). En conjunto, eliminan la dependencia de Redis en la mayoría de las aplicaciones Rails. Este es un tema frecuente en las entrevistas técnicas de Rails 8. ## Cómo Solid Queue reemplaza los backends de jobs basados en Redis Solid Queue es un backend de Active Job respaldado por base de datos que almacena los jobs directamente en PostgreSQL, MySQL o SQLite. El mecanismo clave es `FOR UPDATE SKIP LOCKED` — una característica SQL disponible en PostgreSQL 9.5+ y MySQL 8+ que convierte una tabla relacional ordinaria en una cola de trabajo concurrente sin bloqueos. La arquitectura se compone de tres elementos: - **Workers**: consultan la tabla `solid_queue_ready_executions` y reservan jobs mediante `SKIP LOCKED` - **Dispatchers**: mueven los jobs programados desde `solid_queue_scheduled_executions` hacia la tabla de listos cuando llega su momento de ejecución - **Schedulers**: gestionan las tareas recurrentes definidas en la configuración ```ruby # config/solid_queue.yml production: dispatchers: - polling_interval: 1 batch_size: 500 workers: - queues: "*" threads: 5 polling_interval: 0.1 processes: 2 ``` Esta configuración ejecuta dos procesos worker con 5 hilos cada uno, consultando la base de datos cada 100 ms. El dispatcher verifica los jobs programados cada segundo en lotes de 500. ## Encolado transaccional en Rails 8 Uno de los argumentos más sólidos a favor de Solid Queue frente a los backends basados en Redis es el encolado transaccional. Cuando un job se encola dentro de una transacción de base de datos, solo se hace visible después del commit. Los backends de Redis no pueden ofrecer esta garantía — un job podría ejecutarse antes de que la transacción que lo creó finalice, referenciando registros que aún no existen. ```ruby # app/jobs/send_welcome_email_job.rb class SendWelcomeEmailJob < ApplicationJob self.enqueue_after_transaction_commit = true queue_as :default def perform(user_id) user = User.find(user_id) UserMailer.welcome(user).deliver_now end end # app/models/user.rb class User < ApplicationRecord after_create do SendWelcomeEmailJob.perform_later(id) # Job only enqueued after the CREATE transaction commits # No risk of the job running before the user record exists end end ``` Con `enqueue_after_transaction_commit` habilitado, el job se difiere hasta que la transacción que lo envuelve tenga éxito. Si la transacción hace rollback, el job nunca se encola. Esto elimina toda una categoría de condiciones de carrera que afectan a las colas respaldadas por Redis. ## Controles de concurrencia y colas prioritarias Solid Queue incluye controles de concurrencia nativos que Sidekiq solo ofrece en su versión Enterprise de pago. La opción `concurrency_limit` restringe cuántos jobs de un tipo determinado pueden ejecutarse simultáneamente. ```ruby # app/jobs/api_sync_job.rb class ApiSyncJob < ApplicationJob limits_concurrency to: 3, key: ->(account_id) { "api_sync_#{account_id}" } def perform(account_id) account = Account.find(account_id) ExternalApi.sync(account) end end ``` Esta configuración asegura que como máximo 3 jobs de sincronización API se ejecuten simultáneamente por cuenta, previniendo violaciones de límites de tasa sin coordinación externa. Los jobs bloqueados se almacenan en `solid_queue_blocked_executions` y se liberan automáticamente cuando un espacio queda disponible. La prioridad funciona en dos niveles: prioridad numérica por job (número menor = prioridad más alta) y orden de colas en la configuración del worker. Ambos se pueden combinar para un control detallado del orden de ejecución. > **Dato clave para entrevistas** > > Una pregunta habitual en entrevistas de Rails 8 se centra en las diferencias entre Solid Queue y Sidekiq. El factor diferenciador clave: Solid Queue ofrece garantías transaccionales y controles de concurrencia integrados sin costo adicional. Sidekiq supera en rendimiento bruto para cargas de alto volumen (más de 10,000 jobs/minuto) gracias al almacenamiento en memoria de Redis. Para el 95% de las aplicaciones, Solid Queue proporciona rendimiento suficiente. ## Jobs recurrentes sin cron Solid Queue reemplaza la programación basada en cron con un scheduler integrado. Las tareas recurrentes se definen en un archivo de configuración YAML y son gestionadas por el proceso scheduler. ```ruby # config/recurring.yml production: cleanup_expired_sessions: class: CleanupExpiredSessionsJob schedule: every 6 hours daily_report: class: DailyReportJob schedule: every day at 6am queue: reports weekly_digest: class: WeeklyDigestJob schedule: every Monday at 9am ``` El proceso scheduler lee este archivo y encola los jobs correspondientes en los intervalos definidos. A diferencia de cron, se ejecuta dentro del mismo supervisor de procesos y comparte la misma conexión a la base de datos. ## Despliegue con integración Puma Rails 8 con [Kamal](https://kamal-deploy.org/) proporciona despliegue sin configuración para Solid Queue. El parámetro `SOLID_QUEUE_IN_PUMA=1` indica a Puma que haga fork y supervise los procesos de Solid Queue junto al servidor web. ```ruby # config/puma.rb (Rails 8 default) plugin :solid_queue if ENV["SOLID_QUEUE_IN_PUMA"] ``` Este modelo de despliegue en un solo proceso simplifica la orquestación de contenedores. Una sola imagen Docker ejecuta tanto el servidor web como los procesadores de jobs, reduciendo la sobrecarga operacional para aplicaciones pequeñas y medianas. ## Solid Cache: caché respaldado por base de datos que escala Solid Cache es un `ActiveSupport::Cache::Store` respaldado por base de datos que aprovecha el rendimiento de los SSD modernos para reemplazar Redis y Memcached como almacén de caché por defecto. La premisa: los SSD son solo marginalmente más lentos que la RAM para operaciones de lectura, pero ofrecen órdenes de magnitud más almacenamiento a una fracción del costo. Solid Cache utiliza una estrategia de expiración FIFO (First In, First Out) en lugar de LRU (Least Recently Used). Aunque FIFO es teóricamente menos eficiente, la capacidad de almacenamiento vastamente superior compensa — las entradas permanecen en caché mucho más tiempo, reduciendo los cache misses en general. ```ruby # config/environments/production.rb config.cache_store = :solid_cache_store # config/solid_cache.yml production: databases: - cache store_options: max_age: 604800 # 1 week in seconds max_size: 256 # Max entry size in KB namespace: "app_v1" expiry_batch_size: 100 # Entries cleaned per expiry cycle ``` ## Arquitectura del caché y mecanismo de expiración Solid Cache rastrea las escrituras mediante un contador interno. Cuando el contador alcanza el 50% del `expiry_batch_size` configurado, una tarea en segundo plano se activa para limpiar las entradas expiradas. Este enfoque amortizado evita las pausas de tipo stop-the-world que pueden ocurrir con la evicción LRU en instancias de Redis con memoria limitada. La tabla `solid_cache_entries` almacena todos los datos en caché: ```ruby # db/cache_schema.rb (generated by installer) create_table :solid_cache_entries do |t| t.binary :key, null: false, limit: 1024 t.binary :value, null: false, limit: 262144 # 256 KB default t.datetime :created_at, null: false t.index :key, unique: true t.index :created_at # For FIFO expiry end ``` La lectura y escritura en esta tabla utilizan por defecto el mismo pool de conexiones que el resto de la aplicación. Para aplicaciones de alto tráfico, configurar una base de datos separada para los datos de caché evita que las operaciones de caché impacten el rendimiento de la base de datos principal. ## Configuración de base de datos separada para el caché Aislar Solid Cache en una base de datos dedicada es sencillo y recomendado para cargas de producción que generan tráfico de caché significativo. ```yaml # config/database.yml production: primary: <<: *default database: myapp_production cache: <<: *default database: myapp_cache_production migrations_paths: db/cache_migrate ``` Esta separación asegura que millones de operaciones de escritura de caché no inflen el WAL (Write-Ahead Log) de la base de datos principal ni compitan por espacios en el pool de conexiones con las consultas de la aplicación. > **Consideración para producción** > > Sin una base de datos separada, las lecturas y escrituras de Solid Cache participan en cualquier transacción `ActiveRecord` que las envuelva. Esto significa que una transacción de larga duración mantiene las entradas de caché en un estado sin commit. Es fundamental configurar una base de datos de caché dedicada para aplicaciones en producción. ## Sharding y cifrado Solid Cache soporta el sharding de datos en caché a través de múltiples bases de datos para distribuir la carga. También soporta [atributos cifrados](https://guides.rubyonrails.org/active_record_encryption.html) — los datos en caché permanecen cifrados en reposo, un requisito de cumplimiento para aplicaciones que manejan información sensible. ```ruby # config/solid_cache.yml production: databases: - cache_shard_1 - cache_shard_2 - cache_shard_3 store_options: max_age: 1209600 # 2 weeks ``` Las entradas se distribuyen entre los shards usando hashing consistente sobre la clave de caché. Agregar o eliminar shards causa un aumento temporal en los cache misses mientras las entradas se redistribuyen, pero no se produce pérdida de datos. ## Monitoreo con Mission Control Jobs [Mission Control Jobs](https://github.com/rails/mission_control-jobs) proporciona un panel web para inspeccionar y gestionar los jobs de Solid Queue. Muestra los workers, las colas y los estados de los jobs (en progreso, finalizados, bloqueados, fallidos) a través de un engine Rails montado. ```ruby # config/routes.rb Rails.application.routes.draw do mount MissionControl::Jobs::Engine, at: "/jobs" end # Gemfile gem "mission_control-jobs", ">= 1.0.1" ``` Mission Control también expone una API de consola para operaciones masivas sobre jobs fallidos: ```ruby # Rails console ActiveJob.jobs.failed.where(job_class: "ApiSyncJob").retry_all ActiveJob.jobs.failed.where(job_class: "BrokenJob").discard_all ``` Este acceso programático es esencial para manejar fallos de jobs a gran escala sin necesidad de navegar manualmente por un panel de control. ## Preguntas técnicas clave para entrevistas Las entrevistas de Rails 8 se enfocan cada vez más en el stack Solid. A continuación, las preguntas que surgen con mayor frecuencia junto con la profundidad de respuesta esperada. **P: ¿Cómo logra Solid Queue procesar jobs de forma concurrente sin Redis?** Solid Queue utiliza `FOR UPDATE SKIP LOCKED`, una cláusula SQL que permite a múltiples workers consultar la misma tabla sin bloquearse mutuamente. Cada worker bloquea un lote de filas, las procesa y elimina los registros de ejecución. Los demás workers omiten las filas ya bloqueadas y reservan jobs diferentes. **P: ¿Qué problema resuelve el encolado transaccional?** Evita que los jobs se ejecuten antes de que la transacción de base de datos que los originó haya sido commitida. Sin esto, un job podría referenciar un registro que fue revertido mediante rollback, causando errores `ActiveRecord::RecordNotFound`. **P: ¿Por qué Solid Cache usa FIFO en lugar de LRU?** FIFO es más simple de implementar en una base de datos y evita la amplificación de escritura al no necesitar actualizar marcas de tiempo de acceso en cada lectura. La compensación viene de la capacidad SSD — las entradas permanecen más tiempo, por lo que la tasa de aciertos se mantiene alta a pesar de la estrategia de evicción menos óptima. **P: ¿Cuándo debería una aplicación seguir usando Redis en lugar del stack Solid?** Redis sigue siendo superior para aplicaciones que procesan más de 10,000 jobs por minuto, cargas que requieren lecturas de caché por debajo del milisegundo, o aplicaciones que ya utilizan Redis para otros propósitos (Pub/Sub, rate limiting, almacenamiento de sesiones). El stack Solid apunta a la simplicidad, no al rendimiento máximo. Estas preguntas y muchas más se pueden practicar en los módulos [ActiveJob y trabajos en segundo plano](/technologies/ruby-on-rails/interview-questions/active-job-background-jobs) y [Estrategias de caché](/technologies/ruby-on-rails/interview-questions/caching-strategies) de SharpSkill. ## Conclusión - Solid Queue reemplaza las colas de jobs basadas en Redis con una solución respaldada por base de datos usando `FOR UPDATE SKIP LOCKED` para procesamiento concurrente - El encolado transaccional elimina las condiciones de carrera entre escrituras en base de datos y ejecución de jobs — una garantía que Redis no puede proporcionar - Los controles de concurrencia integrados, jobs recurrentes e integración con Puma se incluyen en Solid Queue sin costo adicional - Solid Cache utiliza caché FIFO respaldado por SSD con sharding y cifrado opcionales, eliminando Memcached y Redis de la pila de infraestructura - La configuración de una base de datos separada para Solid Cache evita que las operaciones de caché impacten el rendimiento de la base de datos principal - Mission Control Jobs proporciona monitoreo en producción y gestión masiva de jobs a través de un panel web y una API de consola - Para la mayoría de las aplicaciones Rails 8 en 2026, el stack Solid es la opción por defecto recomendada — Redis sigue siendo la elección solo para casos de alto rendimiento que superan los 10,000 jobs por minuto --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/es/blog/ruby-on-rails/solid-queue-solid-cache-rails-8-guide