← Extractions

How (and why) to run SQLite in production — Stephen Margheim at wroclove.rb 2024

Stephen Margheim's wroclove.rb 2024 talk argues SQLite is a viable, and often excellent, production database for Rails applications. He explains why SQLite's linear-write limitation isn't a showstopper, walks through four performance fixes (immediate transactions, non-blocking busy timeout, fair retry interval, WAL mode) plus an experimental isolated reader/writer connection pool, and introduces his enhanced-sqlite3-adapter and Litestream gems that package the solution.

Model
claude-opus-4-7
Ingestion
b3fbbf61
Input tokens
504,835
fresh
308,455
cached
178,649
cache write
17,731
Output tokens
17,586
Duration
263.7s
Roundtrips
9
Tool calls
23
Cost
$0.00
Nodes/edges extracted
30 / 67
Read set (nodes/edges)
150 / 3

Nodes (30)

update Stephen Margheim person
attrs (empty) → {"role" => "Head of Engineering at test.io", "twitter" => "@fractaledmind", "location" => "Berlin, Germany"}
description Conference speaker. → American developer living in Berlin, Germany since ~2019. Head of engineering at test.io (a crowd-driven QA testing c...
short_description Conference speaker. → Head of Engineering at test.io; Ruby/Rails open source developer focused on SQLite-on-Rails.
update How (and why) to run SQLite in production talk
description Talk at wroclove.rb 2024. → Stephen Margheim's wroclove.rb 2024 single-speaker talk arguing that SQLite is a viable choice for production Rails a...
short_description Talk at wroclove.rb 2024. → wroclove.rb 2024 talk on making SQLite production-ready for Rails applications.
create test.io company
kind (empty) → company
name (empty) → test.io
slug (empty) → test-io
attrs (empty) → {"industry" => "software QA / testing"}
description (empty) → Crowd-driven quality-assurance testing company. Stephen Margheim is the Head of Engineering. In 2024 the team finishe...
short_description (empty) → Crowd-driven QA testing company; Stephen Margheim's day-job employer.
create Ben Johnson person
kind (empty) → person
name (empty) → Ben Johnson
slug (empty) → ben-johnson
description (empty) → Creator of Litestream (point-in-time SQLite replication to S3-compatible storage) and its successor LiteFS (multi-nod...
short_description (empty) → Creator of Litestream and LiteFS; works at Fly.io on SQLite replication.
create Fly.io company
kind (empty) → company
name (empty) → Fly.io
slug (empty) → fly-io
attrs (empty) → {"industry" => "cloud hosting"}
description (empty) → Cloud platform where Ben Johnson works on Litestream and LiteFS.
short_description (empty) → Cloud platform; employer of Ben Johnson and home to LiteFS.
create Litestream tool
kind (empty) → tool
name (empty) → Litestream
slug (empty) → litestream
attrs (empty) → {"category" => "service"}
description (empty) → Go-based utility by Ben Johnson that streams every operation from a SQLite WAL file to any S3-compatible object store...
short_description (empty) → Streaming point-in-time backup utility for SQLite databases to S3-compatible storage.
create LiteFS tool
kind (empty) → tool
name (empty) → LiteFS
slug (empty) → litefs
attrs (empty) → {"category" => "service"}
description (empty) → Ben Johnson's successor to Litestream, enabling multi-node SQLite deployments. Mentioned as the option for applicatio...
short_description (empty) → Multi-node SQLite replication built by Ben Johnson, successor to Litestream.
create Turso company
kind (empty) → company
name (empty) → Turso
slug (empty) → turso
attrs (empty) → {"industry" => "managed database service"}
description (empty) → Managed cloud SQLite service. Margheim cites Turso as 'one of the last generous free tiers in the managed-database sp...
short_description (empty) → Managed cloud SQLite service known for a generous free tier.
create enhanced-sqlite3-adapter tool
kind (empty) → tool
name (empty) → enhanced-sqlite3-adapter
slug (empty) → enhanced-sqlite3-adapter
attrs (empty) → {"license" => "open-source", "category" => "library", "language" => "Ruby"}
description (empty) → Ruby gem written and maintained by Stephen Margheim that automatically patches a Rails application's SQLite configura...
short_description (empty) → Ruby gem packaging production-ready SQLite configuration and Active Record enhancements for Rails.
create litestream-ruby tool
kind (empty) → tool
name (empty) → litestream-ruby
slug (empty) → litestream-ruby
attrs (empty) → {"license" => "open-source", "category" => "library", "language" => "Ruby"}
description (empty) → Ruby gem by Stephen Margheim that wraps the Litestream Go executable, maps its configuration into a Rails application...
short_description (empty) → Ruby gem wrapping the Litestream Go binary for easy Rails integration.
create sqlite3-ruby tool
kind (empty) → tool
name (empty) → sqlite3-ruby
slug (empty) → sqlite3-ruby
attrs (empty) → {"category" => "library", "language" => "Ruby"}
description (empty) → Ruby gem that binds SQLite to Ruby; the driver used by Active Record for SQLite connections. Since version 1.6.9 it a...
short_description (empty) → Ruby driver gem binding SQLite to Ruby and Active Record.
create Hatchbox tool
kind (empty) → tool
name (empty) → Hatchbox
slug (empty) → hatchbox
attrs (empty) → {"category" => "platform"}
description (empty) → Deployment platform cited as making it easy to throw a Rails application onto a single node — enough architecture, in...
short_description (empty) → Single-node deployment platform for Rails applications.
create Immediate Transactions concept
kind (empty) → concept
name (empty) → Immediate Transactions
slug (empty) → immediate-transactions
attrs (empty) → {"category" => "pattern"}
description (empty) → SQLite transaction mode (BEGIN IMMEDIATE) that tries to acquire the write lock when the transaction starts, rather th...
short_description (empty) → SQLite transaction mode that acquires the write lock at BEGIN instead of deferring it.
create SQLite Busy Handler concept
kind (empty) → concept
name (empty) → SQLite Busy Handler
slug (empty) → sqlite-busy-handler
attrs (empty) → {"category" => "pattern"}
description (empty) → SQLite C API hook (sqlite3_busy_handler) invoked whenever a connection fails to acquire the write lock. SQLite's ship...
short_description (empty) → Callback invoked when a SQLite connection can't acquire the write lock; replaces busy_timeout.
create Write-Ahead Logging (WAL) Mode concept
kind (empty) → concept
name (empty) → Write-Ahead Logging (WAL) Mode
slug (empty) → write-ahead-logging-wal-mode
attrs (empty) → {"category" => "pattern"}
description (empty) → SQLite journal mode enabled via `PRAGMA journal_mode=WAL`. Under the default rollback journal, reads and writes conte...
short_description (empty) → SQLite journal mode allowing concurrent reads alongside a single writer.
create Replace SQLite's C busy_timeout with a GVL-releasing Ruby handler takeaway
kind (empty) → takeaway
name (empty) → Replace SQLite's C busy_timeout with a GVL-releasing Ruby handler
slug (empty) → replace-sqlite-s-c-busy_timeout-with-a-gvl-releasing-ruby-handler
attrs (empty) → {"type" => "recommendation"}
description (empty) → SQLite's native busy_timeout is a C callback that keeps holding Ruby's GVL during its waits, preventing other Puma wo...
short_description (empty) → Implement busy_handler in Ruby using Sleep so it releases the GVL during DB waits.
create Isolated Reader/Writer Connection Pools concept
kind (empty) → concept
name (empty) → Isolated Reader/Writer Connection Pools
slug (empty) → isolated-reader-writer-connection-pools
attrs (empty) → {"category" => "pattern"}
description (empty) → Experimental technique demonstrated by Stephen Margheim: abuse Active Record's three-tier multiple-database support t...
short_description (empty) → Technique splitting Active Record's connection pool into separate read and write pools against one SQLite file.
create Branch-Specific SQLite Databases concept
kind (empty) → concept
name (empty) → Branch-Specific SQLite Databases
slug (empty) → branch-specific-sqlite-databases
attrs (empty) → {"category" => "practice"}
description (empty) → Developer-experience pattern enabled by SQLite's file-as-database nature. database.yml runs through ERB, which can sh...
short_description (empty) → Developer-experience trick giving each git branch its own SQLite database file.
create Deferred Requests concept
kind (empty) → concept
name (empty) → Deferred Requests
slug (empty) → deferred-requests
attrs (empty) → {"category" => "pattern"}
description (empty) → Request-level analog of SQLite's deferred transactions that Margheim invented for isolated reader/writer connection p...
short_description (empty) → Default every web request to a read connection and switch to the write connection only for writes.
create Solid Queue project
kind (empty) → project
name (empty) → Solid Queue
slug (empty) → solid-queue
attrs (empty) → {"status" => "active", "license" => "open-source"}
description (empty) → Database-backed background-job queue for Rails that lets Active Job run without Redis. Part of the new 'solid' ecosys...
short_description (empty) → Database-backed Rails Active Job queuing backend, part of Rails' 'solid' ecosystem.
create Solid Cache project
kind (empty) → project
name (empty) → Solid Cache
slug (empty) → solid-cache
attrs (empty) → {"status" => "active", "license" => "open-source"}
description (empty) → Database-backed Active Support cache store in the 'solid' ecosystem. Enables Rails applications to use a SQL database...
short_description (empty) → Database-backed Rails cache store.
create Solid Cable project
kind (empty) → project
name (empty) → Solid Cable
slug (empty) → solid-cable
attrs (empty) → {"status" => "active", "license" => "open-source"}
description (empty) → In-progress database-backed Action Cable adapter in the 'solid' ecosystem. Margheim looks forward to being able to ho...
short_description (empty) → In-progress database-backed Action Cable adapter.
create Mike Dalessio person
kind (empty) → person
name (empty) → Mike Dalessio
slug (empty) → mike-dalessio
description (empty) → Ruby developer who collaborated with Stephen Margheim in 2023 to enable configuring SQLite compile-time flags through...
short_description (empty) → Ruby developer who collaborated on SQLite Bundler compilation-flags support.
create Add enhanced-sqlite3-adapter for production SQLite on Rails takeaway
kind (empty) → takeaway
name (empty) → Add enhanced-sqlite3-adapter for production SQLite on Rails
slug (empty) → add-enhanced-sqlite3-adapter-for-production-sqlite-on-rails
attrs (empty) → {"type" => "recommendation"}
description (empty) → Minimum path to a production-ready SQLite Rails app today: `bundle add enhanced-sqlite3-adapter` (performance: immedi...
short_description (empty) → Three CLI commands package SQLite-on-Rails production readiness.
create Use Immediate Transactions for Rails takeaway
kind (empty) → takeaway
name (empty) → Use Immediate Transactions for Rails
slug (empty) → use-immediate-transactions-for-rails
attrs (empty) → {"type" => "recommendation"}
description (empty) → Rails wraps every write in a transaction and uses a connection pool of five by default, so SQLite's deferred-mode tra...
short_description (empty) → Set default_transaction_mode: immediate to avoid SQLite3::BusyException in Rails.
create Use a fair retry interval for SQLite writes takeaway
kind (empty) → takeaway
name (empty) → Use a fair retry interval for SQLite writes
slug (empty) → use-a-fair-retry-interval-for-sqlite-writes
attrs (empty) → {"type" => "insight"}
description (empty) → SQLite's shipped busy-timeout algorithm waits up to 100 ms per retry after 12 iterations, penalizing older queries re...
short_description (empty) → Constant 1 ms retry beats SQLite's native exponential-ish backoff for steady write streams.
create Run Litestream from day one takeaway
kind (empty) → takeaway
name (empty) → Run Litestream from day one
slug (empty) → run-litestream-from-day-one
attrs (empty) → {"type" => "warning"}
description (empty) → Every SQLite Rails application should configure Litestream from day one to stream its WAL to an S3-compatible bucket....
short_description (empty) → Stream SQLite writes to S3 from the first deploy — production data loss is too costly otherwise.
create Start simple: single-node SQLite is usually enough to reach revenue takeaway
kind (empty) → takeaway
name (empty) → Start simple: single-node SQLite is usually enough to reach revenue
slug (empty) → start-simple-single-node-sqlite-is-usually-enough-to-reach-revenue
attrs (empty) → {"type" => "insight"}
description (empty) → Most new applications can reach revenue on a single node with SQLite, simple tooling like Hatchbox, and typical 200-3...
short_description (empty) → Most applications don't actually need multi-node or exotic infrastructure to start.
create Isn't embedding the database in your app process a security regression? question
kind (empty) → question
name (empty) → Isn't embedding the database in your app process a security regression?
slug (empty) → isn-t-embedding-the-database-in-your-app-process-a-security-regression
attrs (empty) → {"answer_summary" => "Trade-off is real but symmetric (one hardening surface vs. many). For most apps the leverage is...
description (empty) → Audience question: embedding SQLite inside the application process trades away the isolation security principle that ...
short_description (empty) → Does putting SQLite inside the Ruby process sacrifice isolation for performance?
create Is starting with SQLite a lock-in if I later need Postgres? question
kind (empty) → question
name (empty) → Is starting with SQLite a lock-in if I later need Postgres?
slug (empty) → is-starting-with-sqlite-a-lock-in-if-i-later-need-postgres
attrs (empty) → {"answer_summary" => "No meaningful lock-in: SQLite types are a subset of Postgres's, Active Record abstracts the DB,...
description (empty) → Audience question: if a hobby project grows, can I switch from SQLite to Postgres without pain? Margheim: short answe...
short_description (empty) → Can a SQLite-on-Rails app migrate to Postgres once it gets big?

Edges (67)

update Stephen Margheim → authored → How (and why) to run SQLite in production
context (empty) → Margheim delivered this single-speaker talk at wroclove.rb 2024.
update How (and why) to run SQLite in production → presented_at → wroclove.rb 2024
context (empty) → The talk was presented at wroclove.rb 2024.
create Stephen Margheim → works_at → test.io
attrs (empty) → {"role" => "Head of Engineering"}
context (empty) → Margheim is Head of Engineering at test.io.
relation (empty) → works_at
source_node_id (empty) → f8314bba-5263-4bd3-9174-6613ee5fef9e
target_node_id (empty) → 3fbc8075-91e9-46bd-a21c-8f367aec379d
create Turso → uses → SQLite
context (empty) → Turso is a managed cloud SQLite service.
relation (empty) → uses
source_node_id (empty) → d778467e-daea-4c6e-bf19-937f93071bde
target_node_id (empty) → a65d4872-7d76-4774-a7d5-e29e615de75a
create Stephen Margheim → works_on → enhanced-sqlite3-adapter
attrs (empty) → {"role" => "author/maintainer"}
context (empty) → Margheim created and maintains the gem.
relation (empty) → works_on
source_node_id (empty) → f8314bba-5263-4bd3-9174-6613ee5fef9e
target_node_id (empty) → b4df1de7-ba12-4587-9b8a-89ab435a4ea6
create Stephen Margheim → works_on → litestream-ruby
attrs (empty) → {"role" => "author"}
context (empty) → Margheim wrote the Ruby gem wrapping the Litestream Go binary.
relation (empty) → works_on
source_node_id (empty) → f8314bba-5263-4bd3-9174-6613ee5fef9e
target_node_id (empty) → 873bb381-a8b7-4e04-8a18-8dc7becb60a6
create Stephen Margheim → works_on → sqlite3-ruby
attrs (empty) → {"role" => "contributor"}
context (empty) → Margheim landed the fair non-blocking busy_handler on the gem's main branch.
relation (empty) → works_on
source_node_id (empty) → f8314bba-5263-4bd3-9174-6613ee5fef9e
target_node_id (empty) → b9a354eb-a956-42a4-8d54-853f596fd5e8
create Stephen Margheim → works_on → Ruby on Rails
attrs (empty) → {"role" => "contributor"}
context (empty) → Margheim contributes to Rails and plans a PR wiring database.yml timeout to the new fair busy_handler for Rails 8.
relation (empty) → works_on
source_node_id (empty) → f8314bba-5263-4bd3-9174-6613ee5fef9e
target_node_id (empty) → 7aac705a-0987-49f2-b665-9d4e08a6acee
create Stephen Margheim → recommends → SQLite
context (empty) → Entire talk recommends SQLite as a production database engine for Rails apps.
relation (empty) → recommends
source_node_id (empty) → f8314bba-5263-4bd3-9174-6613ee5fef9e
target_node_id (empty) → a65d4872-7d76-4774-a7d5-e29e615de75a
create Stephen Margheim → recommends → Litestream
context (empty) → Strongly recommends running Litestream from day one for SQLite backups.
relation (empty) → recommends
source_node_id (empty) → f8314bba-5263-4bd3-9174-6613ee5fef9e
target_node_id (empty) → c8b1820d-3884-4b11-aedc-e33d07ed1896
create Stephen Margheim → recommends → enhanced-sqlite3-adapter
context (empty) → Recommends `bundle add enhanced-sqlite3-adapter` as the easy path to production-ready SQLite on Rails.
relation (empty) → recommends
source_node_id (empty) → f8314bba-5263-4bd3-9174-6613ee5fef9e
target_node_id (empty) → b4df1de7-ba12-4587-9b8a-89ab435a4ea6
create How (and why) to run SQLite in production → about → SQLite
context (empty) → Core subject of the talk.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → a65d4872-7d76-4774-a7d5-e29e615de75a
create How (and why) to run SQLite in production → about → Ruby on Rails
context (empty) → Focuses on SQLite for Rails applications specifically.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → 7aac705a-0987-49f2-b665-9d4e08a6acee
create How (and why) to run SQLite in production → about → enhanced-sqlite3-adapter
context (empty) → The talk walks through what the gem does and why.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → b4df1de7-ba12-4587-9b8a-89ab435a4ea6
create How (and why) to run SQLite in production → about → Litestream
context (empty) → Talk recommends Litestream and the litestream Ruby gem for resilience.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → c8b1820d-3884-4b11-aedc-e33d07ed1896
create How (and why) to run SQLite in production → about → Immediate Transactions
context (empty) → First performance fix demonstrated in the talk.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → cb92d7be-3aea-41d0-b6e4-94ab345d62ad
create How (and why) to run SQLite in production → about → SQLite Busy Handler
context (empty) → Second and third performance fixes (GVL release and fair retry) are implementations of a custom busy_handler.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → a6435583-9d23-4f45-83d2-69a76ee4dbc0
create How (and why) to run SQLite in production → about → Write-Ahead Logging (WAL) Mode
context (empty) → Fourth of the four performance keys; now a Rails 7.1 default.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → 1ee86e2d-95b9-499d-88fb-399006e36ec7
create How (and why) to run SQLite in production → about → Isolated Reader/Writer Connection Pools
context (empty) → Experimental fifth performance technique demonstrated via Active Record's multi-database support.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → 2530347b-3d21-496b-9bf6-8145caebb1c6
create How (and why) to run SQLite in production → about → Deferred Requests
context (empty) → Invented concept for making isolated reader/writer pools transparent to controllers.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → 43898c09-d49c-413d-84fa-a4f51b6a9b99
create How (and why) to run SQLite in production → about → Branch-Specific SQLite Databases
context (empty) → Developer-experience tip demonstrated near the end of the talk.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → 842b2627-4a58-4c69-9c9c-7255979445c8
create How (and why) to run SQLite in production → about → Global Interpreter Lock
context (empty) → Core reason SQLite's native busy_timeout harms Rails concurrency — it holds the GVL.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → b2da1bdf-0293-4d62-8478-327f08bd9f7f
create How (and why) to run SQLite in production → about → Active Record
context (empty) → Discusses Active Record's connection pool, transaction wrapping, and multi-database support.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → 633eeea8-2026-4906-b512-1e239f3db152
create How (and why) to run SQLite in production → about → PostgreSQL
context (empty) → Extensive comparison between running SQLite and running Postgres in various cloud topologies.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → 46fc2697-69fc-436b-ac82-250ba4370273
create How (and why) to run SQLite in production → about → N+1 Queries
context (empty) → Notes the SQLite docs' advice that you should probably not prematurely optimize away N+1 queries when using SQLite.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → ee033151-443a-4285-aa68-fbc2e9755d06
create How (and why) to run SQLite in production → about → Solid Queue
context (empty) → Mentions the 'solid' ecosystem as a good fit for a SQLite-foundation future of Rails.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → bc443bd9-cc27-4641-8b44-b26cbc448fde
create How (and why) to run SQLite in production → about → Solid Cache
context (empty) → Mentions Solid Cache alongside Solid Queue in the SQLite-foundation vision.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → 24d8b6b6-e8b0-45cc-936c-58dd26744522
create How (and why) to run SQLite in production → about → Solid Cable
context (empty) → Margheim looks forward to having a cable.sqlite3 file once Solid Cable ships.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → f10a456d-470c-4e6d-9187-5cd59d1eacbd
create How (and why) to run SQLite in production → about → Turso
context (empty) → Cited as an example of a generous free tier enabled by SQLite's cost profile.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → d778467e-daea-4c6e-bf19-937f93071bde
create How (and why) to run SQLite in production → about → DHH
context (empty) → Cites DHH's Rails World keynote reiterating Rails as the one-person framework.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → 51ed6191-ce15-4ca5-9eed-d55908e5ab88
create How (and why) to run SQLite in production → about → Hatchbox
context (empty) → Cites Hatchbox as making single-node deployment easy.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → ace2d786-db23-42f4-9d25-e0f4c3d4ae56
create How (and why) to run SQLite in production → about → LiteFS
context (empty) → Mentioned as the option when you genuinely need multi-node SQLite.
relation (empty) → about
source_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
target_node_id (empty) → 7a2a4607-012c-4103-a937-862a8e7ac575
create Ben Johnson → works_on → Litestream
attrs (empty) → {"role" => "creator"}
context (empty) → Ben Johnson created Litestream.
relation (empty) → works_on
source_node_id (empty) → cb636806-7c20-42e8-90cc-be4296fa173d
target_node_id (empty) → c8b1820d-3884-4b11-aedc-e33d07ed1896
create Ben Johnson → works_on → LiteFS
attrs (empty) → {"role" => "creator"}
context (empty) → Ben Johnson built LiteFS as the multi-node successor to Litestream.
relation (empty) → works_on
source_node_id (empty) → cb636806-7c20-42e8-90cc-be4296fa173d
target_node_id (empty) → 7a2a4607-012c-4103-a937-862a8e7ac575
create Ben Johnson → works_at → Fly.io
context (empty) → Ben Johnson now works at Fly.io on SQLite replication.
relation (empty) → works_at
source_node_id (empty) → cb636806-7c20-42e8-90cc-be4296fa173d
target_node_id (empty) → e1757733-4b73-4331-a438-db828fc52a0a
create enhanced-sqlite3-adapter → uses → SQLite
context (empty) → The gem configures and extends SQLite via the sqlite3 Ruby driver.
relation (empty) → uses
source_node_id (empty) → b4df1de7-ba12-4587-9b8a-89ab435a4ea6
target_node_id (empty) → a65d4872-7d76-4774-a7d5-e29e615de75a
create enhanced-sqlite3-adapter → uses → sqlite3-ruby
context (empty) → Patches initializers on top of the sqlite3 gem's driver.
relation (empty) → uses
source_node_id (empty) → b4df1de7-ba12-4587-9b8a-89ab435a4ea6
target_node_id (empty) → b9a354eb-a956-42a4-8d54-853f596fd5e8
create enhanced-sqlite3-adapter → uses → Active Record
context (empty) → Patches Active Record's SQLite adapter and backports adapter features from Rails main.
relation (empty) → uses
source_node_id (empty) → b4df1de7-ba12-4587-9b8a-89ab435a4ea6
target_node_id (empty) → 633eeea8-2026-4906-b512-1e239f3db152
create litestream-ruby → uses → Litestream
context (empty) → The Ruby gem wraps the Litestream Go executable.
relation (empty) → uses
source_node_id (empty) → 873bb381-a8b7-4e04-8a18-8dc7becb60a6
target_node_id (empty) → c8b1820d-3884-4b11-aedc-e33d07ed1896
create Litestream → uses → SQLite
context (empty) → Litestream streams the SQLite WAL to S3-compatible storage.
relation (empty) → uses
source_node_id (empty) → c8b1820d-3884-4b11-aedc-e33d07ed1896
target_node_id (empty) → a65d4872-7d76-4774-a7d5-e29e615de75a
create LiteFS → uses → SQLite
context (empty) → LiteFS builds multi-node replication on SQLite.
relation (empty) → uses
source_node_id (empty) → 7a2a4607-012c-4103-a937-862a8e7ac575
target_node_id (empty) → a65d4872-7d76-4774-a7d5-e29e615de75a
create sqlite3-ruby → uses → SQLite
context (empty) → sqlite3-ruby is the Ruby driver binding to SQLite.
relation (empty) → uses
source_node_id (empty) → b9a354eb-a956-42a4-8d54-853f596fd5e8
target_node_id (empty) → a65d4872-7d76-4774-a7d5-e29e615de75a
create Isolated Reader/Writer Connection Pools → related_to → Active Record
context (empty) → Built on Active Record's three-tier multi-database support with a custom resolver and a patched transaction method.
relation (empty) → related_to
source_node_id (empty) → 2530347b-3d21-496b-9bf6-8145caebb1c6
target_node_id (empty) → 633eeea8-2026-4906-b512-1e239f3db152
create Isolated Reader/Writer Connection Pools → related_to → Write-Ahead Logging (WAL) Mode
context (empty) → Only makes sense because WAL mode allows many concurrent reads alongside the single writer.
relation (empty) → related_to
source_node_id (empty) → 2530347b-3d21-496b-9bf6-8145caebb1c6
target_node_id (empty) → 1ee86e2d-95b9-499d-88fb-399006e36ec7
create Deferred Requests → related_to → Isolated Reader/Writer Connection Pools
context (empty) → Deferred Requests is the request-level switching mechanism that makes isolated pools transparent.
relation (empty) → related_to
source_node_id (empty) → 43898c09-d49c-413d-84fa-a4f51b6a9b99
target_node_id (empty) → 2530347b-3d21-496b-9bf6-8145caebb1c6
create Immediate Transactions → related_to → SQLite
context (empty) → Immediate Transactions is a SQLite transaction mode.
relation (empty) → related_to
source_node_id (empty) → cb92d7be-3aea-41d0-b6e4-94ab345d62ad
target_node_id (empty) → a65d4872-7d76-4774-a7d5-e29e615de75a
create SQLite Busy Handler → related_to → SQLite
context (empty) → busy_handler is a SQLite C API callback for write-lock contention.
relation (empty) → related_to
source_node_id (empty) → a6435583-9d23-4f45-83d2-69a76ee4dbc0
target_node_id (empty) → a65d4872-7d76-4774-a7d5-e29e615de75a
create SQLite Busy Handler → related_to → Global Interpreter Lock
context (empty) → The native C busy_timeout holds Ruby's GVL; the Ruby re-implementation releases it via Kernel#sleep.
relation (empty) → related_to
source_node_id (empty) → a6435583-9d23-4f45-83d2-69a76ee4dbc0
target_node_id (empty) → b2da1bdf-0293-4d62-8478-327f08bd9f7f
create Add enhanced-sqlite3-adapter for production SQLite on Rails → from_talk → How (and why) to run SQLite in production
context (empty) → Primary take-home recommendation of the talk.
relation (empty) → from_talk
source_node_id (empty) → 8bc84bcc-a79c-45b6-b0a3-7151f4f244a7
target_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
create Use Immediate Transactions for Rails → from_talk → How (and why) to run SQLite in production
context (empty) → Fix #1 in the talk's performance journey.
relation (empty) → from_talk
source_node_id (empty) → 77d54db3-4be5-46cc-b962-095eb8b65a72
target_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
create Replace SQLite's C busy_timeout with a GVL-releasing Ruby handler → from_talk → How (and why) to run SQLite in production
context (empty) → Fix #2 in the talk's performance journey.
relation (empty) → from_talk
source_node_id (empty) → 74b3ba63-3e44-4c75-a341-7f3fbbb83389
target_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
create Use a fair retry interval for SQLite writes → from_talk → How (and why) to run SQLite in production
context (empty) → Fix #3 in the talk's performance journey.
relation (empty) → from_talk
source_node_id (empty) → 14a22ce3-ac45-4350-bb97-a60d2593ec0a
target_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
create Run Litestream from day one → from_talk → How (and why) to run SQLite in production
context (empty) → Resilience recommendation grounded in Margheim's own story of deleting a production database.
relation (empty) → from_talk
source_node_id (empty) → 6c6440d6-51dc-46c6-9f29-42f6262a0524
target_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
create Start simple: single-node SQLite is usually enough to reach revenue → from_talk → How (and why) to run SQLite in production
context (empty) → Closing philosophical recommendation of the talk.
relation (empty) → from_talk
source_node_id (empty) → 0a506c57-b1ef-4d20-b77e-796f2a1ca064
target_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
create Use Immediate Transactions for Rails → about → Immediate Transactions
context (empty) → The takeaway is about configuring immediate-mode transactions.
relation (empty) → about
source_node_id (empty) → 77d54db3-4be5-46cc-b962-095eb8b65a72
target_node_id (empty) → cb92d7be-3aea-41d0-b6e4-94ab345d62ad
create Replace SQLite's C busy_timeout with a GVL-releasing Ruby handler → about → SQLite Busy Handler
context (empty) → The recommendation is about implementing the busy_handler in Ruby.
relation (empty) → about
source_node_id (empty) → 74b3ba63-3e44-4c75-a341-7f3fbbb83389
target_node_id (empty) → a6435583-9d23-4f45-83d2-69a76ee4dbc0
create Replace SQLite's C busy_timeout with a GVL-releasing Ruby handler → about → Global Interpreter Lock
context (empty) → The point of the fix is to release the GVL during DB waits.
relation (empty) → about
source_node_id (empty) → 74b3ba63-3e44-4c75-a341-7f3fbbb83389
target_node_id (empty) → b2da1bdf-0293-4d62-8478-327f08bd9f7f
create Use a fair retry interval for SQLite writes → about → SQLite Busy Handler
context (empty) → Fair 1 ms retry is a property of the Ruby busy_handler.
relation (empty) → about
source_node_id (empty) → 14a22ce3-ac45-4350-bb97-a60d2593ec0a
target_node_id (empty) → a6435583-9d23-4f45-83d2-69a76ee4dbc0
create Run Litestream from day one → about → Litestream
context (empty) → The takeaway recommends Litestream specifically.
relation (empty) → about
source_node_id (empty) → 6c6440d6-51dc-46c6-9f29-42f6262a0524
target_node_id (empty) → c8b1820d-3884-4b11-aedc-e33d07ed1896
create Add enhanced-sqlite3-adapter for production SQLite on Rails → about → enhanced-sqlite3-adapter
context (empty) → The takeaway recommends this specific gem.
relation (empty) → about
source_node_id (empty) → 8bc84bcc-a79c-45b6-b0a3-7151f4f244a7
target_node_id (empty) → b4df1de7-ba12-4587-9b8a-89ab435a4ea6
create Start simple: single-node SQLite is usually enough to reach revenue → about → Hatchbox
context (empty) → Mentions Hatchbox as the easy single-node deployment option.
relation (empty) → about
source_node_id (empty) → 0a506c57-b1ef-4d20-b77e-796f2a1ca064
target_node_id (empty) → ace2d786-db23-42f4-9d25-e0f4c3d4ae56
create Isn't embedding the database in your app process a security regression? → asked_at → How (and why) to run SQLite in production
context (empty) → Q&A after Margheim's talk.
relation (empty) → asked_at
source_node_id (empty) → 96089cf5-875d-4d34-8086-b43dc40e1155
target_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
create Is starting with SQLite a lock-in if I later need Postgres? → asked_at → How (and why) to run SQLite in production
context (empty) → Q&A after Margheim's talk.
relation (empty) → asked_at
source_node_id (empty) → 3c830a99-4bb4-4179-b54b-69eacc28fad6
target_node_id (empty) → 143b49fe-b577-4590-9ad3-a5f5ce3bc5b3
create Isn't embedding the database in your app process a security regression? → about → SQLite
context (empty) → Question concerns SQLite's embedded-database security model.
relation (empty) → about
source_node_id (empty) → 96089cf5-875d-4d34-8086-b43dc40e1155
target_node_id (empty) → a65d4872-7d76-4774-a7d5-e29e615de75a
create Is starting with SQLite a lock-in if I later need Postgres? → about → PostgreSQL
context (empty) → Question asks about migrating away from SQLite to Postgres.
relation (empty) → about
source_node_id (empty) → 3c830a99-4bb4-4179-b54b-69eacc28fad6
target_node_id (empty) → 46fc2697-69fc-436b-ac82-250ba4370273
create Is starting with SQLite a lock-in if I later need Postgres? → about → Active Record
context (empty) → Answer credits Active Record's database abstraction.
relation (empty) → about
source_node_id (empty) → 3c830a99-4bb4-4179-b54b-69eacc28fad6
target_node_id (empty) → 633eeea8-2026-4906-b512-1e239f3db152
create Mike Dalessio → works_on → SQLite
attrs (empty) → {"role" => "collaborator (2023)"}
context (empty) → Collaborated with Margheim on SQLite Bundler compile-flags support.
relation (empty) → works_on
source_node_id (empty) → 1210a4ce-4e2a-40c5-b876-bc4176484eaf
target_node_id (empty) → a65d4872-7d76-4774-a7d5-e29e615de75a

Read set

150 nodes

person Stephen Margheim search_nodes+get_node_edges talk From PostgreSQL to SQLite in Rails search_nodes talk Fantastic Databases and Where to Find Them search_nodes tool Sequel search_nodes tool SQLite search_nodes tool DBM / SDBM / GDBM search_nodes talk How (and why) to run SQLite in production search_nodes+get_node_edges tool activerecord-multi-tenant search_nodes concept Active Record search_nodes tool ROM search_nodes concept Vector Database search_nodes concept Database Indexes search_nodes tool CockroachDB search_nodes tool MessageDB search_nodes event Rails World search_nodes project Rails World Website search_nodes event wroclove.rb 2019 search_nodes event wroclove.rb 2018 search_nodes talk Towards the post framework future search_nodes talk How wroclove.rb impacts developers and companies search_nodes talk Mentoring the Rails World Website Lightning Talk search_nodes talk Building LLM powered applications in Ruby search_nodes talk Building Beautiful UIs with Ruby A Rails-Native Approach search_nodes tool Ruby on Rails search_nodes concept Cynefin Framework search_nodes project monolith framework search_nodes tool Ember.js search_nodes resource Woman on Rails search_nodes tool Rack search_nodes tool merb search_nodes takeaway Ruby as a Data Management Language search_nodes tool Discourse search_nodes tool PgHero search_nodes takeaway Per-Event Backups Via Reactors search_nodes tool PgBouncer search_nodes concept Direct Upload to Cloud search_nodes takeaway Automate Phantom Migration Rollback search_nodes concept Logux Proxy search_nodes takeaway Time Travel Superpower search_nodes takeaway Sign serverlessforruby.org petition search_nodes tool Cloudflare Workers search_nodes concept GitHub Self-Hosted Runner search_nodes resource Rocket Real-Time Benchmark search_nodes company Transloadit search_nodes tool langchainrb search_nodes project AnyCable search_nodes concept AI Agent search_nodes takeaway Port Python Libraries With ChatGPT search_nodes tool webpagetest.org search_nodes tool Codecov search_nodes takeaway Spoken Test Feedback with say + iTerm Triggers search_nodes tool Requestly search_nodes tool test-prof search_nodes tool CircleCI search_nodes tool parallel_tests search_nodes concept CI Matrix Strategy search_nodes person DHH search_nodes concept Majestic Monolith search_nodes resource The Rails and Hotwire Codex search_nodes question Have you heard of Stimulus? search_nodes tool Active Admin search_nodes takeaway Keep Project Setup Simple search_nodes question What is an enterprise Rails application? search_nodes concept tus protocol search_nodes question Per-tenant read models via database views search_nodes concept Append-Only Log search_nodes concept Unlogged Tables search_nodes tool log4j search_nodes concept Logux Time-Shift Ordering search_nodes takeaway Immutable Database Raises Mistake Cost search_nodes question How is the event-write kept consistent with external operations? search_nodes concept Current State search_nodes concept Event Store search_nodes concept Entity Caching and Snapshotting search_nodes takeaway Split Reads From Writes With Projections search_nodes concept MVCC Trade-offs in Postgres vs MySQL search_nodes concept Snapshotting search_nodes tool Action Cable search_nodes talk Cables! Cables! Cables! search_nodes resource Equestrian-Shows Platform Case Study search_nodes takeaway Start with Action Cable, switch when performance hurts search_nodes concept Connection Pool for Redis search_nodes project LiteCable search_nodes takeaway Action Cable Crowded-Channel Trade-off search_nodes talk Better WebPerformance with Rails search_nodes concept Static Page Caching via nginx search_nodes tool Puma search_nodes tool server-engine search_nodes concept HTTP/2 Server Push search_nodes tool Unicorn search_nodes tool Iodine search_nodes project raise_permanent_job search_nodes tool Plezi search_nodes takeaway Signed On-the-fly URLs search_nodes concept Function as a Service search_nodes resource serverlessforruby.org Petition search_nodes tool AWS Lambda search_nodes talk FaaS for Ruby Lightning Talk search_nodes takeaway Buy Faster Hardware search_nodes concept Zero-Disconnect Deployment search_nodes takeaway Gradual migration via steps search_nodes takeaway Dockerize Exotic Dependencies search_nodes tool Heroku search_nodes talk Kamal is not harder than your PaaS search_nodes takeaway Contribute to Arkency aggregates repository search_nodes concept Build Gems in Docker Isolation search_nodes tool actions/upload-artifact search_nodes talk Ruby Standard Library Hidden Gems Lightning Talk search_nodes person Akira Matsuda search_nodes tool IronRuby search_nodes tool Ruby search_nodes talk Rubyana Gems and the Ractorous Rubetta Stones! search_nodes talk Scientific Ruby Lightning Talk search_nodes person Emiliano Della Casa search_nodes tool YJIT search_nodes concept N+1 Queries search_nodes question Aren't query optimizations a better first step than caching? search_nodes talk LATERAL Joins Rails Performance Lightning Talk search_nodes takeaway Prefer LATERAL over CTE for filtered top-N per group search_nodes concept Flat Query Structure search_nodes concept Optimistic Locking search_nodes takeaway Read models must not depend on each other search_nodes concept destroy_all vs delete_all search_nodes takeaway Prefer SQL Window Functions over Ruby Aggregation search_nodes concept LATERAL join search_nodes event wroclove.rb 2024 search_nodes event wroclove.rb 2022 search_nodes event wroclove.rb 2023 search_nodes event wroclove.rb 2025 search_nodes event wroclove.rb 2026 search_nodes tool PostgreSQL search_nodes tool Citus search_nodes concept EXPLAIN / EXPLAIN ANALYZE search_nodes resource Postgres for Everything search_nodes concept Global Interpreter Lock search_nodes tool TruffleRuby search_nodes tool Celluloid search_nodes talk MVCC for Ruby developers search_nodes concept Ruby memory retention behavior search_nodes talk UringMachine — High Performance Concurrency for Ruby Using io_uring search_nodes concept ObjectSpace heap dumps search_nodes concept Russian Doll Caching search_nodes question Application-Level Back Pressure For Sidekiq search_nodes concept Cache Preheating search_nodes takeaway Prefer Small Sidekiq Jobs search_nodes takeaway Keep cache keys simple search_nodes concept Sidekiq Batches search_nodes question Scaling Sidekiq Elastically search_nodes talk Under The Hood And On The Surface Of Sidekiq search_nodes talk Sidekiq Batches Lightning Talk search_nodes

3 edges