Two names get bolted together in serving-stack conversations — SGLang and OME — and they are not the same thing, nor do they solve the same problem. SGLang is the runtime that actually executes an LLM request. OME (Open Model Engine) is the operator layer that schedules and scales those runtimes on Kubernetes. Confusing the two, or treating both as a black box you deploy once and forget, is how teams end up reading their inference bill as a fixed cost instead of a set of knobs. Here is the claim worth internalising before anything else: the features inside SGLang — prefix caching, continuous batching, structured-output constraints — directly govern how many GPU-seconds each request consumes. GPU-seconds per request is the per-request economic event. So the choice of serving stack is not an implementation detail you delegate downstream. It is one of the largest levers on cost-per-request you have, and it sits upstream of the cloud bill, not after it. What is SGLang, and what is OME in the serving stack? SGLang is an inference-serving runtime for large language models. Its job is to take a request — a prompt, generation parameters, maybe a schema the output must conform to — and turn it into GPU work as efficiently as it can. It competes in the same category as vLLM and TensorRT-LLM: runtimes that own the hot path where tokens are generated. The distinguishing features SGLang leans on are RadixAttention (a prefix-caching scheme), continuous batching, and first-class support for constrained decoding when you need structured JSON or grammar-bound output. OME — Open Model Engine — is a different layer entirely. It is a Kubernetes operator: a controller that knows how to deploy SGLang runtimes as pods, wire up model weights, route traffic, and scale replicas up and down against demand. If SGLang is the engine, OME is the thing that decides how many engines are running, on which nodes, and when to spin them down. You can run SGLang without OME (a plain deployment behind a service), and OME is the layer that makes that operational at scale. The reason the pairing matters economically is that the two layers control different halves of the cost equation. SGLang controls GPU-seconds per request — the efficiency of each unit of work. OME controls the utilisation floor — whether the GPUs you are paying for are actually busy. You can have a beautifully efficient runtime bleeding money because it sits at 15% utilisation, and you can have a fully-utilised cluster running an untuned runtime that burns twice the GPU-seconds it needs to. Cost-per-request only drops when both halves move in the right direction. Layer What it is What it controls Cost lever SGLang Inference runtime (per-request execution) GPU-seconds consumed per request Prefix caching, batching, decode efficiency OME Kubernetes operator Replica count, scheduling, autoscaling Utilisation floor, idle GPU-seconds Together Serving stack Cost-per-request end to end Both efficiency and utilisation This is the framing the cost-per-request primer for production AI features sets up, and SGLang OME is the concrete runtime you attach it to. How do RadixAttention and continuous batching affect GPU-seconds per request? RadixAttention is SGLang’s approach to prefix caching. When multiple requests share a common prefix — a system prompt, a few-shot template, a long retrieved document reused across a conversation — the key/value cache computed for that prefix can be stored in a radix tree and reused rather than recomputed. The prefill phase, which processes the entire input before the first token is generated, is where a large share of GPU time goes on long-context workloads. If a request’s prefix is already cached, you skip recomputing it, and the GPU-seconds for that request fall accordingly. The size of the win is entirely workload-dependent, and this is where teams mislead themselves. For a workload where every request is unique — one-shot completions with no shared context — prefix caching does almost nothing, because there is nothing to reuse. For a chat product where every turn re-sends the same system prompt plus the growing conversation history, or a RAG pipeline where the same document context is queried repeatedly, the cache-hit rate on shared prefixes can be high and the GPU-seconds saved can be material (observed pattern across serving engagements; the exact figure depends on prompt structure and is not a benchmarked constant). The behaviour of these repeated-context workloads is exactly what our writeup on retrieval-augmented generation patterns and what they prove about workload behaviour digs into. Continuous batching is the second lever, and it attacks a different waste. Naive batching waits for a batch of requests to fill, runs them together, and waits for the slowest one to finish before starting the next batch — which means fast requests idle while a long generation drags on. Continuous batching (sometimes called in-flight or iteration-level batching) instead lets finished requests leave the batch and new ones join at every decode step, keeping the GPU saturated. The effect is higher tokens-per-second throughput at a given latency target, which means more requests served per GPU-second, which means the fixed GPU cost is amortised across more work. This is the same class of runtime optimisation that machine learning compilers exploit to cut cost-per-request, just at the scheduling layer rather than the kernel layer. Structured-output constraints are the subtler third factor. Forcing output to conform to a JSON schema or grammar can, done well, shorten generations and reduce retries — a request that produces valid output on the first pass costs fewer tokens than one that fails validation and gets resubmitted. Done badly, constrained decoding adds overhead per token. Whether it helps your cost-per-request is an empirical question, not an assumption. How does OME set the utilisation floor? A tuned runtime saves nothing if the GPU it runs on sits idle. OME’s scheduling and autoscaling behaviour is what determines whether the efficiency SGLang delivers per request actually shows up on the bill. The mechanism is straightforward once you name it. OME watches demand signals — queue depth, request rate, or a custom metric — and adds or removes SGLang replicas to match. The two failure modes are symmetric. Over-provision, and you pay for GPUs that are barely used; your per-request efficiency is real but your utilisation floor is low, so cost-per-request stays high. Under-provision or scale too slowly, and requests queue, latency SLOs break, and you either eat the SLO miss or over-provision defensively to avoid it. The autoscaling policy — how aggressively it scales, how long it waits before scaling down, whether it can pre-warm replicas — is the dial that sets where between those failure modes you land. Cold starts complicate this. Loading a multi-billion-parameter model into GPU memory takes time, so a replica that scales from zero is not instantly available. OME’s handling of warm pools and scale-to-zero policy determines whether you can afford to run lean off-peak or must keep a floor of warm replicas. For bursty, spiky traffic this trade-off is often the single largest driver of the utilisation floor, and it is decided by operator configuration, not by the runtime. When is SGLang OME the right choice versus a managed inference API? This is the decision most teams actually face, and it does not have a universal answer. The honest version is a set of conditions. Signal Leans toward SGLang OME (self-hosted) Leans toward a managed API Sustained request volume High and steady — utilisation stays high Low or spiky — you’d pay for idle GPUs Shared-prefix structure High reuse (chat, RAG) — caching pays off Every request unique — caching does little Model choice Open-weight model you want to control Proprietary model only the API serves Kubernetes maturity You already run and staff a cluster No platform team to operate an operator Cost-per-request at scale Marginal GPU cost beats per-token API pricing Volume too low to amortise fixed infra Latency and data control Need on-prem or strict data residency Public cloud endpoint is acceptable The pattern we see is that self-hosting with SGLang OME wins when volume is high enough and steady enough that the utilisation floor stays up, and when the workload has enough shared-prefix structure that RadixAttention earns its keep. A managed API wins when volume is low, spiky, or so variable that you cannot keep GPUs busy — because a per-token price you pay only when you call is cheaper than a GPU you rent whether you use it or not. The break-even is a real calculation, not a philosophy; you can rough it out with an LLM token calculator for estimating inference cost per request before committing to either path. For teams operating in the SaaS and platform space, where inference cost is a direct margin line, this decision recurs at every scale threshold — which is why we treat it as a core part of engineering AI infrastructure for SaaS products. How do you measure whether SGLang is actually lowering your cost-per-request? Belief is not measurement. The only way to know whether SGLang OME is doing what you hoped is to instrument the four numbers that compose cost-per-request and watch them under real traffic, not synthetic load. GPU-seconds per request — the primary efficiency number. Falls when prefix caching hits and batching is dense. Cache-hit rate on shared prefixes — tells you whether RadixAttention is finding reuse or your workload has none to find. Tokens-per-second throughput — under a fixed latency SLO, this reflects how well continuous batching is saturating the GPU. Utilisation floor — average GPU utilisation across the autoscaling window, which reveals whether OME is over- or under-provisioning. Multiply GPU-seconds per request by the GPU’s rented cost-per-second and you have cost-per-request from the runtime side; divide the total GPU spend across a window by requests served and you have it from the bill side. If those two numbers disagree, the gap is your utilisation floor telling you OME is paying for idle capacity. Actually pinning down GPU-seconds per request means profiling the serving path itself, which is where runtime concepts meet GPU-level instrumentation of the inference path — the measurement has to happen at the layer where the GPU work occurs, not inferred from the invoice. A caution worth stating plainly: benchmark SGLang against your workload, with your prompt structure and your traffic shape, before drawing conclusions. A published throughput number from someone else’s workload tells you almost nothing about your cost-per-request, because the caching and batching wins depend on the structure of your requests, not on the runtime in isolation. FAQ How should you think about SGLang OME in practice? SGLang is an inference runtime that executes each LLM request, and OME (Open Model Engine) is a Kubernetes operator that schedules and autoscales SGLang runtimes as pods. In practice, SGLang controls how many GPU-seconds each request consumes through prefix caching and batching, while OME controls how busy your GPUs are through autoscaling — so cost-per-request depends on both layers, not one. What is SGLang, and what is OME (Open Model Engine) in the serving stack? SGLang is a serving runtime in the same category as vLLM and TensorRT-LLM, distinguished by RadixAttention prefix caching, continuous batching, and constrained decoding. OME is the operator layer above it that deploys those runtimes on Kubernetes, routes traffic, and scales replicas. The engine executes requests; the operator decides how many engines run and when. How do SGLang features like RadixAttention prefix caching and continuous batching affect GPU-seconds per request? RadixAttention caches the key/value state of shared prefixes so repeated context (system prompts, RAG documents, conversation history) is not recomputed, cutting prefill GPU-seconds when cache-hit rates are high. Continuous batching lets requests join and leave the batch at every decode step, keeping the GPU saturated and raising tokens-per-second. Both lower GPU-seconds per request, but only for workloads whose structure gives them something to exploit. How does OME schedule and autoscale SGLang runtimes on Kubernetes, and why does that set the utilisation floor? OME watches demand signals like queue depth and request rate and adds or removes SGLang replicas to match. Its autoscaling aggressiveness, scale-down delay, and cold-start handling determine average GPU utilisation — the utilisation floor. A low floor means you pay for idle GPUs, so even an efficient runtime yields high cost-per-request until utilisation is fixed. How do SGLang and OME connect to cost-per-request for a production LLM feature? Cost-per-request is GPU-seconds per request multiplied by the GPU’s rented cost-per-second, divided across how busy those GPUs stay. SGLang moves the GPU-seconds side through caching and batching; OME moves the utilisation side through autoscaling. Both must move in the right direction for the bill to drop. When is SGLang OME the right serving choice versus a managed inference API? Self-hosting with SGLang OME tends to win when request volume is high and steady enough to keep GPUs busy, the workload has shared-prefix structure that caching exploits, and you run an open-weight model on a Kubernetes cluster you already staff. A managed API tends to win when volume is low or spiky, since per-token pricing you pay only on use beats renting idle GPUs. It is a break-even calculation, not a default. How do you measure whether SGLang is actually lowering your cost-per-request? Instrument four numbers under real traffic: GPU-seconds per request, cache-hit rate on shared prefixes, tokens-per-second throughput at a fixed latency SLO, and the utilisation floor. Compute cost-per-request from the runtime side (GPU-seconds × cost-per-second) and from the bill side (total spend ÷ requests), and treat any gap as your utilisation floor exposing idle capacity. Always benchmark against your own workload, not a published number. The uncertainty that remains is not about what SGLang or OME do — it is about your workload. Whether prefix caching earns its keep, whether continuous batching lifts throughput enough to matter, and whether OME can keep utilisation high under your traffic shape are all empirical questions that only your own profiling answers. Name the failure class before you spend: an untuned serving stack absorbing cost drift you never measured. The knobs are real; the win is not automatic.