, ,

Data Science Platform Architecture, a Reference Design With Trade Offs Named (Data Science Series, Part 27)

A finance director asked why a four day model took eleven weeks to reach a customer, and almost every answer turned out to be architectural. Here is the four plane reference design I would build today, with the cost and operations trade offs named in real numbers.

Data Science Series · Part 27 of 30

Key takeaways

A data science platform is four planes: data, feature, model and serving. Most outages and most delays live in the handoffs between planes, not inside any one of them.

Build versus buy is a question about how many teams share a component and what its annual floor costs. It is not a question about engineering pride.

Assembling our churn platform from open components cut the monthly bill by 60 percent and nearly tripled the operations hours it consumed. Both numbers are real. Somebody has to say out loud which one your organisation can afford.

Portability lives in two artefacts: feature definitions and the registry contract. Keep those in your own repository and almost every other choice becomes reversible.

Access control is a design input. Retrofitting it into a platform that already serves live traffic costs several times what building it in would have.

Why does it take eleven weeks to put a model in front of a customer when the model itself took four days to build. That question came from a finance director, not from an engineer, and it was the most useful sentence anyone said to me that quarter. She was not asking about algorithms. She was asking why the distance between a working notebook and a served prediction was roughly fifteen times the distance to the working notebook.

Almost every honest answer to her question was architectural. Nobody owned the path from a warehouse table to a feature that a live endpoint could read in single digit milliseconds. Nobody had decided whether training data came from a snapshot or a query. Six of those eleven weeks were spent rebuilding, in a serving language, transformations that already existed in a notebook. A platform is what removes those weeks, and this part is a design for one.

Who this is for: someone who is being asked to design the platform rather than use it, or a senior data scientist about to be handed that job. Assumed starting point: you have shipped at least one model to production yourself, you understand what a feature store solves (Part 23), what a model registry records (Part 24) and what a retraining pipeline looks like (Part 26). You are now making choices that other people will live inside for three years. No code in this part, because none of these decisions are made in code.

Planes of a data science platform

Where the churn project stands: Part 26 left us with a pipeline that can retrain a model, compare it against the incumbent and block a merge when quality drops. What we have never described is the machinery that pipeline runs on. Everything so far assumed a warehouse existed, a registry existed, an endpoint existed. This part names each of those and says what I would choose.

Splitting a platform into planes is not decoration. A plane is a boundary that one team can own, one budget can fund and one contract can describe. Draw the boundaries badly and you get the eleven week problem, where a change to a feature requires coordinated edits in four repositories owned by three teams. Draw them well and a data scientist can add a feature, retrain, and promote without filing a ticket.

flowchart LR subgraph DP[Data plane] A[Warehouse tables] B[Snapshot storage] end subgraph FP[Feature plane] C[Feature definitions in Git] D[Offline store] E[Online store] end subgraph MP[Model plane] F[Training jobs] G[Experiment tracking] H[Model registry] end subgraph SP[Serving plane] I[Batch scorer] J[Real time endpoint] K[Monitoring] end A --> C B --> C C --> D C --> E D --> F F --> G G --> H H --> I H --> J E --> J I --> K J --> K
Four planes and the seams between them. Every arrow crossing a subgraph boundary is a contract somebody has to own.

Count the arrows that cross a boundary in that diagram. There are six. Those six are the entire surface area of your platform contract, and in my experience they account for most incidents. A schema change in the warehouse silently alters a feature. A registry promotion lands a model whose input signature no longer matches what the endpoint sends. Nothing inside a plane broke. A seam did.

Ownership of those seams is worth settling on a whiteboard before anyone writes a line of infrastructure. My preference is that each contract has exactly one owning team and one written expectation, phrased as something measurable: this table is refreshed by 04:00 with a row count within 5 percent of yesterday, this online store answers a batch of twenty entity keys under 60 milliseconds at p99, this registry alias only ever points at a version that passed the merge gate. Vague ownership produces a specific failure mode I have watched three times now. During an incident, two teams each believe the other is investigating, and the first forty minutes are spent establishing that nobody is. A one line contract per seam removes that entirely, and costs an afternoon.

