← Extractions

Nightmare Neighbours: caveats of Rails-based multitenancy

Karol Szuster's wroclove.rb 2022 talk surveys three levels of data partitioning for multi-tenant Rails applications — row-level, schema-level, and database-level — with their pros, cons, and implementation gotchas. Covers default scopes, Postgres row-level security, session parameters, connection pooling caveats with PgBouncer, horizontal sharding in Rails 6.1, and concludes that row-level partitioning is the safest default and that the choice must be made early.

Model
claude-opus-4-7
Ingestion
8ce5dd5d
Input tokens
156,256
fresh
85,321
cached
60,837
cache write
10,098
Output tokens
14,170
Duration
190.1s
Roundtrips
5
Tool calls
18
Cost
$0.00
Nodes/edges extracted
32 / 59
Read set (nodes/edges)
93 / 2

Nodes (32)

update Karol Szuster person
attrs (empty) {"role" => "software engineer", "employer" => "Upside"}
description Conference speaker. Software engineer at Upside who spoke at wroclove.rb 2022 on Rails-based multitenancy, surveying row-level, schema-le...
short_description Conference speaker. Software engineer at Upside; Ruby conference speaker.
create Upside company
kind (empty) company
name (empty) Upside
slug (empty) upside
description (empty) Company where Karol Szuster worked as a software engineer when presenting 'Nightmare neighbours' at wroclove.rb 2022.
short_description (empty) Employer of Karol Szuster at the time of the 2022 talk.
update Nightmare neighbours caveats of Rails based mutlitenancy talk
description Talk at wroclove.rb 2022. Karol Szuster's wroclove.rb 2022 talk on the multi-tenant application pattern in Rails. Covers what multi-tenancy is ...
short_description Talk at wroclove.rb 2022. Talk at wroclove.rb 2022 on multi-tenant Rails data partitioning.
create Multi-Tenancy concept
kind (empty) concept
name (empty) Multi-Tenancy
slug (empty) multi-tenancy
attrs (empty) {"category" => "architecture"}
description (empty) Software development pattern where a single instance of an application serves multiple clients (tenants — typically c...
short_description (empty) Software pattern where a single application instance serves multiple clients with isolated data.
create Single-Tenant Architecture concept
kind (empty) concept
name (empty) Single-Tenant Architecture
slug (empty) single-tenant-architecture
attrs (empty) {"category" => "architecture"}
description (empty) Traditional deployment pattern where each customer has their own dedicated instance of the application. Contrasted wi...
short_description (empty) Running a separate application instance per client.
create Row-Level Partitioning concept
kind (empty) concept
name (empty) Row-Level Partitioning
slug (empty) row-level-partitioning
attrs (empty) {"category" => "pattern"}
description (empty) Multi-tenancy implementation where each record in the database has an assigned tenant_id and queries are always scope...
short_description (empty) Multi-tenant data isolation where every row carries a tenant_id.
create Schema-Level Partitioning concept
kind (empty) concept
name (empty) Schema-Level Partitioning
slug (empty) schema-level-partitioning
attrs (empty) {"category" => "pattern"}
description (empty) Multi-tenancy approach where each tenant lives in its own Postgres schema (a namespace of tables) and the application...
short_description (empty) Multi-tenancy using a separate database schema per tenant.
create Database-Level Partitioning concept
kind (empty) concept
name (empty) Database-Level Partitioning
slug (empty) database-level-partitioning
attrs (empty) {"category" => "pattern"}
description (empty) Most extreme partitioning level: each tenant gets a completely separate database. In MySQL a database and schema are ...
short_description (empty) Multi-tenancy using a separate database per tenant.
create Row-Level Security concept
kind (empty) concept
name (empty) Row-Level Security
slug (empty) row-level-security
attrs (empty) {"category" => "pattern"}
description (empty) Database management system mechanism (fully supported in Postgres) that restricts which rows can be returned, inserte...
short_description (empty) DBMS mechanism restricting row visibility per user or session.
create Transaction Pooling concept
kind (empty) concept
name (empty) Transaction Pooling
slug (empty) transaction-pooling
attrs (empty) {"category" => "pattern"}
description (empty) PgBouncer's most common and default pooling mode. Instead of giving each client a dedicated server connection, a conn...
short_description (empty) PgBouncer mode that assigns connections per transaction rather than per session.
create Horizontal Sharding concept
kind (empty) concept
name (empty) Horizontal Sharding
slug (empty) horizontal-sharding
attrs (empty) {"category" => "architecture"}
description (empty) Scaling technique where data is distributed across multiple databases that share the same schema. Natively supported ...
short_description (empty) Splitting data across multiple databases sharing the same schema.
create Noisy Neighbor Problem concept
kind (empty) concept
name (empty) Noisy Neighbor Problem
slug (empty) noisy-neighbor-problem
attrs (empty) {"category" => "pattern"}
description (empty) Failure mode in multi-tenant systems where tenants on the same shard/instance have correlated or heavy usage patterns...
short_description (empty) One tenant's usage pattern exhausting shared resources and degrading others.
create ActiveSupport CurrentAttributes concept
kind (empty) concept
name (empty) ActiveSupport CurrentAttributes
slug (empty) activesupport-currentattributes
attrs (empty) {"category" => "practice"}
description (empty) Native Rails mechanism (ActiveSupport::CurrentAttributes) providing a per-request Singleton. Commonly used in multi-t...
short_description (empty) Rails per-request Singleton for request-scoped state like current tenant.
create acts_as_tenant tool
kind (empty) tool
name (empty) acts_as_tenant
slug (empty) acts_as_tenant
attrs (empty) {"category" => "library"}
description (empty) Ruby gem that implements row-level multi-tenancy on top of Active Record. Injects default scopes so queries are autom...
short_description (empty) Rails gem implementing row-level multi-tenancy via default scopes.
create activerecord-multi-tenant tool
kind (empty) tool
name (empty) activerecord-multi-tenant
slug (empty) activerecord-multi-tenant
attrs (empty) {"category" => "library"}
description (empty) Alternative Ruby gem to acts_as_tenant that implements row-level multi-tenancy for Rails applications.
short_description (empty) Rails gem implementing row-level multi-tenancy.
create Apartment tool
kind (empty) tool
name (empty) Apartment
slug (empty) apartment
attrs (empty) {"category" => "library"}
description (empty) Historically the de-facto standard Ruby gem for multi-tenancy in Rails, providing schema-per-tenant and database-per-...
short_description (empty) Rails gem for schema- and database-per-tenant multi-tenancy.
create PgBouncer tool
kind (empty) tool
name (empty) PgBouncer
slug (empty) pgbouncer
attrs (empty) {"category" => "service"}
description (empty) External connection pooler for PostgreSQL, typically recommended once a Rails application is scaled across multiple r...
short_description (empty) Lightweight external connection pooler for PostgreSQL.
create RequestStore tool
kind (empty) tool
name (empty) RequestStore
slug (empty) requeststore
attrs (empty) {"category" => "library"}
description (empty) Older Ruby gem that provides a per-request global store backed by Thread.current, used in some multi-tenancy implemen...
short_description (empty) Older Ruby gem providing per-request thread-local storage.
create Unicorn tool
kind (empty) tool
name (empty) Unicorn
slug (empty) unicorn
attrs (empty) {"category" => "service"}
description (empty) Process-forking Rack web server. Because it runs one request per process and no threads, it masks thread-safety bugs ...
short_description (empty) Forking Rack-compatible Ruby web server.
create Shopify company
kind (empty) company
name (empty) Shopify
slug (empty) shopify
attrs (empty) {"industry" => "e-commerce"}
description (empty) E-commerce SaaS platform cited as one of the most recognizable multi-tenant Rails architectures, using a row-level pa...
short_description (empty) E-commerce platform; well-known large-scale Rails multi-tenant architecture.
create Salesforce company
kind (empty) company
name (empty) Salesforce
slug (empty) salesforce
attrs (empty) {"industry" => "SaaS / CRM"}
description (empty) Enterprise SaaS CRM cited alongside Shopify as a battle-tested multi-tenant architecture proving the viability of row...
short_description (empty) Enterprise CRM platform built on multi-tenant architecture.
update Elasticsearch tool
description Mentioned as a read-store optimized for search use cases when building denormalized view models. Search/analytics engine mentioned as an example of an application-level component whose indexes must be created separ...
update Sidekiq tool
description Ruby background job framework. Used in the final rewrite of the media platform to run processing and upload workers o... Background-job processor for Ruby/Rails. Mentioned as an application-level concern that must be designed for multi-te...
short_description Ruby background job processor backed by Redis. Background job processor for Ruby applications.
create Decide the tenancy approach early takeaway
kind (empty) takeaway
name (empty) Decide the tenancy approach early
slug (empty) decide-the-tenancy-approach-early
attrs (empty) {"type" => "recommendation"}
description (empty) Core recommendation of the talk: make an informed choice between row-level, schema-level and database-level partition...
short_description (empty) Commit to a partitioning strategy early to avoid costly rework.
create Default to row-level partitioning takeaway
kind (empty) takeaway
name (empty) Default to row-level partitioning
slug (empty) default-to-row-level-partitioning
attrs (empty) {"type" => "recommendation"}
description (empty) If you must pick a default multi-tenancy approach, row-level partitioning handles most scenarios: simple cross-tenant...
short_description (empty) Row-level partitioning handles most multi-tenancy cases; battle-tested at Shopify and Salesforce.
create Reset session parameters under Rails connection pooling takeaway
kind (empty) takeaway
name (empty) Reset session parameters under Rails connection pooling
slug (empty) reset-session-parameters-under-rails-connection-pooling
attrs (empty) {"type" => "warning"}
description (empty) When using Postgres row-level security with session parameters, always reset the session parameter after the request....
short_description (empty) Always reset RLS session parameters because Active Record reuses connections.
create Beware apartment-style database switching under threaded servers takeaway
kind (empty) takeaway
name (empty) Beware apartment-style database switching under threaded servers
slug (empty) beware-apartment-style-database-switching-under-threaded-servers
attrs (empty) {"type" => "warning"}
description (empty) The apartment gem's database-per-tenant switching re-establishes connections on a model class, which is not thread-sa...
short_description (empty) Re-establishing Active Record connections per tenant is not thread-safe.
create Don't reinvent multi-tenancy — use existing gems takeaway
kind (empty) takeaway
name (empty) Don't reinvent multi-tenancy — use existing gems
slug (empty) don-t-reinvent-multi-tenancy-use-existing-gems
attrs (empty) {"type" => "recommendation"}
description (empty) For row-level partitioning, gems such as acts_as_tenant and activerecord-multi-tenant already implement the default-s...
short_description (empty) Peer-reviewed gems like acts_as_tenant already implement row-level multi-tenancy correctly.
create Cross-tenant aggregation with row-level multi-tenancy question
kind (empty) question
name (empty) Cross-tenant aggregation with row-level multi-tenancy
slug (empty) cross-tenant-aggregation-with-row-level-multi-tenancy
attrs (empty) {"answer_summary" => "Both row-level and schema-level support it, but row-level is easier for aggregation — just drop...
description (empty) Audience question: which approach is best when staff members and admins sometimes need aggregated computations across...
short_description (empty) Which partitioning approach best supports staff/admin aggregated computations across tenants?
create Is the WHERE-clause leak risk real with acts_as_tenant? question
kind (empty) question
name (empty) Is the WHERE-clause leak risk real with acts_as_tenant?
slug (empty) is-the-where-clause-leak-risk-real-with-acts_as_tenant
attrs (empty) {"answer_summary" => "In practice acts_as_tenant raises on missing tenant, so Active Record users are safe. The risk ...
description (empty) Q&A remark: acts_as_tenant raises an error on any Active Record query against a tenant-scoped model when no tenant is...
short_description (empty) Does acts_as_tenant actually prevent the forgotten-WHERE-clause leak?
create Multi-column indexes scoped by tenant question
kind (empty) question
name (empty) Multi-column indexes scoped by tenant
slug (empty) multi-column-indexes-scoped-by-tenant
attrs (empty) {"answer_summary" => "Intuitively yes for uniqueness/lookup patterns scoped by tenant, but speaker wants to verify. P...
description (empty) Audience question: if everything is scoped by tenant and uniqueness is scoped by tenant, do all indexes need to be mu...
short_description (empty) Do row-level multi-tenant tables need indexes that include tenant_id?
create Per-tenant read models via database views question
kind (empty) question
name (empty) Per-tenant read models via database views
slug (empty) per-tenant-read-models-via-database-views
attrs (empty) {"answer_summary" => "Interesting alternative: create materialized/non-materialized views per tenant to separate data...
description (empty) Audience remark: at the database level you can create custom (possibly materialized) views or read models per tenant ...
short_description (empty) Using custom database views/read models per tenant.

Edges (59)

update Karol SzusterauthoredNightmare neighbours caveats of Rails based mutlitenancy
context (empty) Karol presented this talk at wroclove.rb 2022.
create Karol Szusterworks_atUpside
attrs (empty) {"role" => "software engineer"}
context (empty) Self-introduction: 'I'm a software engineer and I work at Upside'.
relation (empty) works_at
source_node_id (empty) 3e575eb3-5701-4c7c-9267-4b60b265529a
target_node_id (empty) c99a9df4-e84c-47ae-a936-91e092184ff0
update Nightmare neighbours caveats of Rails based mutlitenancypresented_atwroclove.rb 2022
context (empty) Talk delivered at wroclove.rb 2022.
create Nightmare neighbours caveats of Rails based mutlitenancyaboutMulti-Tenancy
context (empty) Central topic of the talk.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) f177a107-daa1-4fa3-97fc-23fb1d20f78a
create Nightmare neighbours caveats of Rails based mutlitenancyaboutSingle-Tenant Architecture
context (empty) Contrasted with multi-tenancy as the traditional approach.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) f44e2862-e742-4ceb-8421-15679961cb90
create Nightmare neighbours caveats of Rails based mutlitenancyaboutRow-Level Partitioning
context (empty) First of three partitioning levels covered.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 3ac966ff-8a71-407b-8cfc-556650dc93f1
create Nightmare neighbours caveats of Rails based mutlitenancyaboutSchema-Level Partitioning
context (empty) Second partitioning level covered.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 7e8542ee-9c6e-4ed3-8bfd-16105adc1f6e
create Nightmare neighbours caveats of Rails based mutlitenancyaboutDatabase-Level Partitioning
context (empty) Third partitioning level covered.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 8bfa4ded-ce8b-4f31-b79d-741a87c031b1
create Nightmare neighbours caveats of Rails based mutlitenancyaboutRow-Level Security
context (empty) Covered as a Postgres mechanism to harden row-level partitioning.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 8aaf1b7b-a823-43cf-a398-5fe40e469630
create Nightmare neighbours caveats of Rails based mutlitenancyaboutHorizontal Sharding
context (empty) Recommended as the native Rails 6.1 replacement for apartment-style database-per-tenant switching.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 8d7c314e-2d7a-452c-a347-2f287d957785
create Nightmare neighbours caveats of Rails based mutlitenancyaboutNoisy Neighbor Problem
context (empty) Raised as a risk when tenants share resources in sharded deployments.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 95af10b3-2482-43dc-9609-fd4032fcdc06
create Nightmare neighbours caveats of Rails based mutlitenancyaboutActiveSupport CurrentAttributes
context (empty) Shown as the native Rails mechanism to store the current tenant per request.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) a6776326-176d-47ee-8969-74d218f110f9
create Nightmare neighbours caveats of Rails based mutlitenancyaboutRequestStore
context (empty) Mentioned as an older gem implementing per-request storage for the current tenant.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 1e19dfe9-4084-4363-adf7-dc4d8c8cba50
create Nightmare neighbours caveats of Rails based mutlitenancyaboutacts_as_tenant
context (empty) Recommended gem for row-level multi-tenancy; discussed in Q&A about WHERE-clause risk.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) b147d51a-79f0-4128-8a89-29dcf7c4f6a3
create Nightmare neighbours caveats of Rails based mutlitenancyaboutactiverecord-multi-tenant
context (empty) Alternative gem for row-level multi-tenancy.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) d3160c31-e4e5-4bba-bb04-d6614c0745b3
create Nightmare neighbours caveats of Rails based mutlitenancyaboutApartment
context (empty) Discussed as the historical de-facto standard for schema- and database-per-tenant multi-tenancy and its thread-safety...
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 131e36e5-465f-4289-8044-35d13efc4a2a
create Nightmare neighbours caveats of Rails based mutlitenancyaboutPgBouncer
context (empty) Covered as the typical external connection pooler when scaling Rails.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 681c896d-87e3-4433-8a8c-c35df21ebaf4
create Nightmare neighbours caveats of Rails based mutlitenancyaboutTransaction Pooling
context (empty) Explained as PgBouncer's default mode and its interaction with session-scoped tenant state.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 73daa6ba-19a1-45d6-a4b2-9f55e5aff6e6
create Nightmare neighbours caveats of Rails based mutlitenancyaboutPostgreSQL
context (empty) Row-level security and session parameters discussed in the Postgres context.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 46fc2697-69fc-436b-ac82-250ba4370273
create Nightmare neighbours caveats of Rails based mutlitenancyaboutRuby on Rails
context (empty) Talk focuses on Rails-based multi-tenancy implementations.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 7aac705a-0987-49f2-b665-9d4e08a6acee
create Nightmare neighbours caveats of Rails based mutlitenancyaboutPuma
context (empty) Cited as the threaded server under which apartment's thread-unsafety surfaces.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 39300066-39d4-4bb3-b15b-0fb67a3d3867
create Nightmare neighbours caveats of Rails based mutlitenancyaboutUnicorn
context (empty) Cited as the fork server that masks apartment's thread-unsafety.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) eaf58490-8c64-41e8-9087-09fa87fa9a59
create Nightmare neighbours caveats of Rails based mutlitenancyaboutHeroku
context (empty) Cited as advising against schema-per-tenant due to backup tooling limitations.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) d3785e15-2805-4486-a633-6e785e4f8ae3
create Nightmare neighbours caveats of Rails based mutlitenancyaboutShopify
context (empty) Cited as a recognizable multi-tenant Rails architecture using row-level partitioning.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 934a1185-4a30-4c56-b417-b26f0ad00133
create Nightmare neighbours caveats of Rails based mutlitenancyaboutSalesforce
context (empty) Cited alongside Shopify as a battle-tested multi-tenant architecture.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) eb47eca2-c1f1-4709-b7bb-722728fd40b1
create Nightmare neighbours caveats of Rails based mutlitenancyaboutSidekiq
context (empty) Mentioned as an application-level concern requiring per-tenant handling.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 2365c22d-c83e-4553-b865-ec22d0b5b225
create Nightmare neighbours caveats of Rails based mutlitenancyaboutElasticsearch
context (empty) Mentioned as requiring separate indexes per tenant.
relation (empty) about
source_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
target_node_id (empty) 6d70c627-3da5-4e74-8424-e42de1e4ed59
create Row-Level PartitioningusesActiveSupport CurrentAttributes
context (empty) Row-level multi-tenancy stores current tenant via a per-request Singleton such as CurrentAttributes.
relation (empty) uses
source_node_id (empty) 3ac966ff-8a71-407b-8cfc-556650dc93f1
target_node_id (empty) a6776326-176d-47ee-8969-74d218f110f9
create Row-Level PartitioningusesRequestStore
context (empty) Older implementations use RequestStore for the per-request current tenant.
relation (empty) uses
source_node_id (empty) 3ac966ff-8a71-407b-8cfc-556650dc93f1
target_node_id (empty) 1e19dfe9-4084-4363-adf7-dc4d8c8cba50
create acts_as_tenantrelated_toRow-Level Partitioning
context (empty) Gem implements the row-level partitioning pattern.
relation (empty) related_to
source_node_id (empty) b147d51a-79f0-4128-8a89-29dcf7c4f6a3
target_node_id (empty) 3ac966ff-8a71-407b-8cfc-556650dc93f1
create activerecord-multi-tenantrelated_toRow-Level Partitioning
context (empty) Gem implements the row-level partitioning pattern.
relation (empty) related_to
source_node_id (empty) d3160c31-e4e5-4bba-bb04-d6614c0745b3
target_node_id (empty) 3ac966ff-8a71-407b-8cfc-556650dc93f1
create Apartmentrelated_toSchema-Level Partitioning
context (empty) Apartment was the de-facto implementation of schema-per-tenant.
relation (empty) related_to
source_node_id (empty) 131e36e5-465f-4289-8044-35d13efc4a2a
target_node_id (empty) 7e8542ee-9c6e-4ed3-8bfd-16105adc1f6e
create Apartmentrelated_toDatabase-Level Partitioning
context (empty) Apartment also supported database-per-tenant via connection re-establishment.
relation (empty) related_to
source_node_id (empty) 131e36e5-465f-4289-8044-35d13efc4a2a
target_node_id (empty) 8bfa4ded-ce8b-4f31-b79d-741a87c031b1
create Row-Level Securityrelated_toPostgreSQL
context (empty) Row-level security policies and session parameters demonstrated in Postgres.
relation (empty) related_to
source_node_id (empty) 8aaf1b7b-a823-43cf-a398-5fe40e469630
target_node_id (empty) 46fc2697-69fc-436b-ac82-250ba4370273
create Schema-Level Partitioningrelated_toPostgreSQL
context (empty) Uses Postgres search_path session parameter to switch schemas.
relation (empty) related_to
source_node_id (empty) 7e8542ee-9c6e-4ed3-8bfd-16105adc1f6e
target_node_id (empty) 46fc2697-69fc-436b-ac82-250ba4370273
create Transaction Poolingrelated_toPgBouncer
context (empty) Default PgBouncer pooling mode.
relation (empty) related_to
source_node_id (empty) 73daa6ba-19a1-45d6-a4b2-9f55e5aff6e6
target_node_id (empty) 681c896d-87e3-4433-8a8c-c35df21ebaf4
create Horizontal Shardingrelated_toRuby on Rails
context (empty) Natively supported in Rails since 6.1.
relation (empty) related_to
source_node_id (empty) 8d7c314e-2d7a-452c-a347-2f287d957785
target_node_id (empty) 7aac705a-0987-49f2-b665-9d4e08a6acee
create Horizontal Shardingrelated_toNoisy Neighbor Problem
context (empty) Shard balancing must account for noisy-neighbor effects.
relation (empty) related_to
source_node_id (empty) 8d7c314e-2d7a-452c-a347-2f287d957785
target_node_id (empty) 95af10b3-2482-43dc-9609-fd4032fcdc06
create Decide the tenancy approach earlyfrom_talkNightmare neighbours caveats of Rails based mutlitenancy
context (empty) Concluding recommendation of the talk.
relation (empty) from_talk
source_node_id (empty) af6368ec-cce5-4097-841e-85f62a04dfd1
target_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
create Default to row-level partitioningfrom_talkNightmare neighbours caveats of Rails based mutlitenancy
context (empty) Given as the default recommendation in the Q&A.
relation (empty) from_talk
source_node_id (empty) 1e6558e8-e9c3-4b8a-98bd-955c1792a01e
target_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
create Reset session parameters under Rails connection poolingfrom_talkNightmare neighbours caveats of Rails based mutlitenancy
context (empty) Warning raised while discussing row-level security.
relation (empty) from_talk
source_node_id (empty) 9b96e451-f9f4-414b-b93c-ce74631b5f09
target_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
create Beware apartment-style database switching under threaded serversfrom_talkNightmare neighbours caveats of Rails based mutlitenancy
context (empty) Warning raised while discussing database-per-tenant switching.
relation (empty) from_talk
source_node_id (empty) 4a826b8b-4ff0-4ed2-a0ca-a4662dd7c167
target_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
create Don't reinvent multi-tenancy — use existing gemsfrom_talkNightmare neighbours caveats of Rails based mutlitenancy
context (empty) Recommendation when discussing row-level implementations.
relation (empty) from_talk
source_node_id (empty) b1276ca5-31c2-4397-8420-1fff9f766d43
target_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
create Default to row-level partitioningaboutRow-Level Partitioning
context (empty) Recommends row-level as the default approach.
relation (empty) about
source_node_id (empty) 1e6558e8-e9c3-4b8a-98bd-955c1792a01e
target_node_id (empty) 3ac966ff-8a71-407b-8cfc-556650dc93f1
create Default to row-level partitioningaboutShopify
context (empty) Cites Shopify as validation.
relation (empty) about
source_node_id (empty) 1e6558e8-e9c3-4b8a-98bd-955c1792a01e
target_node_id (empty) 934a1185-4a30-4c56-b417-b26f0ad00133
create Default to row-level partitioningaboutSalesforce
context (empty) Cites Salesforce as validation.
relation (empty) about
source_node_id (empty) 1e6558e8-e9c3-4b8a-98bd-955c1792a01e
target_node_id (empty) eb47eca2-c1f1-4709-b7bb-722728fd40b1
create Reset session parameters under Rails connection poolingaboutRow-Level Security
context (empty) About the mechanism that requires the reset.
relation (empty) about
source_node_id (empty) 9b96e451-f9f4-414b-b93c-ce74631b5f09
target_node_id (empty) 8aaf1b7b-a823-43cf-a398-5fe40e469630
create Beware apartment-style database switching under threaded serversaboutApartment
context (empty) Specifically about the apartment gem's thread-safety issue.
relation (empty) about
source_node_id (empty) 4a826b8b-4ff0-4ed2-a0ca-a4662dd7c167
target_node_id (empty) 131e36e5-465f-4289-8044-35d13efc4a2a
create Don't reinvent multi-tenancy — use existing gemsaboutacts_as_tenant
context (empty) Recommends using acts_as_tenant instead of rolling your own.
relation (empty) about
source_node_id (empty) b1276ca5-31c2-4397-8420-1fff9f766d43
target_node_id (empty) b147d51a-79f0-4128-8a89-29dcf7c4f6a3
create Don't reinvent multi-tenancy — use existing gemsaboutactiverecord-multi-tenant
context (empty) Recommends using activerecord-multi-tenant instead of rolling your own.
relation (empty) about
source_node_id (empty) b1276ca5-31c2-4397-8420-1fff9f766d43
target_node_id (empty) d3160c31-e4e5-4bba-bb04-d6614c0745b3
create Cross-tenant aggregation with row-level multi-tenancyasked_atNightmare neighbours caveats of Rails based mutlitenancy
context (empty) Asked in Q&A of the talk.
relation (empty) asked_at
source_node_id (empty) 355fe365-d023-49c9-9835-713e63bbdacc
target_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
create Is the WHERE-clause leak risk real with acts_as_tenant?asked_atNightmare neighbours caveats of Rails based mutlitenancy
context (empty) Asked in Q&A of the talk.
relation (empty) asked_at
source_node_id (empty) d59ac18b-1f3d-4acc-878b-29ada57e38f2
target_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
create Multi-column indexes scoped by tenantasked_atNightmare neighbours caveats of Rails based mutlitenancy
context (empty) Asked in Q&A of the talk.
relation (empty) asked_at
source_node_id (empty) 598f2a41-cbd1-417c-ad5d-6158c8f991d6
target_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
create Per-tenant read models via database viewsasked_atNightmare neighbours caveats of Rails based mutlitenancy
context (empty) Audience remark in Q&A of the talk.
relation (empty) asked_at
source_node_id (empty) cbfd220b-01ee-43a5-a753-df7ad0205c13
target_node_id (empty) d22b5170-000d-41d7-aac0-bedd6c6fb285
create Cross-tenant aggregation with row-level multi-tenancyaboutRow-Level Partitioning
context (empty) Question compares partitioning approaches for cross-tenant aggregation.
relation (empty) about
source_node_id (empty) 355fe365-d023-49c9-9835-713e63bbdacc
target_node_id (empty) 3ac966ff-8a71-407b-8cfc-556650dc93f1
create Cross-tenant aggregation with row-level multi-tenancyaboutSchema-Level Partitioning
context (empty) Question compares partitioning approaches for cross-tenant aggregation.
relation (empty) about
source_node_id (empty) 355fe365-d023-49c9-9835-713e63bbdacc
target_node_id (empty) 7e8542ee-9c6e-4ed3-8bfd-16105adc1f6e
create Is the WHERE-clause leak risk real with acts_as_tenant?aboutacts_as_tenant
context (empty) Question is specifically about acts_as_tenant's default behaviour.
relation (empty) about
source_node_id (empty) d59ac18b-1f3d-4acc-878b-29ada57e38f2
target_node_id (empty) b147d51a-79f0-4128-8a89-29dcf7c4f6a3
create Multi-column indexes scoped by tenantaboutRow-Level Partitioning
context (empty) Performance follow-up to the row-level approach.
relation (empty) about
source_node_id (empty) 598f2a41-cbd1-417c-ad5d-6158c8f991d6
target_node_id (empty) 3ac966ff-8a71-407b-8cfc-556650dc93f1
create Per-tenant read models via database viewsaboutPostgreSQL
context (empty) Discusses PL/pgSQL views as a separation mechanism.
relation (empty) about
source_node_id (empty) cbfd220b-01ee-43a5-a753-df7ad0205c13
target_node_id (empty) 46fc2697-69fc-436b-ac82-250ba4370273

