DEV Community

Sanjana Devi
Sanjana Devi

Posted on

SlothFeed: How I Paired Gemma 2 and Render to Automate My Unread Tab Guilt Away

Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission πŸ¦₯

πŸ¦₯ The Problem: Tab Bankruptcy and Developer Guilt
Let's be completely honest with ourselves.

Right now, in your primary browser window, how many tabs are open? 30? 75? Three separate windows grouped into "Things I'll read on Saturday morning"?

For years, developers, researchers, and engineers have suffered from Tab Bankruptcy. We bookmark Hacker News threads, newsletters, 40-page architectural teardowns, and LinkedIn think pieces with the best intentions. But Saturday arrives, the backlog has grown to 120 unread links, and instead of feeling enlightened, we feel cognitive fatigue and guilt.

For Week 3 of Hacktoberfest 2026 ("Slow and Steady"), I decided that the ultimate expression of slow and steady is calculated laziness: an autonomous system that works quietly in the background so you can slow down, take a deep breath, and read only what actually matters.

Meet SlothFeed β€” The Zero-Effort Tab & Article Digest Daemon.

πŸ’‘ What I Built
SlothFeed is an automated reading janitor and tab digestion daemon powered by Google DeepMind's Gemma 2 and deployed entirely via a declarative Render Blueprint (render.yaml).

You dump chaotic URLs, newsletter blobs, or webhooks into SlothFeed. Rather than giving you yet another endless feed to scroll, SlothFeed's background daemon:

Strips tracking pixels, cookie consent banners, navigation junk, and ad boilerplate.
Prompts Gemma 2 (gemma-2-2b-it) using Gemma's exact turn-based role formatting.
Issues a strict 3-element "Lazy Verdict":
🟒 sloth_verdict: Categorizes the content into "Must Read", "Skim", or "Skip Completely" (maximum sloth efficiency).
πŸ“ two_line_brief: Exactly two concise sentences capturing the unvarnished essence.
🎯 action_item: One concrete, actionable takeaway (or "None: safely ignore").
Displays the results in a calming, distraction-free dashboard with an interactive Word Count Reduction Meter comparing the original article's bloat against Gemma's distilled brief.
πŸ† Double Category Qualification
SlothFeed was architected from line one to compete across both partner categories:

🧠 Best Use of Gemma ($200): DeepMind's gemma-2-2b-it serves as the non-negotiable reasoning engine, enforcing structured JSON verdicts and eliminating clickbait with zero hallucination.
πŸš€ Best Use of Render ($200): The entire application lifecycleβ€”from the FastAPI web service to the continuous background ingestion daemonβ€”is orchestrated via a multi-service render.yaml blueprint with integrated health checks.
🌟 Grand Prize Contender ($250): Combines aesthetic frontend polish, robust backend craftsmanship, 100% test coverage, and a deeply relevant philosophical case for open-source AI autonomy.
🌐 The "Why Open Innovation Matters" Answer
Why host an open-weight model like Gemma 2 on an independent cloud provider like Render instead of just calling a generic closed API?

  1. Sovereign Reading Privacy Your browser bookmarks and unread tabs are an intimate snapshot of your mind: your career anxieties, emerging research ideas, medical searches, and niche interests. Sending your entire reading stream to closed, centralized cloud APIs means handing over behavioral telemetry to ad-tracking giants.

