Skip to content
Reviewed by Bipeen Sinha Nov 07, 2026

Home › Guides › MLOps projects

Tech Explained · 2026

MLOps Projects in 2026: 6 Portfolio Builds With Real Pipelines, Registries and Drift Alerts

MLOps projects are portfolio builds that prove you can run a model in production rather than only train one: experiment tracking, a model registry, CI/CD, containerised serving, drift monitoring and gated retraining. The 6 builds below run on free tiers, take 8 to 20 hours each, and answer one specific interview question.

7 November 2026·11 min read·By the 360 Digital Transformation Editorial Team
Key takeaways
  • Training is the small part. Fitting the model is roughly 8% of the hours; plumbing eats the rest.
  • The free tiers are narrow. GitHub's Free plan: 2,000 Linux Actions minutes a month on private repos, unlimited on public.
  • Hugging Face changed the rules. Per the Hub's docs, a Gradio or Docker Space now needs a paid plan.
  • Drift monitoring is the differentiator. Almost nobody builds it, which is why interviewers remember it.
  • Use aliases, not stages. MLflow deprecated registry stages from 2.9; the old call dates your project.

Your notebook gets 0.91 AUC. The number goes into a slide, the model goes to a colleague, and six weeks later somebody asks why the predictions look odd and nobody can say which dataset produced that 0.91. Closing that gap is the job.

What MLOps Projects Actually Need to Prove

Nobody screening for an operations role cares whether you know gradient boosting. They want three things: a result you can reproduce, a deployment you can reverse, and evidence you would spot a break first.

Take Meera, a 2021-batch Python developer in Pune who writes reporting scripts for a mid-size insurer and has 30 spare hours a month. She has trained plenty of models, and never stayed responsible for one.

Three numbers worth knowing before you start

Each changes a decision below, not just the framing.

2,000 min
Linux Actions minutes a month on GitHub's Free plan for private repos; public repos reported unlimited
16 GB
RAM on a free Hugging Face cpu-basic Space, which the Hub docs say sleeps at about 48 hours idle
45%
Rise in AI and ML hiring for FY26 per Naukri's JobSpeak index, against roughly 2% white-collar growth in September 2026

GitHub and Hugging Face figures from their published plan and Spaces docs; hiring figure from Naukri JobSpeak. Checked 7 November 2026.

The honest caveat

These projects will not, by themselves, get a fresher hired as an MLOps engineer. Most Indian MLOps job descriptions ask for three or more years of production experience, and no portfolio substitutes for having been paged at 2am. What they reliably do is move you sideways: reporting into data engineering, backend into platform work.

The Reference Architecture All 6 Projects Share

The loop every MLOps project is a slice of

The retrain path along the bottom is the one most portfolios never build.

Reference MLOps pipeline from raw data to a gated retraining loop Raw data feeds a feature job, then a training job, which logs runs to an MLflow tracking server and registry. A CI gate promotes a candidate version, which is built into a container image and deployed as an inference API. The API writes a prediction log, a drift monitor reads it hourly, and when drift crosses a threshold an alert reaches a human who approves a retrain, restarting the training job. Raw data store Feature job Training job MLflow tracking& model registry CI gatetests + metric check Container image Inference API Prediction log Drift monitor Alert + human gate nightly Parquet log run candidate passes gate deploy write row hourly window approved retrain Red boxes are the two stages most portfolios leave out.

Component names are the tools used in each build below, checked 7 November 2026.

Copy one decision: the retrain arrow passes through a human. Automatic retraining sounds impressive and is a trap, for a reason below. Promotion and rollback on a live Azure stack is the core of 360DT's MLOps Engineer course.

6 MLOps Project Ideas, With Stack, Dataset and the Interview Question Each One Answers

Pick by the gap in your CV. Never shipped anything, build 1 and 3. Already deploying at work, go straight to 4 and 6, which read as operations experience rather than tutorial completion.

Six builds, scoped

Each is a slice of the loop above, defending one claim on your CV.

1

Tracked training with a promotion gate

Log three runs, register the best, then attach a champion alias only if it beats the incumbent. The gate is the project, not the model.

