RailsConf 2025 was held in Philadelphia, Pennsylvania from July 8–10, 2025. The annual Ruby on Rails conference brought together Rails contributors, framework users, and the broader Ruby community to discuss the Rails 8 release cycle, performance improvements, and evolving best practices.
Rails 8 and UUID Primary Keys
Rails 8 shipped with improved UUID primary key support. Sessions at RailsConf 2025 walked through the full setup, starting with the migration change:
# Migration
create_table :orders, id: :uuid, default: -> { "gen_random_uuid()" } do |t|
t.string :status
t.timestamps
end
To use PostgreSQL 18’s native uuidv7() function:
create_table :orders, id: :uuid, default: -> { "uuidv7()" } do |t|
t.string :status
t.timestamps
end
This pushes UUID v7 generation entirely to the database layer — every insert, whether from Rails or raw SQL, receives a time-ordered UUID automatically.
Application-Layer Generation
For Rails apps on PostgreSQL 17 or earlier (before native uuidv7()), the recommended approach is application-layer generation using the ordered_uuid gem or a custom before_create callback:
class Order < ApplicationRecord
before_create :set_uuid
private
def set_uuid
self.id ||= SecureRandom.uuid # v4 fallback
# or: self.id ||= OrderedUuid.generate # v7 via gem
end
end
Talks also covered the Ruby standard library’s SecureRandom.uuid, which generates UUID v4. There is no native UUID v7 in the Ruby standard library as of Ruby 3.4 — the community relies on gems for v7.
Index Performance at Scale
A benchmarking talk compared insert throughput for three primary key strategies on a 50-million-row PostgreSQL table:
| Key type | Relative insert time | Index fragmentation |
|---|---|---|
| BIGSERIAL | 1× (baseline) | None |
| UUID v7 | 1.05× | Minimal |
| UUID v4 | 1.6× | Significant |
UUID v7’s millisecond timestamp prefix keeps inserts near the right side of the B-tree, closely approximating BIGSERIAL behaviour. UUID v4’s fully random values scatter inserts across the entire index, causing page splits.
Hotwire and UUID URLs
Sessions on Rails 8’s Hotwire improvements discussed UUID v7 in URL-based Turbo Frames. Because UUID v7 values sort chronologically, a list of resources fetched and sorted by primary key naturally appears in creation order — no ORDER BY created_at clause needed. This simplifies controllers and reduces query complexity in paginated Turbo Frame responses.
Related Ruby and Rails Resources
- Active Record Migrations guide — UUID column setup in Rails
- Active Record TableDefinition API
- strong_migrations gem — safe large-table migration helpers
- PostgreSQL 18 UUID functions — uuidv7() reference
- RFC 9562 — UUID v7 standard
Frequently asked questions
Was UUID v7 covered at RailsConf 2025?
Yes. RailsConf 2025 in Philadelphia included sessions on UUID primary keys in Rails 8, Active Record migration setup using PostgreSQL 18's uuidv7() function as a column default, and B-tree index performance benchmarks showing UUID v7 nearly matching BIGSERIAL insert throughput. The RailsConf website archives session recordings.
Do UUIDs hurt database index performance?
UUID v4 does — its randomness causes every insert to land at a different leaf page, leading to page splits and poor cache locality. UUID v7 embeds a millisecond timestamp so consecutive inserts cluster together, behaving like an auto-increment integer for B-tree purposes.
Does PostgreSQL 18 support UUID v7 natively?
Yes. PostgreSQL 18 ships a built-in uuidv7() function that generates RFC 9562-compliant UUID v7 values directly in SQL — no extensions or application-level generation required. The values store in the existing uuid column type unchanged.
Does Rails 8 support UUID v7 primary keys natively?
Rails 8 added built-in support for UUID primary keys via create_table :orders, id: :uuid in migrations. For UUID v7 specifically, set the PostgreSQL column default to uuidv7() (PostgreSQL 18) or use the ordered_uuid gem for application-layer generation. Rails' Active Record migration guide covers UUID column types in detail.
How do I migrate a Rails app from integer IDs to UUID primary keys?
The migration requires adding a UUID column, backfilling it with generated values, updating foreign keys, and swapping the primary key. Tools like the strong_migrations gem provide safety checks for large-table migrations. Rails' Active Record Migrations guide covers the column manipulation primitives.