Skip to content
SeeItFlow
System Design · 8 chapters · ~28 min read

AI Gateway System Design Interview Guide

How to scope, whiteboard, and defend an AI Gateway design in a 45-minute interview — nineteen questions interviewers actually ask about this topic, a full sample spoken answer, an evaluation rubric, and the mistakes that separate a pass from a strong pass.

Mangesh MandlikLast updated: How lessons are made
Chapter 01

Scope This in Five Minutes

The strongest opening move is naming the three responsibilities before drawing anything — it tells the interviewer you understand this isn't a generic proxy problem.

Open with: 'An AI Gateway governs access, routes reliable/compatible inference, and accounts for usage. Before I draw boxes, let me scope which of those matter most for this conversation.'

  • Ask: how many upstream providers, and does any tenant have a data-residency requirement?
  • Ask: is streaming in scope for V1, or request/response only?
  • Ask: is a hard budget cap required, or is bounded overshoot acceptable?
  • Ask: what's the illustrative scale — requests/sec, typical prompt size, number of tenants?
  • State explicitly what's out of scope (embeddings, images, agents) so the interviewer can correct you if wrong
  • Jumping straight to 'I'll use Redis for rate limiting' before establishing what's actually being rate-limited (requests? tokens? dollars? all three, independently?)
  • Treating this as 'just an API gateway with an LLM behind it' — that framing misses token/budget admission and streaming honesty entirely
  • Spending more than ~5 minutes on scoping — it's a signal of good process, not the main event
Chapter 02

The Whiteboard Build-Up

Draw in dependency order, narrating why each box exists as you add it — this demonstrates the same problem→solution progression this whole module is built around.

Swipe to pan
Whiteboard Build-UpDraw in this order: client → gateway → identity/quota → router/adapters → providers → ledger/control planeClient① Gateway② Quota③ Router④ Adapter④ Adapter⑤ Provider⑤ Provider⑥ Ledger + Control Plane
Draw in this order: client → gateway → identity/quota → router/adapters → providers → ledger/control plane
StepDrawSay
①Client → Gateway"One entry point so every tenant gets consistent identity and policy enforcement."
②Gateway → Quota Store"Before routing anywhere, reserve tokens and budget atomically — this is what stops one tenant from starving another."
③Gateway → Router"The router filters on hard constraints — residency, capability — then scores what's left on price/latency/health."
④Router → Adapters"Each provider gets its own adapter so format differences don't leak into the client contract."
⑤Adapters → Providers"At least two deployments, so routing and circuit-breaking have somewhere to fail over to."
⑥Gateway → Ledger + Control Plane"Usage settles to the ledger idempotently; policy comes from a control plane pushing async snapshots, never a live lookup on the request path."
Chapter 03

Questions Interviewers Ask

These are the questions that actually probe whether you understand the mechanics, not just the component names.

Q

Two gateway replicas both think there's quota left and both admit a request. How do you prevent that?

Strong answer angle

Name the race precisely (local vs. shared state across stateless replicas), then the fix: an atomic check-and-decrement against a shared counter store (Redis Lua script or equivalent single-round-trip atomic op), so only one of two simultaneous reservations for the same unit can succeed.

Likely follow-ups
  • What if the quota store itself is down? — Discuss explicit fail-open vs. fail-closed policy — and that failing closed for budget/TPM and a conservative fail-open for RPM is a defensible, commonly-used split.
  • Why not just use a database transaction for this? — Latency — a transactional DB write on every admission doesn't meet the sub-10ms overhead target at hundreds of req/s; an in-memory atomic store does.
Q

A response is streaming and the provider connection drops after 17 chunks. What does the gateway do?

Strong answer angle

Explain why this differs from a pre-first-byte failure: content has already been shown to the user, so silently failing over would splice in a different generation — dishonest. The correct behavior is an explicit stream_error event marking the response incomplete, with billing settled against actual tokens generated.

Likely follow-ups
  • Does the client get billed for the partial response? — Yes — those tokens were real provider work. Billing reflects what was generated, not what was successfully delivered.
Q

How do you stop one tenant's spend from going over budget?

Strong answer angle

Distinguish after-the-fact metering (checks spend once a request completes — allows concurrent overshoot) from atomic reservation (reserves a conservative worst-case estimate before admission, debits the real amount after, releases the rest). Be explicit that even reservation doesn't guarantee zero overshoot — only a small, bounded, documented one.

