Inspiration

In Lagos, mobile data is bought up front, by the gigabyte (we price it at ₦500/GB, an MTN 7 GB bundle). Every kilobyte a web app ships is paid for by the people who visit it. But bundle growth is invisible at review: an eager import lands, and weeks later someone notices in a dashboard. Green-CI tools measure the pipeline's own grams; nobody shows the cost to visitors, on the merge request, before merge.

What it does

Data Diet is a GitLab merge request gate plus a GitLab Duo flow.

  • On every MR it builds the target branch and the MR, loads the same journey (data-journey.json) in Chromium on the DevTools 3G preset, and compares every byte transferred.
  • If the MR makes a visit heavier than a 1 kB noise allowance, the job fails. Source maps and the lockfile trace the growth to the exact line, and it is priced: ₦ per 1,000 visits, extra seconds on 3G, g CO₂e (network transfer only).
  • Results land in GitLab's own MR widgets (test summary, Code Quality, Metrics) and in a self-contained Data bill page with a calculator for your own traffic and data price.
  • A "Pipeline failed" trigger starts a Duo custom flow (diagnose → fix → watch). It reads report.json, pushes one fix commit as its own service account, and follows the next pipeline. If it can't fix it, it posts on the MR and opens a "needs a human" issue.
  • A guard job keeps the agent on a leash: agent commits touching CI, .gitlab/, tests or scripts fail; one fix attempt per human push.

Results (every number links to a pipeline)

  • Weekend Markets, MR !2: eager html2canvas import blocked at +46.9 kB per visit, naming ShareMarket.tsx:3. The flow pushed a lazy import (b18765af); the gate passed it at +0.5 kB (pipeline).
  • A second project, MR !2: eager Chart.js import blocked at +70.0 kB; the flow template, registered with a Pipeline-failed trigger, pushed 576247b and the gate passed at +0.3 kB (pipeline), with no human step after the push.
  • AriaNg (open source): five real release pairs, 1.3.10 → 1.3.15, all passed at 518.2–518.4 kB per visit, no false blocks (job).
  • A live Data bill and the landing page.

How we built it

TypeScript on Node, Playwright/Chromium for measurement, GitLab CI/CD components (data-budget, guard), a GitLab Duo Agent Platform custom flow with a Pipeline-failed trigger, and Google Cloud Run for the live app and per-MR preview deployments (Workload Identity Federation, no keys in CI). 214 automated tests cover the gate, the report and the guard.

Challenges

  • Measurement noise: we measured unchanged builds repeatedly to set the 1 kB allowance.
  • Attribution: mapping transferred bytes back to the source line through source maps and lockfile changes, including cached repeats and renamed chunks.
  • Keeping an autonomous agent safe: the guard reads only git history, needs no API token, and caps the agent at one attempt per human push.

Honest limits

  • Both projects where the agent fixed an MR are ours, not outside users.
  • CO₂e covers network transfer only; the naira figure uses one cited bundle price (the Data bill calculator takes your own).
  • On the second project, one pipeline started the flow three times (also on a passing pipeline); the extra sessions posted "no fix to make" and committed nothing. We have not found the cause yet.

What's next

Ship the components on the CI/CD Catalog, per-route budgets, and more data tariffs beyond Nigeria.

Built With

Share this project:

Updates

Submission history