Integrations: PostgreSQL & Redis

Integrations: PostgreSQL & Redis

Most Go backends in 2026 rely on this “boring” but powerful trio: Go + Postgres + Redis.

PostgreSQL: pgx

Don’t use lib/pq. It is in maintenance mode. Use jackc/pgx. It is faster, safer, and supports more features (COPY, Listen/Notify).

Connection Pooling

Always use pgxpool, not a single connection.

import "github.com/jackc/pgx/v5/pgxpool"

func NewDB(ctx context.Context, connString string) (*pgxpool.Pool, error) {
    config, err := pgxpool.ParseConfig(connString)
    // Tuning
    config.MaxConns = 25
    config.MinConns = 5
    config.MaxConnLifetime = 1 * time.Hour

    return pgxpool.NewWithConfig(ctx, config)
}

Type-Safe SQL: sqlc

Don’t write ORM code (GORM) unless you love runtime crashes and slow queries. Use sqlc. You write SQL, it generates type-safe Go structs and interfaces. (See Chapter 59 “Code Generation” for details).


Redis: go-redis

Use github.com/redis/go-redis/v9.

Patterns

  1. Caching (Look-aside): go val, err := rdb.Get(ctx, key).Result() if err == redis.Nil { // Miss: Fetch DB, Set Redis val = fetchFromDB() rdb.Set(ctx, key, val, 10*time.Minute) } else if err != nil { return err // Real error } // Hit: use val

  2. Rate Limiting: Redis is atomic. INCR and EXPIRE are perfect for API limits.

  3. Queues: Redis Streams or simple Lists (LPUSH/BRPOP) make for excellent lightweight worker queues before you upgrade to Kafka or NATS.

Context Awareness

Both pgx and go-redis require context.Context in every method call. Always pass the context. This allows your database queries to automatically timeout if the user cancels the HTTP request, preventing zombie queries from eating your database CPU.

// Good
row := db.QueryRow(ctx, "SELECT ...")

// Bad (cancelling request won't stop query)
row := db.QueryRow(context.Background(), "SELECT ...")