Back
Christof Jori

11 min read Β· 14 Aug 2026
Last reviewed

Next
Made on your device, with no Instagram connection. We copy the post link for Instagram’s Link sticker.

How to Productionise a Stateful LLM Platform Without Rewriting the Product

Stateful LLM platform production architecture is the set of boundaries that makes an AI application safe to operate repeatedly for several users. It covers authoritative data, identity, object access, expensive background work, external interfaces, deployment, recovery and verification. The model call is only one component inside that operating system.

This article owns one specific question: how do you move a feature-rich, stateful LLM application from local research use into a controlled shared pilot? It does not decide whether you need a knowledge graph, which is covered by our graph engineering decision guide. It also does not repeat the generic prototype-to-production checklist. The focus here is the dependency order for a platform that already has valuable product logic.

What makes a stateful LLM application different from a demo?

A demo can keep context in a browser session, reload fixtures from files and wait synchronously for a model response. A shared platform cannot. Users expect their data to survive a deployment, their permissions to apply through every interface and a long-running operation to remain understandable after a timeout, refresh or failure.

The starting application in this engagement already had substantial logic for structured domain data, graph operations, document ingestion, grounded conversations, interviews, simulations and evaluation. Its gap was not a missing feature list. The gap was operational ownership across the paths that connect those features.

Research-friendly assumptionShared-platform requirementFailure if left implicit
Files are the live stateOne authoritative transactional storeDeployments or concurrent users produce divergent data.
One trusted operatorServer-validated identity and object accessA valid user can reach another user's data.
The request waits for the modelOwned, observable and recoverable jobsTimeouts look like failures and retries duplicate work.
The browser is the only clientConsistent policy across browser, API and MCPA new interface bypasses assumptions enforced only in the UI.
A running process is healthyDependency-aware readiness and rollbackTraffic reaches an application that cannot serve correct results.
Manual testing proves the releaseAutomated checks plus representative flow QACross-layer regressions recur after every change.

The seven-layer productionisation sequence

The order matters. Polishing the interface before persistence and access control only makes unstable behavior easier to demonstrate. Adding an external API before central authorization creates a second security model. The programme therefore established each foundation before expanding the surface above it.

1. Define the operating envelope before choosing infrastructure

The target was a controlled initial release, not a claim of globally redundant enterprise infrastructure. That decision fixed the immediate acceptance criteria: a repeatable HTTPS deployment, persistent data, controlled onboarding, recoverable releases, useful logs and an explicit list of remaining scale and availability work.

This wording is more than risk management. It prevents architecture theatre. A single application task and a single-zone database may be reasonable for a design-partner pilot when their failure modes, backups and escalation paths are documented. They are not high availability. Naming the boundary lets the team buy the next reliability step when usage justifies it.

2. Move authoritative runtime state into PostgreSQL

The application had portable seed files and local data flows that were useful during research. Wavect retained those files as controlled bootstrap material while moving live subjects, ontologies, user records, organisations, access grants, sessions and machine credentials into PostgreSQL-backed stores.

The important design choice was ownership, not the database brand. Each domain received a store or repository contract, pooled connections and explicit create, read, update and delete behavior. Startup could seed an empty environment deterministically, but a running container no longer treated mutable files as the source of truth. Database integration tests then exercised the same persistence behavior the shared deployment used.

3. Centralize identity, tenant membership and object authorization

Authentication proves who sent a request. It does not prove that person may open a particular subject, graph or job. The platform therefore combined revocable server-side browser sessions, administrative roles, organisation membership and per-user object grants behind one access decision path. Browser routes, JSON APIs and external clients had to ask the same question.

This is the boundary described by OWASP API1:2023 Broken Object Level Authorization: every endpoint that receives an object identifier must verify that the logged-in user may perform the requested action on that object. UUIDs, a valid JWT or a hidden button do not replace that check.