Reproducibility
2

CI that blocks a bad model

Retrain on a fixed slice per pull request, compare against a committed baseline, fail on regression. Reviewers see a red X caused by a model.

CI/CD
3

Containerised inference, pinned by alias

A FastAPI service loading models:/churn@champion at startup and printing the resolved version in /healthz. Prove rollback: move the alias back, restart.

Serving
4

Drift monitoring with a real alert

Log predictions with their features, compare the last hour against the training distribution on a schedule, alert past a threshold. Poison a feature to show it firing.

Monitoring
5

Reproducible feature pipeline

Date-partitioned Parquet plus a manifest of row count, column hash and source commit. Re-run training on last Tuesday's partition, get identical features.

Data lineage
6

Gated automatic retraining

Wire build 4's alert to a training run that registers a candidate and promotes nothing. A human approves the alias move. Explaining why beats automating it.

Governance

Scoping reflects the stacks and free tiers verified on 7 November 2026.

Build Stack Dataset Hours The question it answers
1. Tracked training + gate MLflow, scikit-learn, SQLite UCI Bank Marketing 8 to 10 "When is a version safe to promote?"
2. CI that blocks a bad model GitHub Actions, pytest, baseline JSON Build 1's data, one slice 10 to 12 "What stops a worse model shipping?"
3. Containerised inference FastAPI, Docker, MLflow client None; serves build 1's model 10 to 14 "Walk me through a rollback."
4. Drift monitoring + alert Evidently or SciPy, cron, webhook Build 3's prediction log 14 to 18 "How would you know it had gone stale?"
5. Reproducible features DuckDB, Parquet, JSON manifest NYC TLC trip data 12 to 16 "Reproduce last month's number for me."
6. Gated retraining Builds 1, 2 and 4 wired together Nothing new 16 to 20 "Why would you not retrain automatically?"

On tooling I will commit: MLflow, not a hosted tracker. Not because it wins on features, but because a reviewer can clone your repo, run mlflow ui and see your runs without an account. You give up collaboration features that do not matter when the team is one person. The releases page lists MLflow 3.18.0, published 4 November 2026, so pin the minor version.

Also read: if you have nothing trained yet, start with Machine Learning Projects for Beginners 2026 and come back with a model in hand.

Project 1 Walkthrough: From a CSV to a Promoted Model Version

The full build, with the output at each step. Meera does this on a Saturday afternoon, locally, no cloud account.

Step 1: a tracking server you can point someone at

python -m venv .venv && source .venv/bin/activate
pip install "mlflow==3.18.0" scikit-learn pandas pyarrow

# The registry needs a database backend. The default file
# store will refuse to register a model.
mlflow server \
  --backend-store-uri sqlite:///mlflow.db \
  --default-artifact-root ./mlruns \
  --host 127.0.0.1 --port 5000

Step 2: log three runs, register one

Open http://127.0.0.1:5000 and you should see an empty experiment list. The point of the loop below is not the sweep: each run records its parameters, its metric and a hash of the input, so the registered version traces back to data.

import hashlib, json, mlflow, pandas as pd
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score

mlflow.set_tracking_uri("http://127.0.0.1:5000")
mlflow.set_experiment("churn")

df = pd.read_csv("bank.csv", sep=";")
y = (df.pop("y") == "yes").astype(int)
X = pd.get_dummies(df, drop_first=True)
data_hash = hashlib.sha256(pd.util.hash_pandas_object(X).values).hexdigest()[:12]

Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.2,
                                      stratify=y, random_state=42)

best = (None, -1.0)
for depth in (2, 3, 5):
    with mlflow.start_run(run_name=f"gb-depth-{depth}") as run:
        model = GradientBoostingClassifier(max_depth=depth, random_state=42)
        model.fit(Xtr, ytr)
        auc = roc_auc_score(yte, model.predict_proba(Xte)[:, 1])

        mlflow.log_params({"max_depth": depth, "n_features": X.shape[1]})
        mlflow.log_metric("roc_auc", auc)
        mlflow.set_tag("data_sha256_12", data_hash)
        mlflow.sklearn.log_model(model, name="model")

        print(f"depth={depth} auc={auc:.4f} run_id={run.info.run_id}")
        if auc > best[1]:
            best = (run.info.run_id, auc)

