Interview conceptML System Design

Streaming Conversational AI Systems

Asked of: Software Engineer

Last updated

Landscape architecture diagram of a streaming conversational AI: client transports to edge/gateway, stateless frontends, session store (Redis), admission control, compute workers, event log (Kafka) and snapshot store, showing resume token, chunk framing, cancellation and backpressure flows.

What's being tested

Candidates must show end-to-end engineering judgment for building low-latency, robust streaming chat systems: real-time transport choices, transient client state management, concurrency and cancellation, backpressure/admission control, and availability tradeoffs. Interviewers probe whether you can design practical, testable interfaces (APIs, idempotency, resume tokens), reason about tail latency and resource isolation, and communicate clear failure modes and mitigations a Software Engineer would implement.

Core knowledge

  • Streaming transport options — tradeoffs between `WebSocket`, Server-Sent Events (SSE), HTTP/2+gRPC streaming, and HTTP chunked responses; choose by bidirectionality, proxy compatibility, and browser support.

  • Chunked transfer & framing — send discrete token/delta frames; include sequence numbers, content-type application/json-seq, and explicit end-of-stream markers to enable reassembly and resume.

  • Resume tokens & idempotency — attach a compact resume cursor or token with each frame so clients can reconnect and request "resume from offset X"; use server-side idempotency keys for request deduplication.

  • Backpressure & admission control — use token-bucket or leaky-bucket per-client rate limiting and global admission control; reject or queue requests when CPU/latency budgets exceed thresholds to protect p99 latency.

  • Cancellation semantics — propagate client cancels immediately to compute layer; implement soft-cancel (stop token generation) and hard-cancel (kill compute) with timeout/window for graceful cleanup.

  • Stateless fronting with sticky state — keep frontends stateless relays but use sticky session routing or external session store (small Redis) for ephemeral streaming metadata (resume tokens, partial buffers).

  • Transient UI state model — represent in client as immutable message tree with in-progress flags and append-only token deltas; reconcile streams by id/seq to avoid flicker and duplicates.

  • Persistence model: snapshots & event log — store conversation as append-only event log plus periodic snapshots for reads; snapshotting at message boundaries speeds restores and sharing use-cases.

  • Consistency and concurrent updates — use optimistic concurrency control (CAS) for edits and snapshot writes; design for last-writer-wins or CRDT merge only if multi-author editing required.

  • Latency budgeting — set tight budgets: e.g., client RTT + server queueing + model compute ≤ target (e.g., 500ms for response start), monitor p95/p99 for throttling decisions; expose graceful degrade path (shorter summary instead of full generation).

  • Monitoring & observability signals — instrument request lifecycle: enqueue time, start time, token emission rate, bytes streamed, cancellation rate, resume success rate; alert on rising resume/retry counts and p99 token gaps.

  • Testing & determinism — add deterministic replay hooks and synthetic load tests that simulate partial-frame loss, reconnects, and slow clients; mock providers with configurable latency and tokenization.

Worked example — Build a Reliable Streaming Chat UI

First 30 seconds: clarify client constraints (browser vs native), expected throughput (users concurrently streaming), allowed transports (`WebSocket` vs SSE), and what “reliable” means (resume on reconnect, no duplicated tokens, consistent UI ordering). Skeleton answer pillars: (1) transport + framing (frame = {msg_id, seq, resume_token, delta}), (2) client state management (immutable message list with an in-progress entry and id/seq reconciliation), (3) resume & idempotency (server issues resume cursors and supports resume API), and (4) admission/backpressure (client-level rate-limits & server-side admission).

One tradeoff to flag: using `WebSocket` gives bidirectional control and built-in backpressure semantics in some stacks, but is harder to proxy and scale through certain load balancers—SSE is simpler but uni-directional. Implementation detail to call out: include sequence numbers and a server-signed resume token to avoid accepting stale resumes after conversation deletion. Close with next steps: if time remains, sketch tests (reconnect fuzzing), performance targets (p95 start latency), and how to instrument for out-of-order or missing frames.

A second angle — Design a Highly Available Conversational AI Service

This question emphasizes availability, regional isolation, and dependency failures. Apply the same streaming principles but shift focus to system-level resilience: front-door load shedding, multi-region routing, replica isolation, and graceful degradation. With streaming, you must plan admission control globally (reject to preserve p99 for existing streams), fall back to cached or summarised responses on dependency failure, and implement cross-region resume tokens so clients reconnect to nearest healthy region without redoing expensive compute. Also design per-tenant quotas and circuit breakers around an external LLM provider: if provider latency spikes, return a short canned reply or progress bar while preserving connection and allowing resume. The core primitives (framing, resume, cancellation, instrumentation) are identical, but you now prioritize isolation, capacity planning, and failover strategies.

Common pitfalls

Pitfall: assuming TCP backpressure is enough — TCP windows don't provide application-level flow control for tokenized JSON frames; you still need explicit rate or frame control and client-side buffering limits to avoid OOM or UI jank.

Pitfall: resuming by raw byte offset — resumes should be by logical token/sequence id with server validation; byte offsets break across different encodings, partial serialization, and middleware rewrites.

Pitfall: client optimistic UI that blindly appends streamed deltas without deduplication — this yields duplicated text after reconnects; reconcile on msg_id + seq and keep an idempotency filter.

Connections

Interviewers may pivot to adjacent topics like model-serving orchestration (scaling inference backends, warm pools) or data consistency (event sourcing vs relational snapshots) — be prepared to discuss how streaming primitives interact with those systems, especially for admission control and snapshot durability.

Further reading

Practice questions

Related concepts