The practical test matrix crossed roles, organisations, objects and transports. A regular user should not gain access by changing an identifier. An organisation administrator should remain inside that organisation. A revoked session or API key should stop working without waiting for a deployment.

4. Treat long-running LLM work as owned jobs

Document extraction, interviews, profile generation and simulations can outlive a normal HTTP request. Extending a web-server timeout reduces one symptom but does not answer who owns the work, whether a retry is safe or how the user learns what happened.

Wavect introduced a backend-independent job contract with typed states, handler registration, per-user concurrency limits, user-scoped idempotency keys, cooperative cancellation, stored results and errors, completion expiry and graceful shutdown. Polling endpoints provided a simple baseline. Server-Sent Events added application progress and heartbeat updates without making the browser connection the owner of the job.

Job propertyQuestion it must answerRelease evidence
OwnershipWhich authenticated user can observe or cancel it?Cross-user access tests fail closed.
IdempotencyWhat happens when the same action is submitted twice?The duplicate maps to one intended execution.
ProgressCan the user distinguish active, stalled, failed and complete?Polling and event paths expose the same state.
CancellationCan expensive work stop at a safe boundary?The handler cooperates and records the terminal state.
ShutdownWhat happens during a deployment?The queue drains or marks unfinished work for recovery.

An in-process executor was an intentional pilot trade-off, not the final scaling story. The contract made a later move to a durable queue possible without rewriting every product flow. The key is to separate the job lifecycle from the first backend that implements it.

5. Give browser, API and MCP access explicit security contracts

The external API was reorganised into modular route groups with shared dependencies, standard errors, scope checks, per-object authorization and throttling. Human sessions, JWTs and hashed API keys served different clients, but all of them converged on the same domain permissions. Administrative settings could disable external access for a specific object instead of exposing every capability by default.

MCP needs the same discipline. A tool call is not trusted because an agent initiated it. Identifier validation, read and write scope separation, rate limits and sanitized errors still apply. The current Model Context Protocol authorization specification requires resource-bound authorization requests and token audience validation. New integrations should follow the current protocol rather than copying the session or transport assumptions of an older implementation.

6. Make deployment health depend on the service users need

Infrastructure as code defined the network, container service, private database, load balancer, TLS, DNS, image registry, logs and permissions. A commit-triggered workflow built a versioned image, updated the service and waited for stability. The application health endpoint checked database connectivity, so a live process with an unavailable authoritative store did not count as ready.

Deployment controls need a failure action. AWS documents deployment circuit breakers and CloudWatch alarms as mechanisms that can detect failed ECS deployments and roll them back to the last known good state. In this programme, health-aware deployment and rollback were part of the release design, not an operator's improvised response.

7. Combine automated tests with repeated browser QA

Unit tests covered isolated graph, retrieval, grounding, safety and job behavior. A separate integration track used a real PostgreSQL service for persistence, authentication, API and MCP paths. That separation kept fast feedback fast without mocking away the boundaries most likely to fail in the shared environment.

Automation did not replace exploratory QA. Repeated browser passes exposed interaction failures across login expiry, selection state, long-running progress, graph editing, calculations, theme synchronization, errors and loading behavior. Each defect was fixed at the lowest stable owner, then covered by a regression check where practical.

This risk-ordered approach aligns with the NIST Secure Software Development Framework, which organizes secure development around preparing the organisation, protecting software, producing well-secured releases and responding to residual vulnerabilities. NIST explicitly frames the practices as an adaptable basis for risk-based improvement, not a universal checklist.

What evidence makes a controlled pilot credible?

Production readiness is not a binary property of the repository. It is a release claim supported by evidence across the operating envelope. For this class of platform, the minimum useful evidence set looks like this:

