liveBook · Manning

Queue

As explained in Just Use Postgres!

FIFO ordering delivers items in the same order in which they were added.

A queue delivers messages in FIFO order: consumers receive older messages before newer ones. A PostgreSQL implementation stores each message with an insertion timestamp and lifecycle status. section 11.2

A practical message queue separates producer, consumer, and completion work:

  • Enqueue stores the original JSON message and automatically assigns its ID, timestamp, and new status. section 11.2
  • Dequeue selects new messages by created_at, locks them with SKIP LOCKED, and changes their status to processing. section 11.2
  • Completion either marks selected messages completed or deletes them; stalled processing messages can be reset after an application-defined threshold. section 11.2

Transactional consumption

A consumer can begin a transaction, call mq.dequeue(1), execute business logic, mark the message completed, and commit. While processing, the message remains invisible to other consumers. section 11.2

Listing 11.1 Creating a queue as a regular Postgres table
CREATE SCHEMA mq;

CREATE TYPE mq.status AS ENUM ('new', 'processing', 'completed');

CREATE TABLE mq.queue (
    id BIGSERIAL PRIMARY KEY,
    message JSON NOT NULL,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    status mq.status NOT NULL DEFAULT 'new'
);

Inspect the table, JSON payload, timestamp, and new/processing/completed status model. section 11.2

Listing 11.3 Creating a function for retrieving messages from the queue
CREATE OR REPLACE FUNCTION mq.dequeue(messages_cnt INT)
RETURNS TABLE (msg_id BIGINT, message JSON, enqueued_at TIMESTAMPTZ) AS $$
BEGIN
  RETURN QUERY
  WITH new_messages AS (
    SELECT id FROM mq.queue
    WHERE status = 'new' ORDER BY created_at
    FOR UPDATE SKIP LOCKED
    LIMIT messages_cnt
  )
  UPDATE mq.queue q
  SET status = 'processing'
  FROM new_messages WHERE q.id = new_messages.id
  RETURNING q.id, q.message,
    date_trunc('seconds',q.created_at) AS created_at;
END;
$$ LANGUAGE plpgsql;

Inspect the dequeue function that combines FIFO selection, row locking, and status transition. section 11.2

How Just Use Postgres! covers it

How deep it goes
Explains table design, enqueue/dequeue functions, locking, transactions, completion, and stalled-message recovery.
Examples
Uses PostgreSQL schema and PL/pgSQL listings for enqueue, dequeue, transactional consumption, and completion.
What it assumes
Assumes PostgreSQL, SQL transactions, JSON values, and PL/pgSQL function definitions.
What you can do after
Operate/configure a PostgreSQL-backed queue with concurrent consumers and explicit message completion.
How it connects
Connects FIFO ordering with JSON, timestamps, transactions, row locking, and message status management.

Also explained in

Compare how 23 books explain queue →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Just Use Postgres!. The section links point to the parts of the book it draws on.