Skip to main content
GORM uses a dialector to abstract database-specific behavior. Install the driver package for your database, then pass the dialector to gorm.Open along with a *gorm.Config.
func Open(dialector gorm.Dialector, opts ...gorm.Option) (*gorm.DB, error)
The returned *gorm.DB is safe for concurrent use. Create it once at application startup and share it across your codebase — do not open a new connection per request.

Supported databases

Install the driver:
go get -u gorm.io/driver/mysql
Connect using a DSN string:
import (
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

// DSN format:
// user:password@tcp(host:port)/dbname?param=value
dsn := "user:password@tcp(127.0.0.1:3306)/mydb?charset=utf8mb4&parseTime=True&loc=Local"

db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
    panic("failed to connect to MySQL")
}
DSN parameters
ParameterRecommended valueDescription
charsetutf8mb4Full Unicode support including emoji
parseTimeTrueScan DATE and DATETIME into time.Time
locLocalUse the server’s local timezone for timestamp parsing
You can also connect using an existing *sql.DB:
import (
    "database/sql"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

sqlDB, err := sql.Open("mysql", dsn)
if err != nil {
    panic(err)
}

db, err := gorm.Open(mysql.New(mysql.Config{
    Conn: sqlDB,
}), &gorm.Config{})
Set parseTime=True in your DSN. Without it, GORM cannot scan MySQL DATETIME columns into time.Time fields, causing a runtime error.

Connection pool settings

gorm.Open wraps the standard library’s database/sql connection pool. You can access the underlying *sql.DB via db.DB() to configure pool behavior:
import "time"

sqlDB, err := db.DB()
if err != nil {
    panic(err)
}

// Maximum number of connections that can be open simultaneously
sqlDB.SetMaxOpenConns(25)

// Maximum number of idle connections kept in the pool
sqlDB.SetMaxIdleConns(10)

// Maximum time a connection can be reused before being closed
sqlDB.SetConnMaxLifetime(time.Hour)

// Maximum time a connection can sit idle before being closed
sqlDB.SetConnMaxIdleTime(30 * time.Minute)
Recommended starting values
SettingDevelopmentProduction
MaxOpenConns525–100
MaxIdleConns210–25
ConnMaxLifetime1h1h
ConnMaxIdleTime5m30m
Set MaxOpenConns to a value your database can handle. Most managed PostgreSQL instances default to 100 total connections — leave headroom for monitoring, migrations, and admin tools.

gorm.Config options

Pass a *gorm.Config as the second argument to gorm.Open to control GORM’s behavior at initialization time.
db, err := gorm.Open(dialector, &gorm.Config{
    // Skip the automatic ping on open (useful when the DB may not be available at startup)
    DisableAutomaticPing: true,

    // Cache prepared statements for reuse across queries
    PrepareStmt: true,

    // Skip wrapping single create/update/delete in a transaction (improves throughput)
    SkipDefaultTransaction: true,

    // Do not create foreign key constraints when running AutoMigrate
    DisableForeignKeyConstraintWhenMigrating: true,
})
Config fields relevant to connection
FieldTypeDescription
DisableAutomaticPingboolSkip the ping that verifies the connection on Open. Useful for lazy-connect patterns.
PrepareStmtboolExecute all queries as prepared statements and cache them. Reduces parse overhead for repeated queries.
PrepareStmtMaxSizeintMaximum number of cached prepared statements (LRU eviction). Defaults to math.MaxInt64.
PrepareStmtTTLtime.DurationTTL for cached prepared statements. Defaults to 1 hour.
SkipDefaultTransactionboolSkip the implicit transaction around single create/update/delete operations.
DisableForeignKeyConstraintWhenMigratingboolDo not emit CONSTRAINT clauses during AutoMigrate. Useful for databases with limited FK support.
NamingStrategyschema.NamerOverride the default table/column naming convention.
Loggerlogger.InterfaceSet a custom logger. Defaults to logger.Default which prints to stdout.
NowFuncfunc() time.TimeOverride the function used to generate current timestamps.
DryRunboolBuild SQL statements but do not execute them. Useful for inspecting generated queries.
CreateBatchSizeintDefault batch size when CreateInBatches is called.
TranslateErrorboolTranslate database-specific errors into GORM errors (e.g. ErrDuplicatedKey).

Verifying the connection

After opening a connection, ping the database to confirm it is reachable:
sqlDB, err := db.DB()
if err != nil {
    panic(err)
}

if err := sqlDB.Ping(); err != nil {
    panic("database unreachable: " + err.Error())
}
If you set DisableAutomaticPing: true, this is the correct place to check connectivity before your application starts serving traffic.

Using an existing sql.DB

If you manage the *sql.DB yourself (for example, to share a connection pool across multiple ORMs or to apply custom TLS configuration), pass it to the dialector directly:
import (
    "database/sql"
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

sqlDB, err := sql.Open("pgx", dsn)
if err != nil {
    panic(err)
}

db, err := gorm.Open(postgres.New(postgres.Config{
    Conn: sqlDB,
}), &gorm.Config{})
GORM will use the provided *sql.DB and will not create its own connection pool.

Next steps

Declaring models

Map Go structs to database tables with field tags, data types, and constraints.

Auto migrate

Automatically create and update your schema as your models evolve.

Configuration

Full reference for all gorm.Config fields including logging and naming strategies.

CRUD operations

Start creating, reading, updating, and deleting records.

Build docs developers (and LLMs) love