Problem and scope

July 26, 2026 · View on GitHub

Research snapshot

This design was checked on 2026-07-26 against the official PGMQ repository, including its extension SQL, upgrade migrations, SQL API documentation, and integration tests.

The release used as the v1.0 reference is:

At that snapshot, the upstream client list contained maintained Rust and Python clients and several community clients, but no C++ client. pgmq-cpp fills that C++ integration gap. It remains an independent community project and has no affiliation with or endorsement from PGMQ.

Relevant upstream discussions also shaped the runtime boundary:

The operational problem

A C++ backend often needs to do something later: generate an asset, settle an order, send a callback, or run a retryable maintenance task. Keeping that work only in process memory loses it on restart. Adding another broker can be unjustified when the service already depends on PostgreSQL and PGMQ.

PGMQ supplies durable queue tables and public PostgreSQL functions. A production C++ consumer still has to solve several application-level problems:

  • safe libpq ownership and pooling;
  • parameter binding, JSON conversion, and typed result parsing;
  • explicit transaction boundaries;
  • bounded concurrency and backpressure;
  • visibility renewal for long work;
  • stale-claim detection;
  • retry timing, attempt limits, dead letters, and replay;
  • notification reconnects and polling fallback;
  • cooperative shutdown;
  • metrics and events;
  • real database, contention, disconnect, and process-crash testing.

Ad hoc SQL in every service duplicates this machinery and makes subtle reliability assumptions difficult to review.

Target users

pgmq-cpp is for C++20 services that:

  • already use PostgreSQL and can install PGMQ 1.12.0 as an extension;
  • want an in-process SDK and worker library, not another network service;
  • need regular at-least-once processing for long or external work;
  • or need atomic short jobs whose effects live in the same PostgreSQL transaction as the queue acknowledgement;
  • can make externally visible operations idempotent.

Existing choices

Call PGMQ SQL directly

This has no additional library dependency, but every application must maintain queue-name validation, result-shape parsing, transactions, connection ownership, retries, renewal, shutdown, and compatibility checks. It remains a reasonable choice for a very small synchronous producer.

Use an upstream or community client in another language

The upstream v1.12.0 documentation lists Rust and Python clients and links community clients for several other languages. Introducing another runtime or a sidecar solely to reach PGMQ adds deployment and failure boundaries and does not supply a native C++ handler runtime.

Use a dedicated broker

Kafka, RabbitMQ, NATS, SQS, and similar systems offer different scaling, retention, routing, and operational properties. They are better choices when those properties are required. pgmq-cpp deliberately optimizes for services whose queue state should remain in existing PostgreSQL.

Goals

The v1.0 project aims to provide:

  1. A complete C++20 wrapper for the selected PGMQ 1.12.0 public operations.
  2. Strong value types and one consistent exception model.
  3. Safe caller-owned transactions.
  4. A bounded multi-queue, multi-worker runtime.
  5. At-least-once regular processing with renewable visibility leases.
  6. Same-database transactional processing.
  7. Atomic dead-letter moves and replay tooling.
  8. Advisory LISTEN/NOTIFY wake-ups with authoritative polling fallback.
  9. Cooperative graceful shutdown and explicit timeout outcomes.
  10. Embeddable metrics and events without an HTTP server.
  11. Installable CMake targets, examples, CLI, tests, benchmark harnesses, and an auditable verification record.

Non-goals

The project does not attempt to:

  • implement a queue server or replace PGMQ;
  • clone Kafka, SQS, or a workflow engine;
  • provide a REST/gRPC service, web console, account system, or operator;
  • coordinate distributed transactions across external systems;
  • promise exactly-once external side effects;
  • forcibly terminate arbitrary C++ handlers;
  • make PostgreSQL NOTIFY a durable source of queue truth;
  • hide the operational cost of PostgreSQL locks, long transactions, or partition maintenance;
  • support every historical PGMQ result shape;
  • support PGMQ's SQL-only installation in v1.0.

Success criteria

“Implemented” and “proven” are separate claims. A release candidate requires:

  • the SDK and worker paths to contain real implementations;
  • clean configure/build/unit tests;
  • real PostgreSQL/PGMQ integration evidence for queue and transaction semantics;
  • concurrent, disconnect, lease, retry, dead-letter, shutdown, and deterministic crash evidence;
  • a successful external find_package consumer build;
  • runnable examples;
  • at least one benchmark run with raw environment metadata;
  • no core-path TODO or permanently skipped test;
  • documentation that retains the at-least-once and notification limitations.

The current evidence is recorded, without inference, in verification.md.