Skip to content
Forward Deployed

Forward Deployed
Lessons and contents
Build the MVPLesson 1 of 5
5 lessons
Learn

Build the MVP: understand the problem

Source
From the Staff AI System Design course
By
Sourav Banerjee
Last updated
8 Nov 2026

Report an issue

Alice, a procurement analyst in Tenant A, wants to draft a supplier email from text she provides and reopen the saved answer. Build that request path before adding document search, background jobs, or a platform of separate services.

This is an educational design for a hypothetical customer. All workload, latency, quota, retention, and token figures below are illustrative assumptions. The executable lab verifies a local slice with fixture identity and a deterministic model. It does not deploy an enterprise service or call a hosted model.

Follow five learning phases: understand the problem, learn and design, observe and experiment, think like a Staff engineer, then validate and carry forward. The detailed material stays within the original MVP scope.

Before this lesson, read the T18.1 overview for the complete customer journey and target architecture. Then return here to build the first saved-draft path.

1. Before This Stage

No system exists. There is no previous stage to inherit, no benchmark, and no existing identity integration. Alice currently copies text into an unmanaged drafting tool and saves the result manually. That workflow is the hypothetical starting requirement, not observed customer research.

Diagram: Enterprise User: Alice, Tenant A; Requirement: draft and reopen supplier email; No API, model adapter, or request store existsDiagram: Enterprise User: Alice, Tenant A; Requirement: draft and reopen supplier email; No API, model adapter, or request store exists

Before diagram. Text alternative: Alice has a requirement; the platform has no implemented components.

The smallest useful outcome has four properties. A trusted identity identifies Alice. A server submits approved text to a model. The server saves the completed answer before reporting success. A later read returns only Alice’s own saved request.

2. The Customer Contract

Ask what Alice will do with the answer. She reviews and sends the email herself. The application neither sends messages nor makes procurement decisions. There are no internal document connectors, so it must not claim to answer questions from company policy or cite unavailable sources.

Before the formal contract, picture five moments in Alice’s workflow:

Supplier-email moment Name for the idea Guarantee and limit
Alice proves which account she uses; Bob still cannot open her saved draft Authentication identifies the caller; authorisation checks access Trusted code checks tenant and user on every history read; model text cannot grant access
Alice is willing to wait about five seconds for a saved draft Service-level objective (SLO) A measured target for a defined request population; a fast example does not prove it
Saving the answer and its completed label must agree Database transaction Local changes commit together or roll back; the separate provider is not inside that transaction
Alice double-clicks Submit after a network pause Idempotency Reusing the same scoped key can return the existing result; it does not guarantee one provider execution after every possible crash
Alice sees “saved” and expects to reopen the answer Acknowledgement boundary Report completion after the answer commit; partial or unsaved text is not a completed saved draft

The 95th percentile, or p95, is the latency threshold met by 95% of the measured requests. Counting timeouts and errors alongside latency prevents fast rejections from looking like success. The rest of the lesson makes these promises precise. Learn the consequence first, then use the formal term to explain your design.

Requirement Illustrative acceptance criterion Design consequence
Draft from supplied text One authenticated POST returns an answer and request ID Synchronous API with a model adapter
Reopen a draft A committed completed answer can be read by its owner Durable relational request history
Isolate history Tenant B cannot list or fetch Tenant A requests Trusted tenant/user predicates on every read
Stay responsive Healthy pilot p95 below five seconds Deadline hierarchy and measured latency breakdown
Bound spending Expected 1,200 input and at most 300 output tokens Provider token limits and usage counters in the real integration
Protect supplied text Only approved non-sensitive pilot text; credentials stay on server Explicit provider boundary, no prompt/token logging
Retain briefly Proposed 30-day history policy Deletion/backup policy must be implemented before a real pilot

The five-second value is a proposed service-level objective (SLO), a target measured over a defined population. It is not a promise this lesson has demonstrated. Define the pilot SLI, or service-level indicator, as elapsed time for valid authorised draft requests from server receipt to final response, with timeouts counted as failures. Track rejection rate separately so rejecting requests cannot make latency look healthy. Include user-side latency to detect network delays outside the server measurement.

The scope is one active pilot user, 200 requests during an eight-hour workday, and a brief 0.5 requests per second peak. Tenant B is a negative-test fixture, not a second launched customer. Confirm real demand, provider text handling, deployment region, and identity requirements before a pilot.

3. What This Module Covers

Topic Depth What you should be able to do
Requirements and architecture methodology Build depth Turn user outcomes into boundaries, alternatives, and failure tests
Estimation and capacity planning Build depth Compute demand and identify which limit the units describe
Networking fundamentals Design depth Locate DNS, connection, TLS, and HTTP failures on the path
APIs and streaming protocols Build depth Build/debug a request contract and defend JSON versus streaming
Database architecture Design depth Explain keys, indexes, transactions, and the external-call gap
End-to-end AI application design Build depth Implement the representative auth-to-model-to-history slice

No modules are revisited here.

Nearby concepts have narrower treatment:

Module Treatment here Where it is taught
Design documentation and communication Context only: use an ADR, without teaching a documentation portfolio T18.13, build depth
Gateway and service communication Context only: name an ingress role; do not teach service-to-service architecture T18.7, build depth
Identity and access control Context only: trusted caller scope and fixture checks T18.7, build depth
Background execution systems Deferred: no durable jobs or worker recovery T18.3, build depth
Document ingestion and indexing Deferred: supplied text only, no internal knowledge pipeline T18.4, build depth

Build depth means explaining, choosing, building a representative slice, observing failure, and mitigating it. Design depth requires architectural explanation and a small design exercise. There are no revisit modules in T18.2.

Before starting, be able to read basic Python, JSON, SQL, and HTTP. Stop at the MVP boundary. Defer retrieval, durable workers, caches, Kubernetes, GPU hosting, and advanced tenant scheduling until a requirement motivates them.

4. First Walk Through the Failure

Suppose the server calls the model and immediately sends Alice the text, then tries to save it. The database write fails. Alice saw a success, but reopening the request yields nothing. A model response alone has failed the customer contract.

Reverse the acknowledgement boundary. First insert a processing row and commit it. Then call the provider without an open database write transaction. After generation, update the row to completed with its answer and commit. Only then return a successful answer. If the final write fails, return a storage error; the earlier row may remain processing and need investigation.

This ordering creates a visible ambiguity: the provider might have generated and charged for an answer that the database never recorded. A database transaction cannot atomically include an independent hosted-model API. Preserve the request ID, avoid automatic retries, and make this gap explicit. T18.3 can later strengthen job recovery; this lesson does not claim exactly-once model execution.

Key Takeaways

  • The smallest useful outcome has four properties. A trusted identity identifies Alice, a server submits approved text to a model, the answer is saved before success is reported, and a later read returns only her own request.
  • Commit a processing row, call the provider with no database write transaction open, then commit completed with the answer. Only then return success, and return a storage error if the final write fails.
  • A database transaction cannot include an independent hosted model. A failed final write can leave an answer the provider generated and charged for but the database never recorded, so keep the request ID and do not retry automatically.
  • The five-second p95 is a proposed SLO for valid authorised requests from server receipt to final response, with timeouts counted as failures. Track rejection rate separately so fast rejections cannot make latency look healthy.

Rate your confidence and keep notes on the module page.