cd /news/artificial-intelligence/how-i-built-a-carbon-footprint-track… · home topics artificial-intelligence article
[ARTICLE · art-37984] src=dev.to ↗ pub= topic=artificial-intelligence verified=true sentiment=↑ positive

How I Built a Carbon Footprint Tracker with Django + NVIDIA NIM

A developer built Carbon.Ledger, a full-stack Django web app that logs user activities, computes CO₂ impact using database-stored emission factors, and provides AI-powered reduction tips via NVIDIA NIM's Mistral Large model. The app features a hallucination guard that checks LLM-generated numbers against provided context to prevent misinformation, and uses htmx for dynamic dropdowns without custom JavaScript. Deployed on Render, the project highlights the importance of separating LLM text generation from data calculations.

read3 min views1 publishedJun 24, 2026

I wanted to build something that mattered. Climate change is one of those topics where awareness is the first barrier — most people don't know their actual footprint. So I built Carbon.Ledger: a full-stack web app that lets you log activities, see your CO₂ impact, and get AI-powered tips to cut back.

Here's how I built it, what went wrong, and the one engineering decision I'm most proud of.

mistralai/mistral-large-3-675b-instruct-2512

The app is built around one simple loop:

Understand → Track → Reduce

Users can read lesson articles, browse a glossary (CO₂e, Scope 1/2/3, Net Zero), and ask free-text climate questions via an LLM-powered Q&A — rate limited to 10 questions/day.

An activity logging form lets users log transport, energy, food, and goods. CO₂ is auto-computed on save using emission factors stored in the database — no LLM involved here. The dashboard shows a 30-day breakdown with a Chart.js donut chart and progress against a monthly goal.

Rule-based insights compare the user's totals against national average benchmarks. The top emission category drives filtered recommendations. And once per day, the LLM generates a personalized tip — cached 24h per user.

This is the part I'm most proud of.

LLMs make up numbers. That's a real problem when you're talking about emissions data — if the model says "beef produces 5 kg CO₂ per kg" when the real figure is 27, that's actively harmful misinformation.

My solution in services/llm.py

:

def _contains_hallucinated_numbers(response: str, context: str) -> bool:
    """
    Extract all numbers from the LLM response.
    Check every one of them exists in the context we provided.
    If not → hallucination detected.
    """
    import re
    response_numbers = set(re.findall(r'\d+\.?\d*', response))
    context_numbers = set(re.findall(r'\d+\.?\d*', context))
    return not response_numbers.issubset(context_numbers)

The flow:

timeout=10.0

and max_retries=1

are explicitly set to prevent hung Gunicorn worker threads on slow LLM responses.Key principle: the LLM is never used for calculations. All math is Python/DB.

The activity log form has a dependent dropdown — selecting a category dynamically loads the relevant emission factors. I used htmx for this instead of writing custom JavaScript:

<select name="category" 
        hx-get="/factors/"
        hx-target="#factor-select"
        hx-trigger="change">

One attribute. No JS file. The server returns a partial HTML snippet with the filtered factors. This is exactly what htmx is built for.

Render makes Django deployment straightforward. A few Django-specific things worth noting:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = not DEBUG
SESSION_COOKIE_SECURE = not DEBUG
CSRF_COOKIE_SECURE = not DEBUG

Render terminates TLS at the proxy level, so SECURE_PROXY_SSL_HEADER

is essential — without it Django won't recognize HTTPS requests and will redirect loop forever.

Also: randomize your admin URL via env var:

ADMIN_URL = env('ADMIN_URL', default='admin/')

Stops bots from hammering the default /admin/

endpoint.

Async LLM calls. Right now the LLM calls are synchronous — a slow NVIDIA NIM response blocks a Gunicorn worker. The fix is Celery + Redis for background tasks. I skipped it for the MVP but it's the first thing I'd add.

Audited emission factors. The 22 factors I seeded are approximations from public sources, not peer-reviewed figures. For a production app, you'd want to integrate a verified dataset like the UK Government GHG conversion factors.

Email verification. Currently anyone can sign up with any email. Not a problem for an MVP, but a real gap.

If you're building something with Django + LLMs, the hallucination guard pattern is worth stealing. And if you have thoughts on better emission factor datasets, I'd love to hear them in the comments.

── more in #artificial-intelligence 4 stories · sorted by recency
── more on @django 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/how-i-built-a-carbon…] indexed:0 read:3min 2026-06-24 ·