mlflow.register_model(f"runs:/{best[0]}/model", "churn")
json.dump({"roc_auc": best[1], "data_sha256_12": data_hash},
          open("baseline.json", "w"), indent=2)
print("registered from run", best[0], "auc", round(best[1], 4))

Expected output: three depth=... auc=... lines, then a registered-model line naming version 1. Write down your AUC: it is the baseline build 2 defends.

Step 3: the promotion gate, which is the actual project

Registering a version is not promotion. Promotion is a deliberate act with a condition attached, and this is where most portfolios stop.

from mlflow import MlflowClient

client = MlflowClient(tracking_uri="http://127.0.0.1:5000")
TOL = 0.005   # allow this much noise, no more

candidate = max(client.search_model_versions("name='churn'"),
                key=lambda v: int(v.version))
cand_auc = client.get_run(candidate.run_id).data.metrics["roc_auc"]

try:
    champ = client.get_model_version_by_alias("churn", "champion")
    champ_auc = client.get_run(champ.run_id).data.metrics["roc_auc"]
except Exception:
    champ_auc = None

if champ_auc is None or cand_auc >= champ_auc - TOL:
    client.set_registered_model_alias("churn", "champion", candidate.version)
    print(f"promoted v{candidate.version} ({cand_auc:.4f})")
else:
    print(f"BLOCKED v{candidate.version}: {cand_auc:.4f} "
          f"below champion {champ_auc:.4f}")
    raise SystemExit(1)

Use aliases, not stages. MLflow's tracking issue says registry stages were deprecated from 2.9 with removal planned for a later major release, so calling transition_model_version_stage in 2026 says you learned this from a 2022 tutorial.

Now make it demonstrable: rerun step 2 with max_depth=1 so the metric drops, run step 3, screenshot the BLOCKED line and its non-zero exit. That beats any diagram in your README.

What usually goes wrong here

Two things, every time. You forget the SQLite flag, get a cryptic registry error, lose twenty minutes. Then your installed versions drift from what MLflow logged beside the model, and load_model fails on a pickle from a different scikit-learn minor. Pin it now.

Building a CI/CD Pipeline for Machine Learning on 2,000 Free Minutes

A CI/CD pipeline for machine learning differs from an ordinary one in one way: what can regress is a number, not a test. The rest is normal continuous integration, so DevOps habits transfer.

The budget matters. GitHub's Free plan includes 2,000 Linux Actions minutes a month on private repositories and reports public ones as unlimited on standard runners, with Windows counting double and macOS tenfold. GitHub also cut per-minute runner rates on 1 January 2026 by up to 39% by machine type, which hits overage, not the quota. Make the repo public if you can.

# .github/workflows/model-ci.yml
name: model-ci
on:
  pull_request:
    paths: ["src/**", "requirements.txt", "baseline.json"]

jobs:
  guard:
    runs-on: ubuntu-latest
    timeout-minutes: 12          # a runaway fit will not eat the month
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-python@v6
        with:
          python-version: "3.12"
          cache: pip
      - run: pip install -r requirements.txt
      - run: pytest -q tests/test_features.py
      - name: Train on the pinned slice
        run: python src/train.py --slice data/ci_slice.parquet --out metrics.json
      - name: Fail if the metric regressed
        run: |
          python - <<'PY'
          import json, sys
          new = json.load(open("metrics.json"))["roc_auc"]
          base = json.load(open("baseline.json"))["roc_auc"]
          print(f"candidate {new:.4f} vs baseline {base:.4f}")
          if new < base - 0.005:
              sys.exit(f"REGRESSION: {base - new:.4f} below tolerance")
          PY
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: metrics
          path: metrics.json

Two details matter. timeout-minutes stops a hung job eating your month over a weekend, and if: always() keeps the metrics from failed runs. Workflow design at this level is drilled hands-on in 360DT's AWS DevOps programme and the AZ-400 track.

