Skip to main content

Admission Control for AI Workloads

A target can satisfy policy and still lack capacity. Admission control turns readiness into a bounded claim before work begins.

Lovell Felix 8 min read

In Placement Profiles, I described what a workload needs without naming the infrastructure that will satisfy it. That was enough to narrow the field to targets a workload is allowed to use.

It was never enough to know whether any of them could take the work right now.

I noticed the gap most clearly when inference runs directly on my 18GB Mac, sharing unified memory with the editor, browser, containers, and everything else I'm running. A background task can be fully eligible for that runtime and still be the wrong thing to start while an interactive model is resident.

I catch that kind of contention while I'm sitting at the machine. An automated caller only sees a qualified target and a healthy endpoint, not the cost of starting one more workload.

From Model Routing to Workload Placement separated where a task executes from where its inference requests are served. Neither decision reserves memory, a workspace, an inference slot, or room on a queue. Admission is where the system decides whether one of those targets can accept the work now.

Readiness is evidence, not a reservation

My inference proxy already uses health information when it selects an implicit local route. That keeps traffic away from a local backend that is known to be unhealthy, but health alone is a weak admission signal.

A process can be alive while its model is cold. A queue can respond while every worker is occupied. A remote endpoint can be reachable while the workload has no remaining cost budget. On the Mac, a local model can be healthy even though loading another model would put too much pressure on unified memory.

A useful admission decision may need current memory pressure, model residency, queue depth, workspace availability, and cost. The workload contributes its deadline, priority, and permitted fallback paths.

Some of that information comes from the target, and some comes from the workload. I do not need one capacity formula for every runtime. I need enough current state to compare an eligible target with the work it is being asked to accept.

That state is still an observation. If the local runtime appears to have room for one more workload, two callers can read the same value and choose it at the same time. Both decisions look valid in isolation, but together they overcommit the machine.

Admission happens at the capacity boundary

For each admission-controlled resource, participating callers need a common authority that grants claims against the same capacity state. It might be the runtime, a queue broker, or a central allocator. The important part is that every caller updates the same capacity state before work begins.

The mechanism can vary with the resource. A runtime might issue a concurrency token. A worker pool might lease a workspace slot. A scheduler might reserve part of a capacity budget.

Each claim belongs to one workload, expires if the work never starts, and releases its capacity when the work finishes. The runtime also checks it when execution begins — an expired claim sends the caller back to the start of admission.

On the Mac, a token does not stop a browser tab or an unrelated process from consuming memory. It only prevents workloads using the admission path from taking the same slot. The runtime still has to check physical conditions when work starts.

These are two different kinds of claim. A queue slot or a workspace lease is a hard reservation: the system that owns the resource controls every consumer of it. A concurrency token against unified memory is advisory: it binds the callers that go through admission and nothing else. Treating them as the same kind of claim only holds as long as every consumer of that resource actually goes through admission.

If conditions changed, the runtime refuses the start and releases the claim. The placement layer can then try another eligible target, queue the work, or reject it.

Recent readiness can help rank candidates. The capacity claim is what admits the work.

Admission requires a bounded capacity claim The workload contract and current target observations inform an atomic capacity claim. A granted claim admits the workload. A refused claim returns the workload to placement, which can try another eligible target, admit the task to a bounded queue, or reject it. ADMISSION BOUNDARY workload contract deadline · priority · fallback target observations readiness · capacity · queue CAPACITY BOUNDARY attempt a bounded claim acquire · validate · release CLAIM GRANTED CLAIM REFUSED admit claim is active placement decides within the placement profile try another not a final outcome queue bounded queue slot reject reason NEXT CANDIDATE A refused claim returns the workload to placement for another permitted path.
Placement proposes a target. A bounded capacity claim decides whether work can start.

Task execution and inference are still separate

The first article separated task-execution placement from inference placement. Admission needs to preserve the same boundary.

A remote worker may have an available workspace while the approved inference path has no capacity. Granting one claim does not admit the entire workload if another resource is required before it can begin — and if the second claim fails, the first must be released rather than held by work that still cannot run.