Data plane decisions that lock you in

Start here, because this is the layer you will not get to change. Compute engines get swapped every few years without much drama. Storage layout and the modelling conventions on top of it outlive three generations of tooling, which is why a clean dimensional model is worth more to a machine learning platform than most people building one expect. If that phrase is unfamiliar, it means organising warehouse tables around business entities and events rather than around whatever the source system emitted, and the analyst series covers it properly in data modeling basics for analytics.

Two decisions matter more than the rest. First, whether training reads a query or a snapshot. A query is convenient and quietly non reproducible, because the underlying table keeps changing beneath you. A snapshot written to object storage with an immutable path costs storage and buys you the ability to rebuild a model exactly, eighteen months later, when a regulator asks. I take the snapshot every time. Storage is the cheapest thing in the diagram.

Second, whether point in time correctness is enforced by the platform or left to individual notebooks. Point in time correctness means a training row only ever sees feature values that existed at the moment being predicted, and it is the single most common source of leakage in a churn model. Left to individuals, it is done correctly by roughly half of them. Enforced in the feature layer, with an event timestamp on every source and an as of join at retrieval, it is done correctly by all of them. That is not a tooling preference, it is a correctness argument, and it is why the feature plane exists at all.

Feature layer, build or buy

Every platform review I have sat in eventually stalls on this one, so let me give the decision rule I actually use before giving the reasoning. Buy when three or more teams will share the component and a managed option meets your latency target at an annual floor under about fifteen percent of the platform budget. Build the thin version otherwise. The rule sounds arbitrary until you have paid an annual floor that dwarfed your usage.

flowchart TD A[New platform component] --> B{Three or more teams share it} B -->|no| C[Build the thin version] B -->|yes| D{Managed option meets latency target} D -->|no| E[Build, and fund the on call rota] D -->|yes| F{Annual floor under 15 percent of budget} F -->|no| C F -->|yes| G[Buy, keep definitions portable]
Decision rule I apply to every platform component, not only the feature layer.
War story: I signed off a fully managed feature platform for a team of four data scientists running exactly eleven feature views. It was the safe choice on paper and it was wrong. Seven months in, the line item was 4,100 US dollars a month against a workload that a single Postgres instance could have absorbed. We migrated to open feature definitions with a scheduled materialisation job into Postgres. Cost for that layer fell to 260 dollars a month. The p99 online read went from 41 milliseconds to 56, which nobody noticed, and our operations load for that layer went from about 2 hours a month to 6, which everybody noticed. Migration took nine working days, almost all of it re expressing feature definitions that should have been portable from the start.

Two lessons came out of that, and only one of them is about money. Keep feature definitions in your own repository as declarative objects, whatever engine executes them. Open source Feast is designed around exactly this split, with an offline store for building training sets and an online store holding only the latest value per entity key, and the definitions sit in your code either way. When the definitions are portable, changing the engine is a nine day job. When they live in a vendor console, changing the engine is a rewrite, and you will not do it, which is precisely what the pricing model assumes.

Orchestration and training layer

Orchestration attracts more architectural argument than it deserves. A scheduler runs jobs in an order, retries them, and tells you when one failed. Airflow does that, and version 3.3.0 landed in July 2026 with a coordinator layer that lets individual tasks run outside Python while the scheduling logic stays in Python, which removes the main reason teams used to reach for something else. My verdict: use the orchestrator your data engineering team already operates, and spend the argument you saved on the model registry contract instead.

Registry design deserves that attention because it is where deployment gets its meaning. MLflow models are addressed as a URI, and an alias gives a mutable pointer at a specific version, so a production service targets a name and an alias rather than a version number. Promotion then becomes a single act of moving that alias, fully audited, reversible in seconds. Serving code never learns a version number, which means a rollback is not a deployment. I would avoid any design where the endpoint hardcodes a version, because every rollback becomes a release, and releases at three in the morning are how good models get replaced by bad ones.

