Shopify2023-10-18Tutorial
How to Introduce Composite Primary Keys in Rails
Summary
Shopify addressed inefficient data access in its multi-tenant Rails application, where auto-incrementing primary keys interleaved records from many shops even though queries usually targeted one shop. InnoDB stores rows in B+ trees and loads pages into a buffer pool, so the team changed orders and other suitable tables to composite primary keys such as [shop_id, order_id] while keeping an auto-incrementing id secondary key and configuring Active Record to use id. Supporting Ghostferry, migration tooling, and data extraction systems also had to accommodate the schema change, with unique secondary constraints avoided in some cases because LHM migrations could deadlock. On the most queried table, common queries improved 5–6x, median buffer pool reads fell from 1.8 to 1.2, and elapsed database time dropped roughly one hour per day per shard, while inserts became about 10x slower.
Context
Shopify’s multi-tenant database stored records from many shops interleaved by auto-incrementing primary keys, while most queries accessed one shop at a time. This caused inefficient page loading and made database performance and capacity important concerns.
Approach / What changed
Use composite primary keys such as [shop_id, order_id] to cluster records by shop, retain an auto-incrementing id as a secondary key, and configure Active Record to treat id as the primary key. Adapt migration, live data migration, and data extraction infrastructure to support the changed schema.
Takeaways
Composite clustering produced 5–6x faster common queries on the most queried table and reduced median MySQL buffer pool reads from 1.8 to 1.2 per query.
Rails application assumptions about integer primary keys could be preserved by retaining id as an auto-incrementing secondary key and setting self.primary_key = :id.
Composite primary keys improved read performance but made inserts roughly 10x slower because more database pages needed to be read and flushed.
Source and freshness
- Source
- shopify.engineering
- Published
- Added to Yomu
- Last updated
Summaries are generated from the original by a language model. Check the original before relying on it.
Keep reading
Related reading
The Good Stuff
Paid picks we use ourselves. Links carry a referral code — a subscription through one earns us a commission at no extra cost to you.
The best engineering reads, once a week
One useful email. Unsubscribe anytime.