Streaming Conversational AI Systems
Asked of: Software Engineer
Last updated

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+gRPCstreaming, 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
p99latency. -
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/p99for 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
p99token 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+seqand 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
- Designing Data-Intensive Applications (Martin Kleppmann) — event logs, snapshots, and distributed consistency patterns for conversation stores.
Practice questions
- Design a Chatbot with Object-Oriented PrinciplesOpenAI · Software Engineer · Technical Screen · medium
- Design a Highly Available Conversational AI ServiceOpenAI · Software Engineer · Onsite · medium
- Implement an Extensible Chatbot AppOpenAI · Software Engineer · Technical Screen · medium
- Build a Reliable Streaming Chat UIOpenAI · Software Engineer · HR Screen · hard
- Design a GPT chat UI with snapshots and sharingOpenAI · Software Engineer · Technical Screen · hard
- Design an AI chatbot with browser storageOpenAI · Software Engineer · Technical Screen · medium
- Design a minimal ChatGPT with presetsOpenAI · Software Engineer · Technical Screen · hard
- Design a chatbot (system design)OpenAI · Software Engineer · Technical Screen · medium
- Design ChatGPT homepage with streaming choicesOpenAI · Software Engineer · Technical Screen · hard
Related concepts
- LLM Chat Product ArchitectureML System Design
- Real-Time Messaging And Collaboration SystemsSystem Design
- Designing a ChatGPT-Style LLM Product End-to-End
- Chat System Design and Message DeliverySystem Design
- LLM Chat Applications, RAG, And ML EvaluationML System Design
- Slack-Like Messaging SystemsSystem Design