Service Levels for the Space Between Systems: Making Backpressure Explicit
Most integration incidents do not begin with a red light. They begin with a queue that is slightly deeper than it was yesterday, a retry count that has crept upward, or a batch window that closes a little later each week. The connection is still up. The API is still returning responses. The event stream is still flowing. Yet the estate is already under strain, because the producer and the consumer no longer share the same rhythm.
For UK organisations running mixed estates of batch files, message queues and event streams, backpressure is often treated as a technical detail to be handled inside middleware. It is better understood as a governance issue. The queue is where availability, latency and supplier behaviour meet. If that space between systems has no agreed service level, it will eventually define one during an incident.
Connection health is not flow health
Operational dashboards tend to answer a narrow question: is the link available? They show successful HTTP responses, open ports, broker connectivity and job completion. These are necessary signals, but they do not show whether work is being absorbed at a sustainable rate. A system can be technically available while its backlog grows beyond the point of recovery.
The practical measures are less glamorous. Queue depth shows accumulation. Message age shows whether the backlog is recent or stagnant. Consumer lag shows whether the downstream process is keeping pace. Retry volume shows whether transient failures are being amplified by repeated attempts. Taken together, these measures describe flow health rather than connection health.
That distinction matters in supplier conversations. A managed service can be available according to its own status page while the integration consuming it falls further behind. Without shared flow metrics, accountability becomes a debate about definitions. With them, the discussion moves to capacity, throttling and recovery time.
Three numbers that belong in the agreement
Not every metric needs to become a contractual term. But three families of measure are usually worth making explicit.
The first is queue depth and age. For event-driven systems, this may be consumer lag by partition or by consumer group. For batch systems, it may be the number of unprocessed records, the age of the oldest file, or the time taken to close the daily window. The precise measure matters less than agreeing which one represents the service.
The second is a retry budget. Retries are useful, but unbounded retries turn a downstream fault into a self-inflicted denial of service. A retry budget should state the maximum number of attempts, the backoff pattern, the total time allowed before the message is parked, and the conditions under which retries stop altogether. It should also confirm that retried operations are idempotent, or that duplicate handling is understood by both parties.
The third is a recovery expectation. If a queue exceeds an agreed threshold, what happens next? Is the producer expected to slow down? Is the consumer expected to scale? Is the supplier expected to provide additional capacity? Is a manual intervention required? A threshold without an associated action is only an alert. A threshold with a named action is closer to a service level.
Throttling as agreed behaviour
Backpressure works best when it is designed into the interface rather than improvised during an outage. At the ingress point, a token bucket or rate limiter can cap sustained throughput and allow short bursts within agreed limits. When the limit is exceeded, the producer should receive a predictable response, such as a throttling status with a retry-after instruction, rather than an ambiguous failure.
Queues should be bounded. An unbounded queue does not remove pressure; it stores it until the recovery options are worse. Bounded queues force a decision earlier, when there is still room to prioritise, defer or shed work. For business-critical flows, that decision may involve reserving capacity for priority messages and allowing lower-value traffic to wait.
Dead-letter handling is part of the same discipline. A dead-letter queue without an owner is simply a place where failures are left to age. The agreement should identify who triages the queue, how quickly, what evidence is retained, and how replay is authorised. Retention periods should be long enough to support reconciliation, but not so long that the queue becomes an unmanaged archive.
Batch and event-driven systems need different clauses
Batch integrations are often governed by the calendar. The service level may be expressed as an arrival window, a maximum file size, a record count and a completion deadline. Rejection files and reconciliation reports are not extras; they are the evidence that the batch has been understood. If a supplier changes the delivery time or file structure, the contract should require notice, because the downstream schedule is part of the service.
Event-driven integrations need clauses around lag, ordering and duplicates. Consumer lag should be measured against a defined percentile, not only an average, because averages hide the partitions that are falling behind. Ordering guarantees should be stated per key rather than assumed across the whole stream. Duplicate tolerance should be explicit, especially where retries and replays are permitted.
In both cases, capacity reviews are more useful than static promises. A supplier that agrees to a fixed rate without reviewing seasonal peaks, month-end processing or regulatory deadlines is offering a number, not a service. UK organisations often carry predictable annual peaks, and the integration agreement should reflect them.
Accountability without blame
The purpose of these measures is not to assign fault. It is to make the operating model visible. Suppliers should expose the metrics that describe their side of the flow: accepted rate, throttled rate, queue depth, error rate and dead-letter volume. Consumers should expose their own lag and recovery evidence. Both parties should share a runbook for degradation, including who decides to pause a producer and who authorises a replay.
Backpressure is sometimes described as a technical pattern. In practice, it is a contractual posture. It says that the space between systems has limits, that those limits are known, and that neither side will pretend a growing queue is normal. For an integration estate, that is a more honest form of service level than a green dashboard that nobody trusts.