PlaneDefault I would pickAlternativeTrade off you are accepting
DataWarehouse you already run, plus immutable snapshotsLakehouse on an open table formatSnapshot storage cost against reproducibility you can defend in an audit
FeatureOpen definitions, Postgres or Redis online storeManaged feature platformAround 15 ms extra p99 and 4 more operations hours a month, for roughly a 15x cost cut
ModelMLflow tracking and registry, aliases for promotionVendor native registry tied to the compute platformYou run the tracking server yourself, and keep the option to move compute
OrchestrationWhatever data engineering already operatesA second, machine learning specific schedulerLess tailored to model workflows, far fewer on call rotas to staff
ServingContainer behind an autoscaler, batch by defaultFully managed endpoint per modelYou own scaling policy and cold starts, and you can colocate models on one node
MonitoringModel metrics into the observability stack you already page fromDedicated machine learning observability productWeaker drift visuals, but alerts reach a human who is actually on call
Defaults for a platform serving one to five model teams. Above roughly ten teams, several of these flip toward the managed column.

Serving layer sizing

Most churn models do not need a real time endpoint, and building one anyway is the most common overspend I see. If a retention team acts on a churn score once a week, a nightly batch write into the warehouse and the customer relationship system serves them perfectly, at a fraction of the cost and with none of the availability obligations. Part 22 walked through that choice in detail. Architecturally, the rule I hold to is that latency requirements come from the action, never from the model.

Where real time genuinely applies, such as scoring a churn risk at the moment a customer opens a cancellation page, the design constraint is not model inference. Inference on a gradient boosted churn model runs in low single digit milliseconds. Feature retrieval is the expensive half, and the diagram below is the contract that keeps it honest.

One definition, two stores, two consumersAny path that bypasses the shared definition is where training serving skew entersFeature definitionsversioned in GitOffline storefull history, as of joinsOnline storelatest value per entityTraining jobServing endpointsame values, or you have skew
Feature definitions are the portable artefact. Stores and consumers are replaceable around them.

Sizing follows from that picture. Budget your latency by hop, not in aggregate. On our churn endpoint the split was roughly 6 milliseconds of network, 41 of feature retrieval, 3 of inference and 38 of the surrounding application, for an 88 millisecond p99. Anyone attacking that number by making the model smaller would have been optimising 3 percent of the total. Naming the hops before you tune is what stops that.

One serving decision that repays thinking about early is whether models get their own container each or share one. A container per model is cleaner to reason about and is what most managed platforms sell you. It also means every model pays for its own idle capacity, and with four models at modest traffic we were paying for roughly 3.5 idle replicas at all times. Colocating those four behind a single process, loading each from the registry at startup and routing on a path segment, took our serving line from 1,600 to 1,150 dollars a month without touching latency. What it cost was blast radius: a bad model version now takes down four endpoints instead of one. I accept that trade below about five models and reject it above ten, because past that point the isolation is worth more than the idle capacity, and a single deployment holding a dozen models becomes something nobody wants to be paged for.

Cost and operations trade off, with real numbers

Platform posts that compare architectures almost never show a bill, so here is ours. Same churn workload, same team of four, measured across two consecutive quarters. Left hand column is the fully managed stack we started on. Right hand column is the assembled stack we moved to. I have included operations hours because a cost comparison that omits them is dishonest.

Monthly platform cost by componentChurn workload, four data scientists, US dollars per monthmanaged stackassembled400020000Feature4100260Warehouse28002100Orchestration900340Serving16001150Registry750180Total: 10,150 per month managed, 4,030 assembled, a 60 percent reductionOperations load over the same period: 6.5 hours a month, rising to 18
Cost fell by 60 percent. Operations hours nearly tripled. Only one of those two numbers usually reaches a steering committee.
ComponentManaged, USD per monthAssembled, USD per monthp99 readOps hours per month
Feature layer4,10026041 ms to 56 ms2 to 6
Warehouse compute2,8002,100not applicable1 to 1
Orchestration900340not applicable1 to 4
Serving1,6001,15088 ms to 96 ms2 to 5
Tracking and registry750180not applicable0.5 to 2
Total10,1504,030slightly slower6.5 to 18
Two quarters of measured figures on one workload. Treat them as a shape, not as a quote for your own environment.

