Apply backpressure before a queue grows without bounds

If producers create work faster than workers finish it, a queue can become an ever-growing waiting room. Backpressure gives the producer an explicit admission decision before it accepts more work.
Cooperating producers check capacity while holding the shared admission-row lock.
Make admission atomic where the work is stored
This Django fragment assumes a toy Workspace row and a Job table. Every producer for the workspace must use this service for the example limit to hold.
from django.db import transaction
def accept_job(workspace_id, payload):
with transaction.atomic():
Workspace.objects.select_for_update().get(pk=workspace_id)
outstanding = Job.objects.filter(
workspace_id=workspace_id,
state__in=["pending", "running"],
).count()
if outstanding >= 100:
return None
return Job.objects.create(
workspace_id=workspace_id,
state="pending",
payload=payload,
)
The value 100 is an example backlog policy. It is not a claim about how much work a particular server can handle. The transaction locks the shared admission row so cooperating producers do not all observe the same count and over-admit concurrently.
This design stores accepted work durably in the application database. A separate dispatcher can enqueue pending IDs. The browser should receive a job ID only after acceptance is committed, and a clear capacity response when no job was accepted.
Count the work that still consumes capacity
Define whether retrying, delayed or exporting jobs belong in the outstanding set. If a state is omitted while it still consumes scarce resources, the nominal limit can be bypassed. Cancellation and terminal transitions need to update the same authoritative job lifecycle.
A broker-depth check alone is racy when several producers check and enqueue independently. It can still be a useful operational signal, but it should not be described as a strict distributed admission bound without coordination.
The database query here can become expensive at scale. Index the intended filter and measure it; a counter or reservation ledger may be appropriate when a measured bottleneck justifies the extra consistency work.
Test the boundary with 99 and 100 synthetic outstanding jobs, then exercise concurrent admissions on PostgreSQL. Confirm a rejected request does not leave an orphan job or trigger a provider action.
Queue age and completion rate help an operator understand pressure. A flat queue count can hide jobs that are no longer making progress.
Postzyo provides related queue context. Celery's optimization guide discusses arrival and processing capacity; Django documents transactions.