Dead-simple UUIDv7 primary keys for modern Rails apps
Automatically use UUID v7 for all primary keys in Rails applications. Works with PostgreSQL, MySQL (mysql2 & trilogy), and SQLite — zero configuration required. Just add the gem and you're done!
- Assumes UUIDv7 primary keys by default for all models - just add the gem and you're done!
- Uses native
SecureRandom.uuid_v7(Ruby 3.3+) - Automatically sets
:uuidas default primary key type - Works perfectly on PostgreSQL, MySQL, and SQLite
- Zero database extensions needed
- Production-ready logging for debugging and monitoring
Add to your Gemfile:
gem "rails-uuid-pk", "~> 0.14"Then run:
bundle installThat's it! The gem automatically enables UUIDv7 primary keys for all your models.
By default, all models use UUIDv7 primary keys. After installation, every new model automatically gets a uuid primary key with UUIDv7 values:
rails g model User name:string email:string
# → creates id: :uuid with automatic uuidv7 generation# This works out of the box:
User.create!(name: "Alice") # ← id is automatically a proper UUIDv7For exceptional cases where you need integer primary keys (legacy tables, third-party integrations, etc.), you can explicitly opt out:
class LegacyModel < ApplicationRecord
use_integer_primary_key # Exception: this model uses integer PKs instead
end
# Migration must also specify :integer for the table
create_table :legacy_models, id: :integer do |t|
t.string :name
endMigration helpers automatically detect mixed primary key types and set appropriate foreign key types:
# Rails will automatically use the correct foreign key types
create_table :related_records do |t|
t.references :legacy_model, null: false # → integer foreign key (LegacyModel uses integers)
t.references :user, null: false # → UUID foreign key (User uses UUIDs by default)
endFor existing Rails applications with integer primary keys, use the included generator to automatically add use_integer_primary_key to models with integer primary keys:
rails generate rails_uuid_pk:add_opt_outsThis generator:
- Scans all ActiveRecord models in your application
- Checks the database schema for primary key types
- Adds
use_integer_primary_keyto models with integer primary keys - Is idempotent and safe to run multiple times
Options:
--dry-run: Show what would be changed without modifying files--verbose: Provide detailed output (default: true)
When installing Action Text or Active Storage, migrations automatically integrate with UUID primary keys - no changes needed.
Polymorphic associations work seamlessly with UUID primary keys. Foreign key types are automatically detected.
When using bulk insert operations (Model.import, insert_all, upsert_all), UUIDs are NOT automatically generated as callbacks are skipped:
# This will NOT generate UUIDs:
User.insert_all([{name: "Alice"}, {name: "Bob"}])
# Manual UUID assignment required:
users = [{name: "Alice", id: SecureRandom.uuid_v7}, {name: "Bob", id: SecureRandom.uuid_v7}]
User.insert_all(users)UUIDv7 provides excellent performance with monotonic ordering and reduced index fragmentation compared to UUIDv4.
- Generation: ~800,000 UUIDs/second with cryptographic security
- Storage: Native UUID (16B) on PostgreSQL, VARCHAR(36) on MySQL/SQLite
- Index Performance: Better locality than random UUIDs
For detailed performance analysis and optimization guides, see PERFORMANCE.md.
For architecture decisions and design rationale, see ARCHITECTURE.md.
See DEVELOPMENT.md for setup instructions, testing, and contribution guidelines.
For security considerations and vulnerability reporting, see SECURITY.md.
Bug reports and pull requests welcome on GitHub. See DEVELOPMENT.md for contribution guidelines.
MIT License - see MIT-LICENSE for details.