← 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 MargheimauthoredHow (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 productionpresented_atwroclove.rb 2024
context (empty) The talk was presented at wroclove.rb 2024.
create Stephen Margheimworks_attest.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 TursousesSQLite
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 Margheimworks_onenhanced-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 Margheimworks_onlitestream-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 Margheimworks_onsqlite3-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 Margheimworks_onRuby 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 MargheimrecommendsSQLite
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 MargheimrecommendsLitestream
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 Margheimrecommendsenhanced-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 productionaboutSQLite
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 productionaboutRuby 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 productionaboutenhanced-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 productionaboutLitestream
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 productionaboutImmediate 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 productionaboutSQLite 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 productionaboutWrite-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 productionaboutIsolated 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 productionaboutDeferred 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 productionaboutBranch-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 productionaboutGlobal 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 productionaboutActive 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 productionaboutPostgreSQL
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 productionaboutN+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 productionaboutSolid 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 productionaboutSolid 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 productionaboutSolid 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 productionaboutTurso
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 productionaboutDHH
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 productionaboutHatchbox
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 productionaboutLiteFS
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 Johnsonworks_onLitestream
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 Johnsonworks_onLiteFS
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 Johnsonworks_atFly.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-adapterusesSQLite
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-adapterusessqlite3-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-adapterusesActive 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-rubyusesLitestream
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 LitestreamusesSQLite
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 LiteFSusesSQLite
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-rubyusesSQLite
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 Poolsrelated_toActive 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 Poolsrelated_toWrite-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 Requestsrelated_toIsolated 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 Transactionsrelated_toSQLite
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 Handlerrelated_toSQLite
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 Handlerrelated_toGlobal 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 Railsfrom_talkHow (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 Railsfrom_talkHow (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 handlerfrom_talkHow (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 writesfrom_talkHow (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 onefrom_talkHow (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 revenuefrom_talkHow (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 RailsaboutImmediate 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 handleraboutSQLite 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 handleraboutGlobal 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 writesaboutSQLite 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 oneaboutLitestream
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 Railsaboutenhanced-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 revenueaboutHatchbox
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_atHow (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_atHow (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?aboutSQLite
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?aboutPostgreSQL
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?aboutActive 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 Dalessioworks_onSQLite
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