Read set

93 nodes

talk Nightmare neighbours caveats of Rails based mutlitenancy search_nodes+get_node_edges talk Multi-region data governance in Rails application search_nodes question What is an enterprise Rails application? search_nodes concept Mutator Layer search_nodes concept Rails Reload-Safe ES Configuration search_nodes concept Namespace-Based Folder Hierarchy search_nodes concept Fixtures over Factories search_nodes concept Read-Write Split search_nodes takeaway Prefer a simple top-to-bottom worker search_nodes tool Active Admin search_nodes concept Developer vs Programmer search_nodes talk Developer, Programmer, and AI search_nodes takeaway AI Will Not Replace Developer-Client Empathy search_nodes person Adam Okoń search_nodes takeaway Our Work Is About Business Value, Not Code search_nodes company SpaceX search_nodes talk Offline Sandwich Focus Workflow search_nodes concept Senior Developer Title search_nodes takeaway Sign serverlessforruby.org petition search_nodes takeaway Event Sourcing Mind Shift Trade-off search_nodes concept Distributed Monolith search_nodes resource Rocket Real-Time Benchmark search_nodes project Petri Nets Performance Prediction Gem search_nodes tool Sync Space VR search_nodes talk Adventures in durable execution search_nodes question How to do DDD remotely? search_nodes takeaway Replay-Based Debugging search_nodes concept Reservation Pattern search_nodes event wroclove.rb 2022 search_nodes event wroclove.rb 2023 search_nodes event wroclove.rb 2024 search_nodes event wroclove.rb 2019 search_nodes event wroclove.rb 2018 search_nodes event wroclove.rb 2026 search_nodes event wroclove.rb 2025 search_nodes talk Building LLM powered applications in Ruby search_nodes talk Ever shorter feedback loop search_nodes talk Data Management With Ruby search_nodes tool PostgreSQL search_nodes concept LATERAL join search_nodes talk LATERAL Joins Rails Performance Lightning Talk search_nodes concept Common Table Expression search_nodes takeaway Prefer LATERAL over CTE for filtered top-N per group search_nodes talk From PostgreSQL to SQLite in Rails search_nodes takeaway Time Travel Superpower search_nodes concept Active Record search_nodes project granite search_nodes tool JSON API Resources search_nodes tool aggregate_root search_nodes tool Devise search_nodes tool rails_event_store search_nodes tool acts_as_api search_nodes tool Avo search_nodes tool Sequel search_nodes concept Bouncing Select search_nodes takeaway Horizontal Scale Superpower search_nodes tool flag_shih_tzu search_nodes tool Uppy search_nodes company Transloadit search_nodes tool RealtimeBoard search_nodes concept tus protocol search_nodes concept Direct Upload to Cloud search_nodes tool webpagetest.org search_nodes concept Command UUID Deduplication search_nodes takeaway Don't reuse service objects across applications search_nodes project rails_event_store/ecommerce search_nodes takeaway Contribute to Arkency aggregates repository search_nodes tool GraphQL search_nodes tool Heroku search_nodes resource serverlessforruby.org Petition search_nodes tool AWS Lambda search_nodes talk Kamal is not harder than your PaaS search_nodes tool Docker search_nodes tool Discourse search_nodes takeaway Silver Bullet Anti-Pattern search_nodes concept Stalling For Time search_nodes concept Vector Clock search_nodes tool Tyrant search_nodes concept Unique Per-Site Email Leak Detection search_nodes tool Ruby on Rails search_nodes concept Cynefin Framework search_nodes tool Ember.js search_nodes project monolith framework search_nodes tool Rack search_nodes tool Ruby search_nodes talk Towards the post framework future search_nodes tool Puma search_nodes tool Iodine search_nodes takeaway Signed On-the-fly URLs search_nodes tool Plezi search_nodes tool nginx search_nodes concept HTTP/2 Server Push search_nodes tool Brotli search_nodes

2 edges