Quick Example

This page walks you through a minimal working example.

Start Postgres with PGMQ

The quickest way to get a PGMQ-enabled Postgres running locally is with Docker:

# docker-compose.yml
services:
  postgres:
    image: ghcr.io/pgmq/pg18-pgmq:v1.10.0
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: pgmq
      POSTGRES_PASSWORD: pgmq
      POSTGRES_DB: pgmq
docker compose up -d
docker compose exec -T postgres psql -U pgmq -d pgmq -c "CREATE EXTENSION IF NOT EXISTS pgmq;"

Runnable Example with Scala CLI

Save the following as pgmq-example.scala and run it with scala-cli run pgmq-example.scala:

//> using dep io.github.matejcerny::pgmq4s-skunk:0.8.0
//> using dep io.github.matejcerny::pgmq4s-circe:0.8.0

import _root_.skunk.Session
import cats.effect.{IO, IOApp}
import io.circe.{Decoder, Encoder}
import natchez.Trace.Implicits.noop
import pgmq4s.*
import pgmq4s.circe.given
import pgmq4s.skunk.{SkunkPgmqAdmin, SkunkPgmqClient}
import scala.concurrent.duration.*

case class OrderCreated(orderId: Long, email: String) derives Encoder.AsObject, Decoder

object Main extends IOApp.Simple:
  val run: IO[Unit] =
    Session
      .pooled[IO](
        host = "localhost",
        port = 5432,
        user = "pgmq",
        database = "pgmq",
        password = Some("pgmq"),
        max = 10
      )
      .use: pool =>
        val client = SkunkPgmqClient[IO](pool)
        val admin  = SkunkPgmqAdmin[IO](pool)
        val queue  = QueueName("getting_started")

        for
          _        <- admin.createQueue(queue)
          msgId    <- client.send(queue, OrderCreated(1L, "dev@example.com"))
          messages <- client.read[OrderCreated](queue, VisibilityTimeout(30.seconds), 10.messages)
          _        <- IO.println(s"Received: ${messages.map(_.payload)}")
        yield ()

Core Concepts

pgmq4s provides two main traits:

  • PgmqClient[F] — message operations: send, read, pop, archive, delete, setVisibilityTimeout
  • PgmqAdmin[F] — queue management: createQueue, dropQueue, purgeQueue, metrics, listQueues

Each database backend provides implementations of both. Pick the backend that matches your stack.