FIFO Queues
FIFO (First-In-First-Out) queues guarantee that messages are processed in the exact order they are sent, with exactly-once delivery semantics.
Creating a FIFO Queue
- Node.js SDK
- REST API
const queue = await rinda.queues.create({
name: 'payment-events',
region: 'us-east-1',
isFifo: true,
dlqEnabled: true,
maxReceiveCount: 3,
});
console.log('FIFO queue:', queue.id, queue.isFifo); // true
curl -X POST https://api.rinda.dev/v1/queues \
-H "Authorization: Bearer $RINDA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "payment-events",
"region": "us-east-1",
"isFifo": true,
"dlqEnabled": true,
"maxReceiveCount": 3
}'
Message Groups
Message groups allow parallel processing while maintaining order within each group. Use groupId to assign messages to a group:
const q = rinda.queue(queue.id, { isFifo: true });
// Messages for customer-123 are processed in order
await q.send({
body: { action: 'charge', amount: 99.99 },
groupId: 'customer-123',
deduplicationId: 'charge-001',
});
await q.send({
body: { action: 'refund', amount: 99.99 },
groupId: 'customer-123',
deduplicationId: 'refund-001',
});
// Different group — processed independently and in parallel
await q.send({
body: { action: 'charge', amount: 49.99 },
groupId: 'customer-456',
deduplicationId: 'charge-002',
});
Batch Send
Send multiple FIFO messages at once. Every message must include groupId and deduplicationId:
const q = rinda.queue(queue.id, { isFifo: true });
const result = await q.sendBatch([
{ body: { seq: 1 }, groupId: 'batch-group', deduplicationId: 'dedup-1' },
{ body: { seq: 2 }, groupId: 'batch-group', deduplicationId: 'dedup-2' },
{ body: { seq: 3 }, groupId: 'batch-group', deduplicationId: 'dedup-3' },
]);
console.log('Sent:', result.messageIds.length, 'messages');
Receiving FIFO Messages
Receive and process messages in order:
const q = rinda.queue(queue.id);
const messages = await q.receive({ maxMessages: 5 });
for (const msg of messages) {
console.log('Body:', msg.body);
await msg.delete();
}
Deduplication
The deduplicationId prevents duplicate messages within a 5-minute window:
await q.send({
body: { orderId: '123' },
groupId: 'orders',
deduplicationId: 'order-123-created',
});
// This is a no-op — same deduplicationId within the dedup window
await q.send({
body: { orderId: '123' },
groupId: 'orders',
deduplicationId: 'order-123-created',
});
SDK Validation
When you create a queue handle with { isFifo: true }, the SDK validates that groupId and deduplicationId are provided before sending:
import { RindaValidationError } from '@rindahq/sdk';
const q = rinda.queue(queue.id, { isFifo: true });
try {
// Throws — missing groupId and deduplicationId
await q.send({ body: { test: true } });
} catch (err) {
if (err instanceof RindaValidationError) {
console.error(err.message); // 'FIFO queues require "groupId"...'
}
}
Batch validation reports the specific index:
try {
await q.sendBatch([
{ body: { a: 1 }, groupId: 'g1', deduplicationId: 'd1' },
{ body: { b: 2 } }, // Missing groupId at index 1
]);
} catch (err) {
console.error(err.message); // '...Missing on message at index 1.'
}
FIFO Queue Stats
const q = rinda.queue(queue.id);
const stats = await q.stats();
console.log('Messages:', stats.approximateMessageCount);
When to Use FIFO
| Use Case | Queue Type |
|---|---|
| Event processing where order matters | FIFO |
| Financial transactions | FIFO |
| State machine updates | FIFO |
| Log ingestion | Standard |
| Email notifications | Standard |
| Thumbnail generation | Standard |
Limitations
- FIFO queues have lower throughput than standard queues (300 messages/second per group)
- Both
groupIdanddeduplicationIdare required for every message - Deduplication window is 5 minutes