Likely follow-ups
  • Can you guarantee zero overshoot? — No, and say so directly — tokenizer differences and delayed provider usage reporting leave a real, if small, gap. A hard cap can get arbitrarily close at the cost of more false rejections near the budget edge.
Q

Why not just let every tenant call the provider directly with their own API key?

Strong answer angle

That's architecturally valid for a single team — walk through why it stops working at N teams: duplicated integration logic, N held credentials, no shared spend visibility, and critically no way to enforce a per-tenant model allowlist or atomic cross-tenant quota.

Q

How does this design scale to 10x the traffic?

Strong answer angle

Two separate answers: the gateway's own request-handling scales horizontally (stateless replicas behind a load balancer, sharing one quota store and ledger). The upstream provider's own rate limit does not scale just by adding gateway replicas — that's a separate capacity negotiation, and the design should surface it rather than hide it.

Likely follow-ups
  • What becomes the bottleneck first? — Usually the shared quota store's op rate for a single hot tenant, or the upstream provider's own RPM/TPM ceiling — not the gateway's own compute, which is cheap to replicate.
Q

A client requests 'the fast model.' How does the gateway know which actual provider model to call?

Strong answer angle

It doesn't look up a provider model directly — it resolves a logical model name (e.g. 'support-fast') to a list of candidate deployments the registry maintains, each with its own documented capability set (streaming, function calling, context window, vendor). The registry must publish the *intersection* of capabilities across all deployments behind one logical name, not the union — otherwise a client's request can succeed or fail purely depending on which deployment the router happened to pick that time.

Likely follow-ups
  • What happens when a provider silently changes a model's behavior? — The adapter contract is the firewall — an adapter raises an explicit CapabilityUnsupported error rather than silently dropping a field the new model version no longer honors. Routing never masks a real capability regression as a transient failure.
Q

What exactly does a 429 from this gateway mean, and is it always the same thing?

Strong answer angle

No — there are at least two different 429s, and conflating them is a common interview mistake. A 429 from the gateway itself means this tenant's own RPM/TPM/budget reservation failed at admission; the client should honor Retry-After and back off per-tenant. A 429 relayed from the provider means the *provider's* aggregate limit was hit — which can happen even when the tenant's own admission succeeded, if the gateway's total traffic across all tenants exceeds what the provider allots the account. The two call for different operator responses: one is a per-tenant policy signal, the other is a capacity/procurement signal.

Likely follow-ups
  • Why not just treat every 429 the same and retry? — A blind retry on a gateway-issued 429 ignores a deliberate admission decision and can make a hot tenant's problem worse; a blind retry on a provider 429 without routing to a different deployment just re-hits the same exhausted capacity.
Q

Walk me through enforcing a tokens-per-minute limit specifically — how is that different from a requests-per-minute limit?

Strong answer angle

RPM counts requests; TPM counts a quantity that isn't known exactly until the response finishes. The gateway reserves an estimated token count at admission — input tokens from a real tokenizer pass over the prompt, output tokens from the request's max_tokens cap (the worst case) — against a sliding or fixed window counter in the same atomic store used for RPM. The estimate, not the eventual actual, is what's checked against the limit at admission time, because the actual isn't known yet.

Likely follow-ups
  • What if the real output comes in far under the estimate? — The reservation settles to the real token count at completion and releases the unused portion back to the window — the same reserve-then-settle pattern used for budget.
Q

At exactly what point in the request lifecycle does reservation happen, and why not later?

Strong answer angle

Reservation happens at step 4 of admission — after authentication and policy authorization, but strictly before the router picks a deployment or any upstream call is made. Reserving any later (say, after the provider accepts the call) reopens the exact race two concurrent requests can exploit: both could pass a non-atomic check before either one's usage is recorded. Reserving earlier (before authorization) would needlessly charge quota against requests that policy was always going to reject.

Q

A response is streaming token by token. How do you even count tokens for billing before the stream ends?

Strong answer angle

You mostly don't count them yourself — the adapter's extractUsage step reads the provider's own usage accounting, typically delivered in a final SSE event or trailing metadata after the last content chunk, and that provider-reported count is the only source of truth for actual billing, never the gateway's own re-tokenization of the streamed text. If a stream is canceled before that final usage event arrives, settlement is marked pending reconciliation until the provider's usage report (which can arrive asynchronously) confirms the real amount.

