Skip to content
mummra.dev

Writing 18 Oct 2026 3 min read

Building exports at Triparound with Azure Service Bus and pub/sub

The architectural idea behind an export feature I built at Triparound: using Azure Service Bus and pub/sub to separate requests from processing, with practical considerations for messages and retries.


An export button looks simple from the outside: select some data, click Export, and get a file. Behind that button, the application has to coordinate work that may take considerably longer than an ordinary web request.

For the export functionality I built in Triparound’s public project, I used Azure Service Bus and a publish/subscribe mechanism. This post explains the architectural idea behind that approach, using a simplified flow rather than production code.

Separating the request from the work

An export involves several responsibilities: accepting the request, retrieving the data, generating the output, and making the result available to the user.

Putting all of that inside a single HTTP request couples the user’s wait to the entire operation. As the dataset grows, so does the amount of time the connection must remain open.

An asynchronous design separates accepting the request from completing it. The application can acknowledge that an export has been requested while a background consumer handles the expensive work.

Where pub/sub fits

Azure Service Bus implements pub/sub through topics and subscriptions. A publisher sends a message to a topic. Each matching subscription receives its own copy, and consumers process messages from their subscription independently. Multiple workers reading the same subscription share its workload; separate subscriptions provide the fan-out. Microsoft’s topics and subscriptions documentation

A simplified export workflow could look like this:

User requests an export
        ↓
Application publishes ExportRequested
        ↓
Service Bus topic
        ↓
Export-processing subscription
        ↓
Worker generates and stores the result
        ↓
Application makes the export available

The event name is illustrative. The important boundary is between the component accepting the request and the component performing the export.

Pub/sub becomes especially useful when several independent responsibilities need to react to the same event. An export-completed event, for example, could have separate subscriptions for user notifications and audit recording. Those are possible extensions of the pattern, rather than claims about Triparound’s implementation.

The message is a contract

A useful export message describes the work without carrying the entire dataset. An export identifier, the requested scope, and a versioned message structure give the consumer enough context to act.

The generated file belongs in storage. Messages can carry a reference to it, keeping file transfer separate from workflow coordination. Microsoft describes this approach as the claim-check pattern. Publisher–subscriber design guidance

Retries need application-level thinking

Moving work into messaging introduces failure cases that deserve explicit handling.

With Service Bus Peek-Lock, a message can be delivered again—for example, if processing succeeds but acknowledgement fails. An export consumer therefore needs to tolerate repeated delivery without accidentally producing duplicate effects. Broker duplicate detection alone does not make every downstream operation happen exactly once. Service Bus delivery and duplicate-processing guidance

For an export workflow, that means thinking about stable export identifiers, durable status, retry behaviour, and how failed work becomes visible to operators.

The user experience matters just as much. “Request accepted” and “file ready” represent different states, and the interface should communicate that distinction clearly.

The architectural value of this approach is the separation of responsibilities: the application accepts the request, messaging coordinates the handoff, and consumers perform the work. An export becomes a workflow whose individual stages can be understood, operated, and improved independently.