My take on the numbers

Eleven and a half extra operations hours a month is roughly 0.07 of a full time engineer, and we bought them for 6,120 dollars a month. On that arithmetic the assembled stack wins comfortably, and it did for us. Flip one variable, though, and it reverses. If your team has no platform engineer, those hours come out of modelling time at the worst moments, usually during an incident, and the managed stack is the right answer even at three times the price. Decide who carries the pager before you decide what to buy.

Governance built in from day one

Access control is treated as a phase two item on most platform plans I review, and phase two rarely arrives. Retrofitting it is expensive for a structural reason: once feature views, training jobs and endpoints exist without any notion of an owner, adding one means editing every object and negotiating with every consumer. Feast added role based access control as a first class part of its architecture rather than as a wrapper, and the reason is exactly this. Ownership belongs in the object model.

Three things I would build in from the first sprint, and no more than three, because governance scope creep kills platforms too. Every feature view carries an owner and a data sensitivity label. Every registered model version carries the snapshot identifier it trained on, which the registry already supports through lineage back to the producing run. Every promotion writes an audit entry naming a human. That set is small enough to build in a week and sufficient to answer the three questions an auditor asks: who owns this, what did it learn from, and who approved it going live. Part 29 goes considerably further into model risk, but a platform without those three fields cannot support anything Part 29 describes.

In practice: attach the sensitivity label at the feature view rather than at the column. A churn model that reads a payment failure count inherits the payment system sensitivity automatically, and the endpoint that serves it inherits the same. We found four features carrying customer identifiers into a model output that was being written to a shared warehouse table, and we found them by querying labels, not by reading code. That query took under a minute and would have been impossible without the labels being mandatory at creation time.

Reference architecture I would build today

For a team of two to six data scientists shipping a handful of models, of which our churn project is a fair example, here is the concrete answer. Warehouse you already run, with immutable training snapshots in object storage. Feature definitions declared in your own repository, materialised on a schedule into Postgres, with a managed key value store only once read volume genuinely demands it. MLflow for tracking and the registry, promotion by alias so a rollback never becomes a release. Orchestration on whatever your data engineers already operate. Batch scoring by default, a real time endpoint only where the action that consumes the score happens in a session. Model metrics into the observability stack that already pages someone.

What I would avoid, stated plainly: a second orchestrator bought specifically for machine learning, a managed feature platform below roughly three consuming teams, and any serving design where a version number is hardcoded outside the registry. Each of those looks like sophistication in a design review and reads as an unfunded liability eighteen months later.

One last note on sequencing, which the finance director inadvertently taught me. Build the seams before you build the planes. A platform with a mediocre feature store and a clean contract between training and serving outperforms a platform with an excellent feature store and no contract at all, because the first one can be improved a piece at a time and the second one can only be replaced. Part 28 takes the same architecture and sizes the compute underneath it, which is where the next order of magnitude of cost sits. If you are designing a platform this quarter, write down your six boundary contracts before you write down a single product name, and see how many of them you can already describe precisely.

Data Science Series · Part 27 of 30
« Previous: Part 26  |  Guide  |  Next: Part 28 »

References

About The Author


Discover more from Journal of Intelligent Infrastructure – By Dr Pranay Jha

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

Architect’s Toolkit

About the Author

Dr. Pranay Jha is a Cloud and AI Consultant with 18+ years of experience in hybrid cloud, virtualization, and enterprise infrastructure transformation. He specializes in VMware technologies, multi-cloud strategy, and Generative AI solutions. He holds a PhD in Computer Applications with research focused on Cloud and AI, has published multiple research papers, and has been a VMware vExpert since 2016 and a VMUG Community Leader.

Discover more from Journal of Intelligent Infrastructure - By Dr Pranay Jha

Subscribe now to keep reading and get access to the full archive.

Continue reading