Q

Why is retrying on a different provider unsafe once the first byte of a response has streamed to the client?

Strong answer angle

Before any bytes are sent, a retry is invisible to the client, so failing over to a healthy deployment is the right move, within a bounded number of attempts and a total deadline, all under the one reservation. A timeout deserves care: the provider may have run the request anyway, so the retry has to be covered by the reservation and the first attempt's usage reconciled later. Once content has started streaming, the client has already begun rendering one specific generation; silently retrying and splicing in a different provider's continuation would mean the user sees text from two unrelated generations stitched together, which is actively dishonest, not just a minor inconsistency. The only correct behavior past that point is an explicit stream_error event marking the response incomplete, settled for whatever was actually generated.

Q

One tenant requires EU-only data residency. How does that interact with routing and failover?

Strong answer angle

Residency is a hard filter, applied before scoring, not a preference weighed against price or latency — a deployment that doesn't satisfy the tenant's required region is removed from the candidate set entirely and can never be selected, even if every other eligible deployment is down. This holds during failure too: if the tenant's only compliant deployment is unhealthy, a healthy out-of-region deployment of the same logical model is still not an eligible fallback. The honest answer here is a 503, not a silent compliance violation.

Likely follow-ups
  • Isn't that worse for availability? — Yes, deliberately — for a regulated tenant, violating a residency constraint to preserve uptime is a worse outcome than a bounded, visible 503. That trade-off should be named explicitly, not hidden.
Q

What's the risk in routing purely on cost — always picking the cheapest eligible deployment?

Strong answer angle