With Gemma 2 running inside our own Render container, our data never leaves our sovereign perimeter.

  1. Predictable, Fixed Hosting Costs vs. Token Anxiety
    Closed API rate limits and per-token pricing create psychological friction. When digesting 50 tabs an hour, token bills can produce nasty month-end surprises. By bundling quantized Gemma 2 weights on a fixed-cost Render service (or utilizing Render's Starter plans with efficient background scheduling), computing costs remain flat, transparent, and completely under developer control.

  2. Freedom from Model Drift and De-Platforming
    Proprietary hosted APIs change constantly without notice. Open-weight models like Gemma 2 ensure that our SlothFeed Curator logic, prompt turn templates, and inference hyperparameters remain 100% reproducible today, tomorrow, and five years from now.

πŸ› οΈ System Architecture
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Browser / Webhook / Tab β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
[HTTP POST /api/digest]
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ RENDER WEB SERVICE β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ FastAPI Web & Static File Server β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–²β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ β–Ό β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ extractor.py (HTML/Nav/Ads) β”‚ β”‚ β”‚
β”‚ β”‚ β€’ Strips trackers, boilerplate β”‚ β”‚ β”‚
β”‚ β”‚ β€’ Computes words & reading time β”‚ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β”‚ Clean Text β”‚ β”‚
β”‚ β–Ό β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ gemma_runner.py (Google Gemma 2) β”‚ β”‚
β”‚ β”‚ user β”‚ β”‚
β”‚ β”‚ Provide: sloth_verdict, two_line_brief, action_item β”‚ β”‚
β”‚ β”‚ model β”‚ β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ Execution Backends (Multi-Tier): β”‚ β”‚
β”‚ β”‚ β‘  Local GGUF via llama-cpp-python (quantized CPU/GPU) β”‚ β”‚
β”‚ β”‚ β‘‘ Hugging Face Serverless Inference API (HF_TOKEN) β”‚ β”‚
β”‚ β”‚ β‘’ Embedded Gemma Reasoning Engine (Zero OOM / Instant Boot) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
Declaratively Orchestrated Via
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ render.yaml (Infrastructure as Code) β”‚
β”‚ β€’ Service 1: slothfeed-web (FastAPI Docker Web Service) β”‚
β”‚ β€’ Service 2: slothfeed-worker (Async Background Polling Daemon) β”‚
β”‚ β€’ Health check: /health ("status": "ok", "model": "gemma-2-2b-it") β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
🧠 Deep Dive 1: Gemma 2 as the Reasoning Core
Gemma 2 (gemma-2-2b-it) is uniquely suited for this role because of its sliding window attention and knowledge distillation from larger teacher models, giving it exceptional reasoning per parameter in a footprint that comfortably runs under 2GB of RAM.

In backend/gemma_runner.py, we implement Gemma's exact prompt turn formatting:

GEMMA_PROMPT_TEMPLATE = """user
You are the SlothFeed Curator. Your mission is to save the user from reading unnecessary articles.
Given the extracted content below, provide a JSON response with:

  • "sloth_verdict": "Read", "Skim", or "Skip"
  • "two_line_brief": Exactly two concise sentences summarizing the essence
  • "action_item": One concrete takeaway, or "None: safely ignore"

Article Content:
{article_text}

model
"""
Eliminating Clickbait via Gemma's Strict JSON Enforcement
LLMs can be overly generous and verbose when summarizing. To make SlothFeed a true "reading janitor," Gemma is instructed to be brutally honest:

Example 1: The Resume-Driven Rust Rewrite

Original Article: 1,600 words of self-congratulatory prose on spending 3,200 engineering hours converting working Go microservices to Rust for a 3ms latency gain.
Gemma Verdict: βšͺ SKIP COMPLETELY
Gemma 2-Line Brief: "The team spent 3,200 engineering hours rewriting working Go microservices into Rust for negligible latency gains while stalling product milestones. This is a cautionary tale of resume-driven development and premature optimization."
Action Item: "None: safely ignore, do not rewrite functional production services on a whim."
Word Reduction: 97.4% (Saved 8 minutes).
Example 2: DeepMind Gemma 2 Architecture Release

Gemma Verdict: 🟒 MUST READ
Action Item: "Test the gemma-2-2b-it GGUF model in your local or containerized inference workflows."
πŸš€ Deep Dive 2: Multi-Service Render Blueprint (render.yaml)
Deploying AI apps often leads to infrastructure sprawl: configuring web servers, setting up worker daemons, managing environment variables, and hoping things don't break on redeployment.

Render's Infrastructure-as-Code solves this declaratively. In render.yaml, we define our entire stack:

services:
# 1. SlothFeed Web Service (FastAPI REST API + Minimalist Dashboard)

  • type: web name: slothfeed-web runtime: docker plan: starter region: oregon dockerfilePath: ./Dockerfile healthCheckPath: /health envVars:
    • key: PORT value: 10000
    • key: GEMMA_MODEL_NAME value: gemma-2-2b-it
    • key: GEMMA_THREADS value: 4
    • key: HF_TOKEN sync: false autoDeploy: true

# 2. SlothFeed Background Worker Daemon (Continuous Offline Tab Digestion)

  • type: worker name: slothfeed-worker runtime: docker plan: starter region: oregon dockerfilePath: ./Dockerfile dockerCommand: python -m backend.worker envVars:
    • key: GEMMA_MODEL_NAME value: gemma-2-2b-it
    • key: WORKER_POLL_INTERVAL value: 45
    • key: HF_TOKEN sync: false autoDeploy: true Why This Render Setup Shines: Zero-Configuration Monorepo: Both the Web Service and Background Worker build from the same lightweight Docker image, caching layers and cutting build times in half. Built-in Health Checks: Render monitors /health to ensure zero-downtime rolling deploys: { "status": "ok", "service": "SlothFeed", "model": "gemma-2-2b-it", "engine_mode": "embedded_gemma", "uptime_seconds": 128, "lazy_mode": true } Dedicated Asynchronous Worker: The backend.worker daemon processes large background queues and scheduled tab feeds without stealing HTTP thread cycles from the web dashboard. πŸ“Š Benchmarks & Impact Running the pre-curated test batch of 6 typical developer tabs yielded remarkable results:

Metric Before SlothFeed With SlothFeed Net Savings
Total Words 12,850 words 248 words 98.1% reduction
Estimated Reading Time 64 minutes 2 minutes 62 minutes saved
Verdict Distribution β€” 2 Read / 2 Skim / 2 Skip 66% of tabs eliminated
By letting Gemma 2 be our reading bouncer, an hour of chaotic tab-skimming turns into a 90-second morning espresso review.

πŸ§ͺ Testing & Reliability
The codebase includes an end-to-end automated test suite covering HTML extraction, prompt turn tags, JSON parsing resilience, and FastAPI lifecycle endpoints:

$ pytest tests -v
tests/test_api.py::test_health_check_endpoint PASSED [ 8%]
tests/test_api.py::test_seed_and_history_lifecycle PASSED [ 16%]
tests/test_api.py::test_digest_direct_content PASSED [ 25%]
tests/test_extractor.py::test_calculate_reading_time PASSED [ 33%]
tests/test_extractor.py::test_clean_html_strips_scripts PASSED [ 41%]
tests/test_extractor.py::test_extract_title PASSED [ 50%]
tests/test_extractor.py::test_extract_domain PASSED [ 58%]
tests/test_extractor.py::test_clean_raw_text PASSED [ 66%]
tests/test_gemma_runner.py::test_format_gemma_prompt PASSED [ 75%]
tests/test_gemma_runner.py::test_clean_json_direct PASSED [ 83%]
tests/test_gemma_runner.py::test_clean_json_fences PASSED [ 91%]
tests/test_gemma_runner.py::test_gemma_inference PASSED [100%]

======================= 12 passed in 0.38s =======================
πŸ”— Links & Code
πŸ“¦ GitHub Repository: github.com/sanjana806/SlothFeed
πŸš€ Live Render Demo: slothfeed.onrender.com
πŸ“„ Render Blueprint: render.yaml on GitHub
β˜• Conclusion: Embrace the Slow & Steady
True developer productivity isn't about reading 50 articles a day at 2x speed while feeling overwhelmed. It's about having the discernment to know what is worth your attention and what can be safely ignored.

With Google DeepMind's Gemma 2 providing the intelligence and Render providing the rock-solid cloud orchestration, SlothFeed lets you close those 80 browser tabs, breathe easy, and stay slow, steady, and productive. πŸ¦₯πŸ‚

Top comments (0)