Skip to main content

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​

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

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 CaseQueue Type
Event processing where order mattersFIFO
Financial transactionsFIFO
State machine updatesFIFO
Log ingestionStandard
Email notificationsStandard
Thumbnail generationStandard

Limitations​

  • FIFO queues have lower throughput than standard queues (300 messages/second per group)
  • Both groupId and deduplicationId are required for every message
  • Deduplication window is 5 minutes