Skip to content

Database drivers

River makes use of drivers to insulate itself from third party packages, enabling future use of other database packages or new major versions. Currently, the two supported drivers are riverdatabasesql and riverpgxv5, with riverpgxv5 being the recommended option.


Drivers wrap third party packages

The River Client takes a generic TTx type parameter representing the type of the transaction in use for functions like InsertTx and InsertManyTx. TTx is derived from the client's driver, an agnostic interface to a third party package that provides protocol access to Postgres.

Most of the time, the only time code references a database driver is when it's initializing a River client. NewClient takes a driver as its first parameter, and the driver wraps a database pool:

import "github.com/riverqueue/river"
import "github.com/riverqueue/river/riverdriver/riverpgxv5"
...
dbPool, err := pgxpool.New(ctx, os.Getenv("DATABASE_URL"))
if err != nil {
panic(err)
}
defer dbPool.Close()
riverClient, err := river.NewClient(riverpgxv5.New(dbPool), &river.Config{
...
})
if err != nil {
panic(err)
}

See the InsertAndWork example for complete code.

Known limitations of riverdatabasesql

The riverdatabasesql driver is limited compared to Pgx's in that database/sql doesn't support a way to use Postgres' LISTEN feature, so workers don't immediately receive signals when jobs are inserted. Instead they enter "poll only mode", which polls periodically for newly available jobs.

In general, riverpgxv5 should be considered River's main supported driver. Pgx is performant, feature complete, production hardened, and well maintained, while Go's database/sql is broadly considered misdesigned, and too generic to provide access to important Postgres features.