Where the hours actually go on build 1

Budget for the model and not the plumbing, and you overrun threefold.

Wiring the pipeline, config and paths35%
Debugging environments and dependency pins25%
Monitoring, alerts and the metric gate20%
README, screenshots and the demo recording12%
Training the model8%

Our scoping budget for live cohorts, not a published benchmark. Checked 7 November 2026.

Pick your deploy target before you write the Dockerfile

This trips people up right now. Per the Hub's Spaces documentation, Gradio and Docker Spaces run on compute and require a paid plan to create: PRO for a personal account, Team or Enterprise for an organisation. Free accounts in good standing get two ZeroGPU Gradio Spaces, Static Spaces stay free, and a free cpu-basic Space gives 16 GB RAM and 2 vCPU before sleeping at about 48 hours idle. Check your tier today.

Also read: if the Dockerfile is the part you are least sure of, work through Docker Tutorial for Beginners 2026 before build 3.

Model Drift Monitoring: The Project That Separates You From Everyone Else

Here is the asymmetry worth exploiting. Thousands of portfolios contain a deployed model. Almost none show the author would notice it going wrong. Build this one first if you build only one.

It is research territory rather than a solved tooling problem. Carnegie Mellon's Software Engineering Institute runs a project on predicting changing conditions in production ML systems and publishes Portend, an open source toolset that simulates drift and works out which metrics detect it.

The mechanics are simpler than the theory. Population Stability Index over quantile bins:

import numpy as np, pandas as pd

def psi(expected: pd.Series, actual: pd.Series, bins: int = 10) -> float:
    """PSI over quantile bins of the training distribution."""
    edges = np.unique(np.quantile(expected.dropna(), np.linspace(0, 1, bins + 1)))
    edges[0], edges[-1] = -np.inf, np.inf
    e = np.histogram(expected, bins=edges)[0] / len(expected)
    a = np.histogram(actual, bins=edges)[0] / len(actual)
    e, a = np.clip(e, 1e-6, None), np.clip(a, 1e-6, None)
    return float(np.sum((a - e) * np.log(a / e)))

train = pd.read_parquet("features/train.parquet")
live  = pd.read_parquet("logs/predictions.parquet")
live  = live[live.ts >= live.ts.max() - pd.Timedelta("1h")]

alerts = {c: round(psi(train[c], live[c]), 3)
          for c in ("age", "balance", "duration")
          if psi(train[c], live[c]) > 0.2}

if alerts:
    print("DRIFT", alerts)          # post this to a webhook
else:
    print("stable", len(live), "rows")

Conventionally PSI under 0.1 is stable, 0.1 to 0.25 deserves a look, above 0.25 is a real shift. I use 0.2 because at portfolio volumes an hour of traffic is small enough that you want telling early. A threshold you can justify beats a textbook one you cannot.

To demonstrate it, poison a feature: add 15 years to every age in your request generator and capture the alert. For a dashboard, a Power BI report over the prediction log is fastest, and that modelling sits in 360DT's PL-300 course; the generative equivalent is in the AI Engineer course.

Also read: MLOps vs DevOps in 2026 if you are still deciding which of the two ladders to climb.

Where These MLOps Projects Go Wrong

The retraining loop

A practitioner write-up updated in March 2026 describes a pipeline that retrained whenever any drift detector fired. One Tuesday morning the whole thing went into a retraining loop, because the model's own predictions were feeding back into its training features. That is the argument for build 6's human gate, and a better interview answer than "I automated retraining".

Symptom What is actually happening The fix
Registry calls fail with an unsupported-backend error MLflow is on the default file store, which has no registry Start with --backend-store-uri sqlite:///mlflow.db
load_model raises a pickle error weeks later scikit-learn minor drifted between train and serve Pin exact training versions and reuse the same requirements file
CI passes but the deployed model is the old one The container pinned a version number, not the alias Load models:/name@champion and restart on promotion
Drift alert fires constantly on day one Window too small, so an hour of traffic is noise Require a minimum row count, and widen the window
Actions minutes exhausted mid-month Scheduled training on a private repo, or no timeout Add timeout-minutes or make the repo public

