Case study 10 · Engineering Lifecycle Services

Live run monitoring and cancellation across server instances

Step-by-step run logs streamed to the browser as they are written, and cancellation that reaches whichever server is running the pipeline.

Partner
A multinational advisory firm
Period
October 2024 to January 2026
Live streams
2
Whole run, and each step's input or output
Instance
Any
Cancellation reaches the server running the work
Replay
In order
Sequence numbers prevent gaps and duplicates

The challenge

Pipelines can run for minutes. Users needed to watch progress step by step and stop a run that was going wrong, even though the platform runs on several server instances.

What we built

A database trigger that announces each new log entry by its id, a listener that forwards entries to browsers over WebSockets in sequence order, and a Redis channel that carries cancellation requests to the instance that owns the run, which confirms them.

What was delivered

  • Live run and per-step views over WebSockets
  • Earlier entries replayed when a viewer connects, with no gaps or duplicates
  • Cancellation across instances, confirmed and recorded as a Cancelled status

Partner background

Our partner is a multinational advisory firm whose teams work with large volumes of documents, spreadsheets, databases and email. It wanted one internal platform where those teams could build data pipelines and AI agents themselves, instead of commissioning a new application for each need. The platform had to run inside the partner's Microsoft 365 and Azure environment, keep each team's work separate, and move work from experiment to production through controlled environments. This case study covers one part of that platform; nine case studies describe the whole.

The challenge

Waiting without feedback

Without live progress, users refreshed pages or started duplicate runs to check whether a pipeline was still working.

More than one server

The request to view or cancel a run can arrive at a different instance from the one executing it.

Joining mid-run

A viewer who connects during a run needs the earlier entries and the live ones, with nothing lost or shown twice where the two meet.

Large outputs

A step's output can be too large to send as a single message.

Instances fail

A run whose instance stops must not stay Running forever.

Objectives

  • Show each step's progress as it happens
  • Let viewers who join late see what already happened, in order
  • Cancel a run from any session, whichever instance runs it
  • Deliver large step outputs safely to the browser
  • Mark runs left behind by a failed instance

Our role

CharCentric provided technical leadership and architecture within a multidisciplinary engineering team, and contributed directly to implementation. The platform was built over 16 months, from October 2024 to January 2026, as a Python and FastAPI backend on Azure.

Scope and timeline

The log trigger, streaming endpoints and cancellation were built between December 2024 and August 2025.

Delivery timeline from the project history, against the overall platform build
Delivery timeline from the project history, against the overall platform build

Approach

Let the database announce changes

A PostgreSQL trigger on the run log table sends a NOTIFY message with the new entry's id. Any instance can listen and read the entry by id, which keeps messages far below PostgreSQL's 8,000-byte payload limit.

Number every entry

Each log entry has a sequence number within its run. A new viewer receives stored entries up to the current number, then live entries above it, so the two streams meet without gaps or duplicates. The listener subscribes before stored entries are read, and holds an entry until the one before it has arrived.

A shared channel for control

Cancellation requests are published on a Redis channel. The instance holding the run cancels its task, marks the run Cancelled and publishes a confirmation. A request that is not confirmed within a timeout is reported to the user.

Implementation

Architecture overview
Architecture overview

Run stream

A WebSocket endpoint per run sends stored entries, then live entries, in sequence order, and closes when the run finishes. The listener starts when the first viewer subscribes and stops when the last one leaves.

Step stream

A second endpoint sends a chosen step's input or output, split into size-limited batches.

Cancellation

Each instance keeps a record of the runs it is executing and listens for cancellation only while it has active runs.

Abandoned runs

Each instance sends a heartbeat for its active runs. A sweeper marks a run as failed when its instance stops sending them.

How it works, step by step
How it works, step by step

Tools and technologies

ToolPurpose
PostgreSQL LISTEN and NOTIFYLog change notifications
asyncpgNative listener connection
Redis publish and subscribeCancellation requests and confirmations
FastAPI WebSocketsBrowser streaming
AlembicTrigger migration

What was delivered

WebSocket streams
2
Shared cancel channel
1
Replay
In order
Listeners
On demand
  • Live, replayable run and step logs in the browser, in order
  • Cancellation that works across server instances, with confirmation
  • Listeners that run only while someone is watching
  • Abandoned runs detected and marked failed

Why it matters

Operating a system includes seeing what it is doing and stopping it when needed. Designing for several instances from the start avoids behaviour that only works on one server.

If your organization is planning a platform of this kind, or needs a specific part of one designed and delivered, we would be glad to discuss it.