Why SQLStreams
Edit this pageSQLStreams gives Go applications transactional messaging, retained history, and independent consumer groups in Postgres. It fits applications that want business writes and messages to commit together and can allocate database capacity to both.
One commit for the business write and message
Suppose order 4127 needs a receipt. Writing the order to Postgres and then sending its message to a separate service creates a failure window:
| Failure | Result |
|---|---|
| Order commits; process stops before sending | order exists without its receipt request |
| Message is sent first; order rolls back | receipt request exists for an order that does not |
SQLStreams’s ProduceFunc runs the business write and message insert in one
transaction. Both commit or both roll back. The consumer cannot see the
message before that commit. Transactional Produce
shows the code and how to verify rollback.
The transaction covers database statements. Sending the actual email still happens outside it, and delivery can repeat after a crash or timeout. Side Effects & Retries explains the idempotency responsibility that remains with the application.
Several readers, retained history
On orders.created, email-receipts handles receipts while
fraud-screening scores orders. Each group has its own cursor and retry
state. Adding search-indexer later lets it build a projection from the
same retained messages without resetting either existing group.
| Need | SQLStreams mechanism | Cost or boundary |
|---|---|---|
| Independent handlers | consumer group per reader | each group adds reads and its own delivery state |
| Read historical messages | retained message log | storage and retention determine available history |
| Select matching messages | routing keys and group bindings | groups still advance through the stream’s log |
| Process each account in order | ordered delivery per message key | one slow message holds later messages on that key |
| Apply only current state | message-key compaction | intermediate values may be superseded; incompatible with ordered delivery |
Fan-out, Retention & Replay explains the shared log; Ordering & Concurrency explains per-key behavior. There is no shipped rewind or dead-message redrive verb. Those proposals are labeled separately in their guides.
What you operate
SQLStreams runs inside your Go processes against Postgres. Consumers run upkeep by default; a producer-only deployment also needs a manager. Database backups include messaging state, and SQL exposes cursors, pending deliveries, dead messages, and attempt history.
You still size connection pools, monitor storage and delivery failures, and keep maintenance running. A slow consumer group can prevent old partitions from expiring under the default retention safeguards. Database CPU, memory, I/O, and availability are shared with your application. Architecture describes that arrangement.
Evaluate the fit
Use the Quickstart to run a producer and consumer. Measure with your payloads, handlers, and replica counts before choosing capacity. This page makes no throughput claim; the roadmap tracks benchmark work and release scope.
If messaging must have independent database capacity or availability, include that requirement in your evaluation. The comparison pages cover Kafka, RabbitMQ and SQS, and job queues. The engine is an open-source Go library; its source and license are in the project repository.