Two things to deliberately not build. Not Kubeflow: a weekend of cluster plumbing a reviewer never sees. Not a feature store, because a dated Parquet partition with a manifest proves the same point in an afternoon. Learn Kubernetes separately, as infrastructure, which is how the 360DT certifications overview sequences it.

How to Sequence the Builds, and What to Learn Alongside

Order matters more than selection: builds 2, 3, 4 and 6 all consume artefacts build 1 produces. Out of order, you rebuild the registry three times.

Build 1 first, in one sitting if you can. Then build 3, because a running service makes the loop observable and the rollback demo is the most quotable thing you will own. Build 2 third, once you have a baseline worth defending. Build 4 fourth and slowly, because that is the deep one. Build 5 for data engineering interviews, 6 last.

What to pair with MLOps portfolio projects

The projects teach the loop, not the cloud primitives underneath, and that is the gap interviewers probe second. Study two things alongside: managed orchestration on a real cloud, since local Docker teaches you nothing about compute quotas or managed identities, and pipeline work, because build 5 is a data engineering problem wearing an ML hat, which is why the Microsoft Fabric track overlaps so heavily with MLOps hiring. For generative systems, evaluation architecture is first-class in the CCAR-F prep.

If I were Meera, I would build 1 and 3 this month, put the rollback demo at the top of my CV and start interviewing rather than waiting for all six. Interviews tell you which of the remaining four to build, and that beats another month of unguided work. For the same loop with an engineer reviewing your pipeline, the live MLOps Engineer course mapped to AI-300 and CCAR-F runs weekends; a free webinar is the cheaper way to check the pitch.

Live course

Build the whole MLOps loop with an engineer reviewing your pipeline

Live online·Sat–Sun, 8–11 PM IST·50+ hrs·Rs 24,999

Eight weeks of live weekend sessions on registries, deployment, monitoring and retraining, mapped to the Microsoft AI-300 and Claude CCAR-F exams. You build and defend the pipeline rather than watch one.

Explore the course
MLOps Engineer Course: Azure AI-300 + Claude CCAR-F

Frequently asked questions

What are the best MLOps projects for a portfolio in 2026?

A tracked training run with a promotion gate, a containerised service that rolls back by moving an alias, and a drift monitor that fires a real alert. Those three cover what operations interviews test.

How long does an MLOps project take to build?

Between 8 and 20 hours each. Roughly a third goes on wiring, a quarter on dependency debugging, under a tenth on training. All six is about four months at 30 hours a month.

Can I do MLOps projects without a GPU?

Yes, and you should. Every build here runs on a laptop CPU with tabular data, because the subject is the pipeline. Keep a full retrain under two minutes so CI stays inside the free allowance.

Do I need Kubernetes for an MLOps project?

No, and for a portfolio I would avoid it. One container with a pinned model alias shows the same deployment and rollback thinking in a fraction of the time.

Is MLflow free to use?

Yes. It is open source and self-hosted with no account required, and the releases page lists 3.18.0 published on 4 November 2026. One catch: the registry needs a database backend, so use SQLite or Postgres.

Can a fresher get an MLOps job with projects alone?

Rarely, and it is worth being clear about that. Most Indian MLOps openings ask for several years of production experience. What the projects open up is the adjacent moves.

About this guide. 360 Digital Transformation is an Anthropic Partner and a Microsoft Authorized Training Partner. Other certification bodies, vendors and employers named here are not affiliated with us. Tools and versions change quickly; commands and figures cited were checked on 7 November 2026.

Learn it live with 360 Digital Transformation

Turn this guide into a skill employers can see

Live weekend cohortEMI available

AI Engineer Course: Generative AI, RAG & AI Agents (Microsoft + Claude Certified)

Rs. 27,999Rs. 37,239 Save 24%

Tools and platforms you work with

  • Python
  • Claude API
  • FAISS
  • ChromaDB
  • LangChain
  • LangGraph
  • CrewAI
  • AutoGen (AG2)
Add bonus modules
See the syllabus and batch dates

Other live courses on this career path