BoundaryEvidence before releaseResidual risk to state
DataPersistence and seed tests against PostgreSQL, plus a backup and restore procedureMigration and recovery maturity
AccessRole, tenant and object tests across session and token clientsAdministrative misuse and future policy growth
LLM jobsDuplicate, cancellation, timeout, error and shutdown behaviorProcess-local queue durability and capacity
External interfacesScope, rate-limit, invalid-input and sanitized-error testsProtocol evolution and third-party client behavior
DeploymentHealth-aware rollout, observable failure and tested rollbackSingle-task and single-zone availability
User journeysRepresentative browser flows with recovery from expired or partial statesUnseen combinations in a large interactive interface

Why incremental productionisation beat a rewrite

The existing application already encoded hard-won product behavior. A rewrite would have exchanged visible technical debt for hidden product regression risk. The faster path was to preserve validated flows, install stable ownership below them and repair defects against the new foundation.

That does not mean every old choice survived. File-backed runtime state stopped being authoritative. Access checks moved out of individual routes. Long work stopped belonging to a request. API dependencies became explicit. Shared interface patterns replaced local fixes. Incremental productionisation is selective replacement with an evidence trail, not endless patching.

If your product has the same shape, Wavect's AI enablement and architecture service covers evaluation, system boundaries, production hardening and handover. The anonymized analytics platform case study provides a separate example of stabilizing a complex data product without naming the client. For a wider keep-versus-rebuild decision, use the prototype-to-production guide, or request a production architecture review with your current operating constraints.

Stateful LLM platform production FAQ

What is a stateful LLM platform?
It is an AI application whose useful behavior depends on durable domain data, user or tenant identity, permissions, job state, history or connected records across requests. The model is one component; the platform must also own persistence, access, execution and recovery.
What should be productionised first in an LLM application?
Define the operating envelope first, then establish authoritative persistence and one authorization path. Background jobs, external APIs, deployment automation and wider interface QA depend on those foundations, so implementing them earlier creates duplicate state and policy models.
Should long-running LLM work stay inside an HTTP request?
Usually not when it can exceed normal request time, be retried, cancelled or observed after a refresh. Put it behind an owned job with explicit states, idempotency, progress, cancellation, result storage and shutdown behavior. The first backend can be simple if the contract allows later replacement.
How should an MCP server access platform data?
Treat MCP as another external interface. Validate identifiers, authenticate the client, bind tokens to the intended resource, enforce object permissions and read or write scopes, rate-limit calls and sanitize errors. Do not rely on an agent or client interface to enforce server-side policy.
Does a successful pilot mean the platform is highly available?
No. A controlled pilot can be production-like and useful with a narrower availability target. Document task count, database topology, queue durability, backup and recovery, rollback and incident ownership, then describe the release using that operating envelope rather than an unqualified production-ready label.
When is a rewrite justified?
A rewrite is justified when the core data model cannot express the product, safe coexistence is impractical or replacing the foundations costs less than repeatedly adapting them. Valuable product logic and user flows should be preserved unless evidence shows that their structure prevents safe operation.

Final thoughts

A stateful LLM platform becomes operable when every important state and authority has an owner. PostgreSQL owns durable runtime data. A central policy owns tenant and object access. The job layer owns expensive work. API and MCP routes reuse those decisions. Deployment health reflects real dependencies, and tests plus browser QA supply release evidence.

Keep the product behavior that users already value. Replace the foundations that cannot support shared operation. Most importantly, name the operating envelope honestly. A controlled pilot with explicit trade-offs is a stronger engineering result than an undefined production claim.

Production AI help

Building an AI product and worried about inference cost, architecture, or production readiness? Wavect helps founders turn AI prototypes into reliable production systems.

Explore the service path:

Inbox, without the noise

Follow the work that matters to you

Get a short email when we publish something new. Follow the whole blog or only the problems you care about.

What would you like to receive?
Choose your topics

Free, double opt-in, no tracking pixels.

Back
Christof Jori

11 min read Β· 14 Aug 2026
Last reviewed

Next

Get new posts by email

A short email when we publish. Free, no tracking.

Free, double opt-in, no tracking pixels.