Skip to main content

Messages

Messages are the data you push through Rinda queues. This guide covers all message operations.

Sending Messages​

Single Message​

const q = rinda.queue('QUEUE_ID');

const { messageId } = await q.send({
body: { orderId: '123', action: 'process' },
});

console.log('Message ID:', messageId);

Batch Send (up to 10)​

const result = await q.sendBatch([
{ body: { orderId: '1' } },
{ body: { orderId: '2' } },
{ body: { orderId: '3' } },
]);

console.log('Sent:', result.messageIds); // ['msg-id-1', 'msg-id-2', 'msg-id-3']

Delayed Messages​

await q.send({
body: { reminder: 'Follow up in 5 minutes' },
delaySeconds: 300, // Message becomes visible after 5 minutes
});

Message Attributes​

Attach custom metadata to messages:

await q.send({
body: { orderId: '123' },
attributes: {
source: 'checkout-service',
priority: 'high',
},
});

Receiving Messages​

Basic Receive​

const messages = await q.receive({
maxMessages: 10, // Receive up to 10 messages
waitTimeSeconds: 20, // Long-poll for up to 20 seconds (the default)
});

Long Polling​

Receiving long-polls by default: with no waitTimeSeconds, the call waits up to 20 seconds for a message to arrive and returns as soon as one does. This is what you want almost always — a consumer that short-polls spends most of its requests being told there is nothing, and each of those round trips costs latency for work it did not do.

// Both wait up to 20 seconds.
const messages = await q.receive();
const same = await q.receive({ waitTimeSeconds: 20 });

Twenty seconds is the maximum; anything higher is clamped to it.

Pass 0 when you want the opposite — an answer now, empty or not. That suits draining a queue in a loop, or a health check that must not block:

const messages = await q.receive({ waitTimeSeconds: 0 });
note

The AWS SDK compatibility endpoint keeps SQS's default of 0 rather than this one, because it emulates SQS rather than replacing it.

Processing and Acknowledging​

After processing a message, delete it to acknowledge receipt:

for (const msg of messages) {
try {
await processOrder(msg.body);
await msg.delete(); // Acknowledge
} catch (error) {
// Don't delete — message becomes visible again after timeout
console.error('Processing failed:', error);
}
}

Each received message includes useful metadata:

for (const msg of messages) {
console.log('ID:', msg.id);
console.log('Body:', msg.body);
console.log('Receive count:', msg.approximateReceiveCount);
console.log('Received at:', msg.receivedAt);
}

Deleting Messages​

By Message ID​

Delete a message by its ID, without needing the receipt handle from a receive:

await q.remove('MESSAGE_ID');

Large Messages​

Messages up to 190 KB travel on the queue itself. Larger bodies, up to 1 MB, are stored by Rinda and a reference travels on the queue instead.

The queue engine underneath caps a message at 256 KB counting its attributes, and a stored body is encrypted before it is written — which costs a little more than the body itself. 190 KB is the largest payload that fits inside both of those with room to spare, so the limit does not move underneath you.

This is fully transparent: send and receive look the same at any size, and ordering, deduplication, delivery counts, and dead-letter behaviour are unaffected.

const q = rinda.queue('QUEUE_ID');

// Send a payload larger than 190 KB — stored, with a reference on the queue
const largePayload = { data: 'x'.repeat(300 * 1024), type: 'report' };
const { messageId } = await q.send({ body: largePayload });

// Receive — the full body comes back, not a reference
const messages = await q.receive({ maxMessages: 1, waitTimeSeconds: 5 });
console.log(messages[0].body.type); // 'report'
console.log(messages[0].body.data.length); // 307200
await messages[0].delete();

Visibility Timeout​

When a message is received, it becomes invisible to other consumers for the visibility timeout period. If the message is not deleted within this time, it becomes visible again for reprocessing.

Error Handling​

import { RindaApiError } from '@rindahq/sdk';

try {
await q.send({ body: { orderId: '123' } });
} catch (error) {
if (error instanceof RindaApiError) {
console.error('API error:', error.message);
console.error('Status:', error.statusCode);
console.error('Request ID:', error.requestId);
}
}