PostgreSQL

PostgreSQL is supported by the core better_auth gem through the direct PostgreSQL adapter. Rails applications can use better_auth-rails with ActiveRecord on top of PostgreSQL.

Use the lambda form when configuring the direct adapter. Better Auth passes the final configuration into the lambda, so the adapter sees plugins, custom model names, custom field names, and advanced.database.generate_id.

Install Dependencies

Gemfile
gem "better_auth"
gem "pg"
Terminal
bundle install

Example Usage

config/auth.rb
require "better_auth"

auth = BetterAuth.auth(
  secret: ENV.fetch("BETTER_AUTH_SECRET"),
  base_url: ENV.fetch("BETTER_AUTH_URL"),
  database: ->(options) {
    BetterAuth::Adapters::Postgres.new(
      options,
      url: ENV.fetch("DATABASE_URL")
    )
  }
)

You may also pass an existing PG::Connection when your app owns connection management.

config/auth.rb
require "pg"

connection = PG.connect(ENV.fetch("DATABASE_URL"))

auth = BetterAuth.auth(
  secret: ENV.fetch("BETTER_AUTH_SECRET"),
  database: ->(options) {
    BetterAuth::Adapters::Postgres.new(
      options,
      connection: connection
    )
  }
)

Rails

Rails apps should normally use better_auth-rails and the ActiveRecord adapter.

Gemfile
gem "better_auth-rails"
gem "pg"
Terminal
bin/rails generate better_auth:install
bin/rails db:migrate

Rails uses ActiveRecord by default:

config/initializers/better_auth.rb
BetterAuth::Rails.configure do |config|
  config.database_adapter = :active_record
end

Schema generation & migration

The Ruby schema helpers generate PostgreSQL DDL from the same Better Auth configuration used at runtime, including plugins, custom model names, custom field names, and additional_fields.

PostgreSQL Schema Generation

PostgreSQL Schema Migration

✅ Supported✅ Supported
db/better_auth_schema.rb
config = BetterAuth::Configuration.new(
  secret: ENV.fetch("BETTER_AUTH_SECRET"),
  database: :memory,
  plugins: []
)

statements = BetterAuth::Schema::SQL.create_statements(
  config,
  dialect: :postgres
)

puts statements.join("\n\n")
db/migrate_better_auth.rb
require "better_auth"
require "pg"

config = BetterAuth::Configuration.new(
  secret: ENV.fetch("BETTER_AUTH_SECRET"),
  database: :memory,
  plugins: []
)

statements = BetterAuth::Schema::SQL.create_statements(
  config,
  dialect: :postgres
)

connection = PG.connect(ENV.fetch("DATABASE_URL"))
statements.each { |sql| connection.exec(sql) }

Joins (Experimental)

Enable experimental joins when you want Better Auth to ask the database adapter to fetch related records in one adapter call.

config/auth.rb
auth = BetterAuth.auth(
  secret: ENV.fetch("BETTER_AUTH_SECRET"),
  experimental: { joins: true },
  database: ->(options) {
    BetterAuth::Adapters::Postgres.new(
      options,
      url: ENV.fetch("DATABASE_URL")
    )
  }
)

The PostgreSQL adapter supports native joins for core relationships and for plugin schema relationships declared with references. Rails uses generated ActiveRecord associations for the same schema-driven relationships.

Schema

The Ruby schema maps Better Auth logical fields to PostgreSQL physical columns.

Better Auth fieldPostgreSQL column
emailVerifiedemail_verified
userIduser_id
createdAtcreated_at
expiresAtexpires_at

JSON-like fields use jsonb, date fields use timestamptz, and ids are generated as hex strings by default. Set advanced: { database: { generate_id: "uuid" } } to generate UUID strings instead.

Additional Information

  • The direct adapter supports the shared Better Auth CRUD contract, where operators, sorting, pagination, counts, transactions, and native joins.
  • If you use a non-default PostgreSQL schema, configure the connection search path before the adapter runs and make sure the schema already exists.
  • Rails apps should prefer Rails migrations generated by better_auth-rails; direct SQL generation is intended for non-Rails apps or custom migration workflows.

On this page