skip to content

What does an Amazon SNS FIFO topic give you that a standard topic does not, and what does it require from publishers and subscribers?

level: middleimportance: should knowfreq 40%

answer

  1. ordering only within a message group
  2. group id is also the parallelism key
  3. deduplication is publish-side, not consumer-side
  4. FIFO topic wants FIFO queues downstream
  5. one poison message blocks its group

basics

~20 s

A FIFO topic preserves publish order within a message group and deduplicates repeated publishes inside a short window. Publishers must supply a message group id and a deduplication id (or enable content-based deduplication), and the ordering only survives if the subscriber is a FIFO SQS queue.

solid answer

~50 s

Standard SNS topics are high-throughput, at-least-once and unordered; a FIFO topic trades throughput for strict ordering per message group plus deduplication. Every `Publish` must carry a `MessageGroupId` — order is preserved only within a group, and independent groups are what let the topic parallelise — and either a `MessageDeduplicationId` or content-based deduplication enabled on the topic, which makes a repeat within the deduplication window a no-op. The topic name must end in `.fifo` and the `FifoTopic` attribute is fixed at creation. Crucially, ordering is only end to end if the fanout target preserves it: subscribe FIFO SQS queues, and give each of them a consumer that processes one group at a time. A standard queue subscribed to a FIFO topic still gets the fanout, but not the ordering. Take FIFO only when the business truly requires ordering, because the throughput ceiling is far lower.

code

bash · 5 lines
bash
aws sns publish \
  --topic-arn arn:aws:sns:eu-west-1:111122223333:ledger.fifo \
  --message '{"entryId":"E-9001","amountCents":2500}' \
  --message-group-id account-4711 \
  --message-deduplication-id E-9001-v1

go deeper

for a junior

Know that a FIFO topic preserves order and removes duplicate publishes while a standard topic does neither, and that the topic name ends in .fifo. Say plainly that ordering applies within a message group.

for a middle

Explain the mechanics: MessageGroupId as both the ordering and parallelism key, deduplication id versus content-based deduplication and its window, the immutable FifoTopic attribute, and why FIFO queues are needed downstream to keep the ordering.

for a senior

Show the operational consequences — head-of-line blocking inside a group, dead-letter handling under FIFO, consumer concurrency scaling across groups — and be willing to argue that a sequence number on a standard topic often solves the real requirement more cheaply.

for a principal

Own the decision of where ordering is enforced across a platform: in the transport, in the aggregate's own versioning, or not at all. Weigh the throughput ceiling, the migration cost of an immutable topic type, and the failure isolation you lose when one entity's stuck message stalls its group.

## What the two topic types actually promise A **standard** SNS topic is optimised for throughput: very high publish rates, at-least-once delivery, and no ordering guarantee — two subscribers may legitimately observe the same two events in different orders. A **FIFO** topic adds two guarantees at a substantial throughput cost: 1. **Ordering within a message group.** Messages published with the same `MessageGroupId` are delivered to a subscriber in the order they were accepted. Different groups are independent and may be interleaved arbitrarily — that independence is exactly what allows any parallelism at all. 2. **Deduplication.** Within a deduplication interval (five minutes, as of 2025), a second publish with the same deduplication identity is accepted and acknowledged but not delivered. This protects against a retrying publisher creating a duplicate, not against a consumer processing the same message twice. ## What publishers must do - The topic is created with the `FifoTopic` attribute set to true and a name ending in `.fifo`. This is **immutable** — you cannot convert a standard topic to FIFO or back; you create a new topic and migrate. - Every `Publish` supplies a `MessageGroupId`. Choosing it is the real design decision: it is your ordering key and your parallelism key at the same time. `orderId` or `customerId` is usually right; a constant value serialises the entire topic and destroys throughput; something too fine-grained silently gives up the ordering you wanted. - Every `Publish` supplies a `MessageDeduplicationId`, unless the topic has `ContentBasedDeduplication` enabled, in which case SNS derives one from the message body. Content-based deduplication is a trap for legitimately identical payloads — two genuine "heartbeat ok" events a minute apart are the same body, and the second one disappears. ## What subscribers must do FIFO topics exist to fan out into queues. Ordering survives to the consumer only when the subscribed queue is an **SQS FIFO queue**, which carries the group ordering through to delivery: SQS will not hand out a second message from a group while an earlier one from that group is still in flight. Subscribe a standard queue instead and you keep the fanout and the publish-side deduplication, but the queue reorders freely — a perfectly reasonable choice for a subscriber that does not care about sequence and wants the higher throughput. Two consequences follow that candidates often miss: - **A stuck message blocks its group.** With FIFO, a poison message in group `order-42` halts that group until it is deleted or dead-lettered. That is the price of ordering, and it is why a dead-letter queue and a sensible `maxReceiveCount` matter more, not less, under FIFO. - **Consumer concurrency must respect groups.** Ordering is only preserved if a single consumer handles a group at a time, which SQS FIFO enforces by not releasing the group. Your worker pool scales across groups, never within one. ## The throughput conversation FIFO topics and FIFO queues have far lower throughput quotas than their standard counterparts, and those quotas are per topic and per queue. If your event rate is high, the honest answer is usually not "raise the quota" but "do you actually need global ordering, or do you need per-entity ordering?" Per-entity ordering with a well-chosen group id is achievable; a single ordered stream for an entire domain is a scaling dead end. A frequently better alternative is to keep the topic standard and make ordering a consumer concern: attach a monotonically increasing version or sequence number to each event and let the consumer discard anything older than what it has already applied. That gives you idempotent, order-tolerant processing at standard-topic throughput, and it is what most large systems actually do. Reach for FIFO when the ordering requirement is genuinely a business invariant — a financial ledger, a state machine that cannot go backwards — and when the volume fits inside the quota comfortably. ## Saying it in an interview "FIFO gives me ordering per message group and a short deduplication window, at the cost of throughput and of head-of-line blocking inside a group. It needs a group id on every publish, a deduplication id or content-based deduplication, and FIFO queues on the other side or the ordering evaporates. I'd pick the group id to match the entity whose ordering matters, and I'd check first whether a sequence number on a standard topic solves it more cheaply."

  • How do you choose the MessageGroupId, and what goes wrong at each extreme?
    Pick the entity whose ordering is a business invariant — order id, account id, aggregate id. A single constant group serialises the whole topic and caps throughput at one in-flight message at a time. Groups that are too fine, such as a per-event uuid, give you no ordering at all while paying FIFO's throughput price. The group id is simultaneously your ordering key and your unit of parallelism.
  • What does deduplication on a FIFO topic protect you from, and what does it not?
    It protects against a publisher retrying and creating a second copy of the same event inside the deduplication window. It does not make consumption exactly-once: a consumer can still receive and process a message more than once after a visibility timeout expires or a crash. Handlers must stay idempotent regardless of topic type.
  • When would you deliberately keep a standard topic even though ordering matters?
    When the volume exceeds what FIFO's quotas comfortably support, or when only relative ordering per entity matters and you can enforce it downstream. Stamp each event with a version or sequence number and have consumers ignore anything older than the state they have already applied. That is order-tolerant rather than ordered, and it scales at standard-topic rates.

saying these in an interview costs you the question

  • FIFO topics guarantee global ordering across all messages
  • Deduplication makes end-to-end delivery exactly-once
  • You can convert a standard topic to FIFO in place
  • A standard SQS queue subscribed to a FIFO topic stays ordered
  • Content-based deduplication is always the safe default

context