topic: is like a category for the messages (grouping). Basically, you can:

  • Use a single topic (using the 3rd service name) for all requests.

  • Or use multiple topics for the same service as well if you are confident that there won't be any conflicts.


  • inbox/stripe

  • inbox/currency-cloud

  • inbox/stripe-invoice

  • inbox/stripe-payment

  • ...

Unique External Id

In order to ensure the msgs are unique, you must determine the unique external id for each topic.

Something like: the unique ID of the 3rd-party entity.

If the entity changes the stage frequently, you can add a prefix.

I had a real use case a while back. The Payment entity status would be updated frequently so I introduced:

  • payment-received-{paymentUuid}

  • payment-handling-{paymentUuid}

  • payment-sending-{paymentUuid}

  • payment-sent-{paymentUuid}

DB Constraint: UNIQUE(topic, external_id)


To keep the ordering, we are using the UNIX timestamp in milliseconds instead of using timestamp or datetime from DB.


  • Faster sorting & pulling the unresolved msgs.

  • Keeping the correct order at the millisecond level.

We also add a created_at timestamp column to increase your visibility too (readable).

Last updated