A pure-price router optimizes exactly one axis and ignores two others that matter just as much: latency (the cheapest deployment might also be the slowest, degrading the product) and health (a deployment can be cheap because it's currently struggling, about to trip its circuit breaker). The routing score is deliberately a weighted combination of price, latency, and health precisely so a single cheap-but-unhealthy deployment can't dominate every routing decision.

Likely follow-ups
  • Who sets those weights? — Policy, per tenant or per logical model — a cost-sensitive internal tool and a latency-sensitive customer-facing chat product should not share the same routing weights even if they call the same logical model.
Q

How does provider credential rotation work without downtime?

Strong answer angle

A tenant (or the platform, for shared credentials) can hold two active virtual keys simultaneously during a rotation window — the old key keeps working while the new one is deployed and verified, and only gets revoked once the tenant confirms the cutover. Real provider API keys never leave server-side custody: they live in a secrets manager, and gateways either fetch them through a short-lived audited path or never see the raw secret at all, so a compromised gateway replica's memory exposes at most in-flight request credentials, not the whole vault.

Q

How fresh does a gateway's policy snapshot need to be, and what happens if a permission is revoked right after one is pulled?

Strong answer angle

Freshness is a deliberate, bounded staleness window — commonly tens of seconds — traded for keeping the control plane completely off the request hot path. A revocation that lands between two snapshot pulls is honored only once the next snapshot arrives; that bound must be documented and sized to the actual threat model, not silently assumed to be zero. If the control plane is unreachable entirely, gateways keep serving on their last good snapshot indefinitely, trading currency for availability.

Likely follow-ups
  • When would that staleness window be unacceptable? — A high-security environment needing instant revocation would add a dedicated low-latency revocation broadcast channel for that specific case, rather than making every policy change synchronous for everyone.
Q

What's a 'fallback model' here, and when is the gateway allowed to use one automatically?

Strong answer angle

A fallback is a different, capability-compatible deployment the router tries after the first choice rejects a request — but only automatically, and only before any bytes have reached the client. The fallback must pass the same hard filters (residency, capability, policy) as the original candidate; a fallback is never a compliance escape hatch. After streaming has started, there is no automatic fallback at all — the honest behavior is an explicit stream error, not a silent swap to a different model mid-response.

Q

How do you trace a request end-to-end for debugging without ever touching the prompt text?

Strong answer angle

A single correlation ID is attached at ingress and carried through every hop — gateway, router, adapter, provider call, and back — tagged with tenant, logical model, the deployment actually chosen and why, time-to-first-token, estimated and actual tokens, estimated and actual cost, any policy action taken, and the finish reason. Every one of those is metadata, not payload — full tracing and incident review is possible without the prompt or completion body ever being captured by default.

Likely follow-ups
  • When would you ever capture the actual prompt? — Only opt-in, purpose-limited capture — e.g. a tenant explicitly enabling debug logging for their own traffic — never as a default, and ideally with the captured payload itself access-controlled and separately audited from routine telemetry.
Q

Is this architecture 'zero trust'? What does that mean concretely here, not as a buzzword?

Strong answer angle

Concretely: every request is authenticated against a verified virtual key regardless of network origin — there's no implicit trust granted just because a call arrived from inside the VPC. Every hop re-checks authorization (tenant, model, capability) rather than trusting an upstream component's decision. Provider credentials are never exposed to the caller, even on introspection endpoints. And the control plane, not caller-supplied headers, is the only source of truth for what a tenant is allowed to do — the gateway never trusts a client to self-report its own entitlements.

Q

How would you size the gateway's concurrency limits for a given traffic profile?

Strong answer angle

Apply Little's Law — concurrency in flight equals arrival rate times average time in system (L = λW) — but treat it as a planning number, not a guarantee, because LLM request durations are not uniform: a long-tail minority of slow streams disproportionately holds concurrency slots far longer than the average suggests. Admission control has to reason about concurrent in-flight load directly, not just requests-per-second, or a burst of long streams can exhaust capacity while the RPS graph still looks calm.

Likely follow-ups
  • What if 10% of requests are 10x longer than average? — That tail alone can account for roughly half of total concurrency held at steady state — which is exactly why a single flat latency number stops being a useful planning input once a meaningful long tail exists.
Chapter 04

Common Mistakes Candidates Make

These show up repeatedly enough to be worth naming explicitly, in order of how often they actually cost points.

  • Reversing admission and routing — picking a deployment before confirming the tenant can even afford the call, instead of reserving first
  • Treating streaming as 'the same request, just chunked' instead of recognizing it changes the entire failure/retry model once bytes are committed
  • Proposing a synchronous control-plane lookup on every request 'for freshness,' without noticing this puts the control plane's own availability on the hot path
  • Promising zero budget overshoot without acknowledging tokenizer drift and delayed usage reporting make that promise undeliverable
  • Conflating guardrails (content inspection) with authorization (permission enforcement) — these solve different problems and neither substitutes for the other
  • Assuming more gateway replicas increases the provider's own rate limit — it doesn't; that's an external negotiation
  • Designing a semantic cache without per-tenant key scoping — a cross-tenant cache hit is a data-isolation bug, not a performance win
Chapter 05

A Full Sample Answer, Spoken Out Loud

This is roughly 5–8 minutes of spoken answer to a single prompt — 'Design a gateway that lets multiple teams safely call several LLM providers' — including the interviewer's interjections. Read it as a pace and structure model, not a script to memorize.

"Before I draw anything: an AI Gateway has three jobs — govern access, route reliable inference, and account for usage. Quick scoping questions: how many providers, is streaming in V1, and is a hard budget cap required or is bounded overshoot acceptable?"

"Good — that tells me I don't need a hard synchronous spend check on every token, just atomic reservation with honest settlement. Let me start from the simplest thing that works: one team, one provider, backend holds the API key directly. That's a legitimate V1, not a strawman — it just doesn't survive a second team showing up with their own credential and no shared visibility into spend."

"The first real problem at N teams is a noisy neighbor: a tenant-blind proxy forwards every request through a shared credential with no concept of who's calling, so one team's traffic spike exhausts a limit the whole shared key depends on. The fix is identity first — every request authenticates against a verified virtual key, never a caller-supplied header — and admission control second: before routing anywhere, atomically reserve a conservative worst-case token and dollar estimate against that tenant's own quota."

"Two gateway replicas serving the same tenant concurrently. If each replica checks 'is there quota left' and decrements separately, both can pass the check against stale state and together admit more than the tenant's actual limit — a classic check-then-act race. The fix is a single atomic check-and-decrement against one shared counter store, so only one of two simultaneous reservations for the same unit of quota can ever succeed."

"From there: a router that filters candidates on hard constraints first — data residency, required capability, circuit-breaker state — and only scores what survives on price, latency, and health. Filtering before scoring matters specifically so a cheap, disqualified deployment can never win and only get caught afterward; that ordering bug is how a residency violation reaches a provider. Each provider gets its own adapter so format differences stay out of the client contract, and usage settles to an idempotent ledger afterward — reserve pessimistically, settle precisely, release the gap."

"Streaming changes the failure model once bytes are committed: before the first byte, a failover to a healthy deployment is invisible to the client and safe. After the first byte, splicing in a different provider's continuation mid-response would show the user two unrelated generations stitched together — so the only honest behavior past that point is an explicit stream-error event, billed for what was actually generated, never a silent retry."

"Not zero, and I wouldn't claim zero. Reservation uses the max_tokens cap as the worst case, priced at the policy's rate — say $0.105 reserved for 1,500 input tokens plus a 500-token output cap at realistic asymmetric pricing. If the real completion uses only 310 output tokens, the ledger records the real cost, $0.0822, and settlement refunds the difference, about $0.0228, to the tenant's budget counter. Those are two steps in two stores, made safe to repeat and repaired by a reconciler if a gateway dies between them. The residual gap comes from tokenizer differences and delayed provider usage reporting, not from a design flaw — and whether that residual is acceptable is exactly the kind of policy decision that belongs in Trade-offs & Decisions, not swept under 'basically zero.'"

"Last piece: none of this should put the control plane on the request's hot path. Policy, pricing, and credentials arrive as versioned async snapshots with a bounded freshness window — commonly tens of seconds — so a control-plane outage degrades administration, not live traffic. That's the one-sentence version of the whole design: govern access, route reliable inference, account for usage — and nothing in this gateway does anything else."

Chapter 06

How This Gets Scored

A compact rubric across the dimensions that actually separate a pass from a strong pass — and what changes between a mid-level bar and a staff/principal one.

DimensionSignal of a passSignal of a strong pass (staff+)
ScopingAsks 2–3 clarifying questions before drawing anythingExplicitly states what's out of scope and why, and ties scope choices to which invariants matter most
InvariantsCan name 'tenant isolation' and 'budget control' as goalsStates invariants as falsifiable properties (e.g. 'no two replicas ever double-admit the same reservation') and explains the specific mechanism that holds each one
Core architectureDraws identity → routing → providers in roughly the right orderJustifies *why* each box exists by naming the problem it solves, in the same build-up order as Complete Design, not just reciting component names
Admission / usageKnows requests need rate limitingDistinguishes RPM/TPM/budget as three independently-enforced resources, explains atomic reservation vs. after-the-fact metering, and states the overshoot bound honestly
StreamingKnows streaming exists and uses chunksIdentifies the first-byte-committed boundary as the exact point the failure/retry model changes, unprompted
Failure reasoningCan describe one failure mode when askedProactively narrates failure modes while building the design — quota store down, provider 429 vs. gateway 429, mid-stream drop — before the interviewer has to ask
Trade-offsCan list a pro and a con for a choice when pushedNames the alternative, its cost, and the specific condition that would flip the decision, without prompting
ClarityExplanation is understandable with effortExplanation is precise enough that a support engineer could use it to debug a real incident from the reasoning alone
Chapter 07

How to Defend Your Trade-offs

When pushed on a decision, the strongest answers name the alternative, the cost of each option, and the specific condition under which the choice would flip.

Example exchange: 'Why async control-plane snapshots instead of live policy lookups?' → 'Because a synchronous lookup puts the control plane's availability directly on every request's critical path — if it's slow or down, every chat response is slow or down. The cost is a bounded staleness window for policy changes, including revocations. If the threat model required instant, zero-latency revocation for a high-security environment, I'd add a dedicated low-latency revocation broadcast channel for that specific case, rather than making every policy change synchronous.'

This pattern — name the alternative, name its cost, name the condition that would change the answer — works for every decision in Trade-offs & Decisions. It demonstrates the decision was reasoned, not memorized.

Chapter 08

The One-Sentence Mental Model

If you remember nothing else from this module, remember this sentence — it both scopes the design and gives you a way to check whether any proposed component actually belongs.

“An AI Gateway governs access, routes reliable inference, and accounts for usage — every component exists to do one of those three things, and nothing more.”

— This module's closing scene
Key takeaways
  1. 01Govern access: virtual keys, model ACLs, atomic RPM/TPM/budget reservation
  2. 02Route reliable inference: capability-aware filtering, health/circuit state, residency compliance, honest provider adapters
  3. 03Account for usage: idempotent ledger settlement, reconciliation of estimated vs. actual, metadata-only observability
  4. 04If a proposed component doesn't map to one of these three, it's probably solving a different system's problem (an inference server, a RAG pipeline, an agent orchestrator) — not a gateway's