One successful claim is not enough. The workload can start only after the resources it needs at startup have accepted it.

A queue has two admission points

My current synchronous agent and proxy paths have bounded request windows. If a profile describes work that will exceed those windows, synchronous execution is not eligible in the first place. The work has to use a queue-backed worker or a detached local job whose lifecycle is independent of the original request.

Admission begins again at the queue boundary. In this model, the queue accepts a task only if it has a bounded slot and the estimated start time still fits the workload's deadline. Acceptance records the work for a later attempt.

When a worker picks up that task, it has to claim execution capacity before starting. A queue slot reserves queue capacity, not memory, a model, or a workspace on the eventual worker.

Admission should return a clear result

Admission returns one of three outcomes: admitted, queued, or rejected. Trying another eligible target is not a separate outcome. It begins another admission attempt, and that target must grant its own claim. Queued is a result the caller receives; redirection never reaches the caller at all.

That decision is small enough to record:

{
  "workload_id": "work_01J...",
  "outcome": "admitted",
  "profile": "private-interactive",
  "version": 3,
  "target": "mlx",
  "reason": "warm capacity available",
  "claim_id": "claim_01J...",
  "claim_expires_at": "2026-07-30T13:42:40Z"
}

Priority and fallback are still policy

On a constrained local machine, a scheduled analysis should not displace an interactive coding session merely because it arrived first. A maintenance task should not consume the last worker slot needed for a production response. A low-cost batch job may wait while a deadline-bound task uses an approved remote path.

Priority has to exist before contention. It can affect which capacity is reserved and whether work may wait, while the queue or scheduler continues to own ordering and preemption.

Priority influences admission and queue ordering. It does not imply that running work can be safely displaced — this system doesn't preempt today.

My current routing policy already carries some of this information. Locality, duration, reasoning requirements, and cadence influence whether work stays synchronous, enters a queue, or uses a remote worker. Priority, not just fit, decides which path a workload uses when synchronous, queued, and local-only options are all technically eligible.

Fallback remains inside the placement profile. If the profile permits a smaller qualified model, a queue, or an approved remote endpoint, a refused claim can lead to one of those paths. If it does not, the work is queued on a permitted path or rejected. Admission pressure is not permission to broaden the data boundary or weaken the required capability.

What exists today

The current system has pieces of this boundary, but they do not yet make one admission decision.

The inference proxy checks backend health for implicit routes, though explicit routes bypass that check. Long-running tasks use queue-backed workers instead of synchronous calls, scoped by time windows, task limits, and workspace boundaries. Run records land in a shared ledger.

Those controls prevent some incorrect placements. They do not atomically reserve memory, model slots, queue capacity, or workspaces across the system. The task-claim marker used by a worker is ownership metadata, not a capacity reservation.

The next step is to give the proxy, queues, workers, and schedulers the same small admission behavior. Each one should report the state that matters for its resource, accept or refuse a bounded claim, verify that claim when work starts, and release it afterward.

The gap in my system is applying these mechanisms consistently across inference and task execution: a small admission contract across a local runtime, queues, workers, and cloud APIs that don't share one allocator.

The claim needs a record

The record for this boundary can stay narrow. I need the workload and profile, the target that granted or refused the claim, the claim identifier and expiration, and the reason for the final outcome. That is enough to see whether work started with a valid claim and whether refused work moved to another permitted path.

On the 18GB Mac, this would let a scheduled analysis see that the local slot is occupied, preserve the interactive session, and remain queued until capacity is released. The profile said the runtime was eligible. Admission decided it could not take both workloads at once.

Coming next

This article builds on From Model Routing to Workload Placement and Placement Profiles. The remaining articles follow the decision after admission: how it is observed, governed, and corrected.

  • Observability for Placement Decisions: how to connect placement, admission, execution, and outcome records
  • Governance for AI Workloads: how authority, verification, rollback, and human control bound automation

About the author

Lovell Felix

Infrastructure and reliability engineer working on Linux platforms, configuration delivery, and deployment safety at fleet scale.

@lovellfelix

More notes