Sending messages
Send a message now, after a delay or at a set time, deduplicate repeats, keep related messages in order, and send in batches.
A send stores the message durably before it returns, so once you have a message id the message survives a crash on either side. Every option on this page works the same for push and pull queues.
Send a message
The payload can be any JSON value. A Uint8Array or ArrayBuffer travels as raw bytes instead.
import { queue } from '@gigadrive/sdk';
const invoices = queue<{ invoiceId: string }>('invoices');
const sent = await invoices.send({ invoiceId: 'inv_2041' });
console.log(sent.messageId, sent.deliverAt);Inside a deployed Function, queue() needs no configuration: it authenticates with the Function's own credential, described in OIDC federation. A REST call needs a token with the network:queues:send scope, which a deployed Function's credential already has. Sending to a name that does not exist creates a pull queue with default settings; pass autoCreate: false to the queue handle, or "autoCreate": false in REST, to get 404 queue_not_found instead.
Delay or schedule a message
delay holds a message back for a duration, and at delivers it at a point in time. Both reach up to one year ahead, and at wins when you pass both.
await invoices.send({ invoiceId: 'inv_2041' }, { delay: '15m' });
await invoices.send({ invoiceId: 'inv_2041' }, { at: new Date('2027-01-01T09:00:00Z') });A duration is a number of seconds or a string such as '30s', '15m', '12h' or '7d'. In REST, send delaySeconds or an ISO 8601 deliverAt.
A delayed message's retention period starts when it becomes due, so a message scheduled a month out is still kept for the full period after that. Scheduled messages appear under Scheduled on the queue's Messages tab in the console.
Cancel a scheduled message
Keep the message id from the send, then delete the message before it is processed:
const { messageId } = await invoices.send({ invoiceId: 'inv_2041' }, { delay: '7d' });
await invoices.cancel(messageId);The REST equivalent is DELETE /applications/{applicationId}/queues/{queue}/messages/{messageId}. A message that was already processed answers 404 message_not_found, and one that is being delivered or was dead-lettered answers 400 invalid_request: settle it from its consumer, or purge or retry dead letters from the queue's page.
Deduplicate repeated sends
Give a message a deduplication key, and any later send with the same key inside the queue's deduplication window is dropped. The duplicate send still succeeds: it returns the first message's id with deduplicated: true.
const first = await invoices.send({ invoiceId: 'inv_2041' }, { deduplicationKey: 'invoice:inv_2041' });
const again = await invoices.send({ invoiceId: 'inv_2041' }, { deduplicationKey: 'invoice:inv_2041' });
console.log(again.messageId === first.messageId, again.deduplicated); // true trueThe window is 24 hours by default and up to seven days, set per queue. Keys are up to 256 characters.
Keep related messages in order
Messages that share a groupKey are delivered one at a time, in the order you sent them. The next message in a group waits until the one before it is acknowledged, dead-lettered or expired, while other groups and ungrouped messages keep flowing.
const orders = queue<{ orderId: string; event: string }>('order-events');
await orders.send({ orderId: 'ord_77', event: 'paid' }, { groupKey: 'ord_77' });
await orders.send({ orderId: 'ord_77', event: 'shipped' }, { groupKey: 'ord_77' });Use one group per entity, such as an order or a customer. One group shared by every message makes the whole queue sequential.
Pin a message to a deployment
A push message goes to the environment's current deployment by default. Pass deploymentId to deliver it to a specific deployment instead, for example the one that sent it, so a payload format change in a new deployment cannot meet an old message:
await invoices.send({ invoiceId: 'inv_2041' }, { deploymentId: process.env.GIGADRIVE_DEPLOYMENT_ID });The deployment must belong to the queue's environment; another one is refused with 400 invalid_request. When the pinned deployment no longer serves the environment, the message goes to the current deployment, and the delivery carries x-gigadrive-queue-deployment-fallback: 1.
Send a batch
sendBatch sends up to 100 messages per request and splits larger arrays into requests of 100. Each message carries its own options, and the results come back in the same order:
const results = await invoices.sendBatch([
{ payload: { invoiceId: 'inv_2041' } },
{ payload: { invoiceId: 'inv_2042' }, delay: '1h' },
]);
for (const result of results) {
if (result.error) console.error(result.error.code);
}One refused message does not fail the others. sendBatch splits by count only, and a request whose message bodies add up to more than 4 MiB is refused whole with 400 invalid_request, so send large payloads in smaller batches. In REST, send messages: [...] instead of the single-message fields.
Headers
Add headers to forward metadata with each push delivery, such as a tenant id or a trace header. A message can carry up to 32 headers, each value up to 1,024 characters. These names are reserved and refused with 400 invalid_request:
- Transport headers:
host,content-length,content-type,connection,transfer-encoding,te,upgrade,keep-alive,authorization,cookie, and any name starting withproxy-. - Platform and proxy headers: any name starting with
x-gigadrive-,x-nebula-,x-substrate-,x-vercel-,x-forwarded-orx-bunny-, andx-real-ip,true-client-ipandforwarded.
Set the content type with contentType instead of a header. Schedules reserve two more names.
When a send is refused
| Status | code | Cause |
|---|---|---|
| 400 | invalid_request | A malformed option, a payload over 1 MiB, a batch over 4 MiB of bodies, or a reserved header |
| 402 | billing_cap_reached | The organization reached its spend cap |
| 404 | queue_not_found | The queue does not exist and auto-creation is off |
| 429 | quota_exceeded | Creating the queue would exceed the plan's queues per environment |
| 413 | payload_too_large | The request is larger than 6 MiB |
| 429 | backlog_full | The organization's queued messages reached the plan's storage allowance |
The SDK throws an ApiError carrying that code. Limits and pricing lists the allowances per plan.
