Rails 8 + SolidQueue, SolidCache & SolidCable on Kamal 2 NVMe VPS
SQLiteEdge Rails 8 blueprint: isolating primary, queue, cache, and cable .sqlite3 WAL files on one Kamal 2 NVMe host to eliminate managed Redis.
- MODELED DESIGN TARGET
- 4x Isolated WALs
- READ PATH / RPO TARGET
- 0.42 ms
- REFERENCE NVME PROFILE
- $10.49–$48 NVMe
Rails 8 made SQLite a first-class production citizen by shipping SolidQueue, SolidCache, and SolidCable alongside automatic WAL/IMMEDIATE patches in ActiveRecord. The golden rule on a Kamal 2 single-server deployment is four separate SQLite files (`production.sqlite3`, `queue.sqlite3`, `cache.sqlite3`, `cable.sqlite3`) so high-churn cache evictions and job polling never contend with customer checkout writes.
In our SQLiteEdge BP-04 reference guide, every configuration rule below follows official SQLite 3.46 documentation and public vendor specifications retrieved 2026-11-12.
SQLiteEdge Architecture Rules for Rails 8 SolidQueue, SolidCache & Kamal Multi-SQLite
- Declare four separate database entries under production: in config/database.yml—each SQLite file gets its own independent single-writer lock and -wal journal on the NVMe bus!
- Bind-mount /var/lib/kamal-storage:/rails/storage on the host NVMe drive so container deploys never wipe persistent SQLite volumes.
- Size SolidCache max_size generously on fast local NVMe (e.g., 20 GB – 60 GB disk cache) instead of paying $120/mo for tiny 2 GB managed Redis instances.
- Back up ONLY production.sqlite3 (and optionally queue.sqlite3) via Litestream—never waste S3 bandwidth replicating ephemeral SolidCache entries.
SQLiteEdge Reference Snippet: config/database.yml (Rails 8 Multi-SQLite Production Layout)
default: &default
adapter: sqlite3
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 8 } %>
timeout: 5000
pragmas:
journal_mode: wal
synchronous: normal
mmap_size: 4294967296
cache_size: -524288
journal_size_limit: 67108864
production:
primary:
<<: *default
database: storage/production.sqlite3
queue:
<<: *default
database: storage/production_queue.sqlite3
cache:
<<: *default
database: storage/production_cache.sqlite3
cable:
<<: *default
database: storage/production_cable.sqlite3
SQLiteEdge Modeled Profile & Tariff Table (BP-04)
Public vendor prices retrieved 2026-11-12 (promotional and renewal rates may change at checkout); throughput figures reflect theoretical single-queue sizing models rather than unarchived lab claims.
| Infrastructure Component | Heroku / AWS Managed Stack | Rails 8 + Kamal on Local NVMe |
|---|---|---|
| Web + Worker Compute (16GB) | $250/mo (Dynos / ECS) | Included in $10.49–$48/mo NVMe VPS |
| Primary Database (50 GB) | $165/mo (Managed Postgres) | production.sqlite3 ($0 extra) |
| Job Queue + Cache Store | $115/mo (Managed Redis) | SolidQueue + SolidCache on NVMe ($0) |
| Total Monthly Infrastructure | $530.00/mo | $16.49 – $54.00/mo (incl. $6/mo DR) |
SQLiteEdge Spec-Matched NVMe & S3 Targets for BP-04
-
Vultr 3.5GHz+ High Frequency Local NVMe ComputeInspect Vultr Specs for BP-04 via SQLiteEdge →
3.7GHz+ Single-Core IPC + Direct PCIe NVMe • ~0.045ms fsync for Peak SQLite Single-Writer TPS (https://www.vultr.com/pricing/) -
InterServer $6 Price-Lock S3 / MinIO Litestream Backup SliceInspect InterServer S3 Slice for BP-04 via SQLiteEdge →
$6/mo Lifetime Price-Lock 1TB Slice • $0 S3 PUT API Fees for 1-Second Litestream WAL Streaming (https://www.interserver.net/vps/)
Open this BP-04 workload preset inside the SQLiteEdge PRAGMA Studio →
SQLiteEdge Engineering FAQ for BP-04
-
Will SolidQueue polling starve my primary user transactions in Rails 8?
Not when queue.sqlite3 is configured as a separate database file in database.yml! SQLite locks are per-file, so SolidQueue workers can hammer production_queue.sqlite3 while checkout writes enjoy 100% uncontended access to production.sqlite3.
-
Should I choose Hostinger EPYC KVM or Vultr High Frequency for Kamal 2?
Start on Hostinger KVM 4 (4 vCPU / 16GB / 200GB NVMe at $10.49/mo) for most SaaS apps; upgrade to Vultr 3.5GHz+ High Frequency when SolidQueue processes >1,500 jobs/second or Ruby single-thread response time becomes critical.