SQLStreams

the messaging platform that is just Postgres

You last visited on 9999-99-99 Show what's new since then

Read message metadata

Edit this page
Consumer · Related pages
Posted: 2026-09-17 · Report this thread
brandon Site Admin brandon profile Posts: 96
MetaFromContext(ctx context.Context) (MessageMeta, bool)

Reads message metadata from the context supplied to a consumer handler.

Example

Use this consumer handler with Consume for the charge-cards group on the payments.requested stream. It uses the example payload.

func printPayment(ctx context.Context, payment *PaymentRequestedV1) error {
metadata, ok := sqlstreams.MetaFromContext(ctx)
if !ok {
return errors.New("message metadata is missing")
}
fmt.Println(metadata.Id, payment.OrderId, metadata.Attempts)
return nil
}

Parameters

Parameter Type Required Description
ctx context.Context Yes The consumer handler’s context, or a context derived from it.

Returns

Condition Return value
Context contains message metadata (metadata, true), where metadata is a MessageMeta value.
Context contains no message metadata (MessageMeta{}, false).

MessageMeta

Field Type JSON name Description
Id int64 message_id The message id.
RoutingKey string routing_key The produced routing key. Empty when none was supplied.
MessageKey string message_key The produced message key. Empty when none was supplied.
CompactionRank int64 compaction_rank The message’s rank under its key. Zero can mean an uncompacted message or a compacted message with rank zero. This field alone does not identify compaction.
CreatedAt time.Time created_at The message’s creation time.
ScheduledAt time.Time scheduled_at The scheduled time represented by this message. Zero for other messages.
Attempts int attempts Zero-based delivery attempt. Waiting for an ordered predecessor or a busy message key does not advance it. Failures, handler-requested delays, and expired exception leases advance it.
Delays int delays Consumer handler-requested later runs counted so far, separately from failed attempts.
Options *MessageOptions options Resolved options for this invocation, with group defaults and bounds applied. For example, Options.Timeout is the effective processing timeout.

Delivery attempt numbering

An ordered message that waited without running starts at attempt 0. Claiming a ready or deferred exception leaves its attempt number unchanged. A recorded failure or requested delay advances the next attempt; a delay also increments Delays, so it does not consume the failure budget. Delivery logs record the attempt that produced the outcome, before the counter advances.

An expired exception lease advances the attempt because the prior run’s outcome is unknown. Cursor-range recovery can replay attempt 0; this number is not an exact count of handler invocations across crashes. MaxRetries: 3 still permits attempt 0 and three retries, excluding requested delays.

This pre-v1 change requires a fresh database for testing. Existing exception rows use different counter semantics; do not mix consumers from both versions.