<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: vishu</title>
    <description>The latest articles on DEV Community by vishu (@vishurizz).</description>
    <link>https://dev.to/vishurizz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4096760%2F0637fa2d-cf5d-403b-95ed-1a99287caadf.png</url>
      <title>DEV Community: vishu</title>
      <link>https://dev.to/vishurizz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vishurizz"/>
    <language>en</language>
    <item>
      <title>Building LeetRun: How I Turned Scattered LeetCode Prep into a Gamified SaaS Platform</title>
      <dc:creator>vishu</dc:creator>
      <pubDate>Sat, 29 Aug 2026 14:02:55 +0000</pubDate>
      <link>https://dev.to/vishurizz/building-leetrun-how-i-turned-scattered-leetcode-prep-into-a-gamified-saas-platform-4g86</link>
      <guid>https://dev.to/vishurizz/building-leetrun-how-i-turned-scattered-leetcode-prep-into-a-gamified-saas-platform-4g86</guid>
      <description>&lt;p&gt;&lt;em&gt;Live at &lt;a href="https://leetrun.vercel.app" rel="noopener noreferrer"&gt;leetrun.vercel.app&lt;/a&gt; - guest preview at /sheets, /patterns, /analytics before signup&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Prep Is Scattered, Unmotivating, and Lonely
&lt;/h2&gt;

&lt;p&gt;If you have ever prepared for a software-engineering placement cycle, you know the ritual: open Blind 75 in one tab, NeetCode 150 in another, Striver's sheet in Notion, LeetCode in a third window, and manually tick boxes when you finally get an Accepted verdict.&lt;/p&gt;

&lt;p&gt;Nobody tells you which pattern you are weak in relative to Google or Amazon interviews. Nobody holds you accountable when you skip a week. And every AI chatbot gives the same generic two-pointer lecture whether you solved 200 mediums yesterday or zero.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;LeetRun&lt;/strong&gt; to close that gap.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Insight
&lt;/h2&gt;

&lt;p&gt;The data already exists on LeetCode. The GraphQL API exposes full submission history. The product opportunity was indexing that history against curated sheets and wrapping it in motivation loops — not building another problem database from scratch.&lt;/p&gt;




&lt;h2&gt;
  
  
  What LeetRun Actually Ships
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Curated sheets&lt;/strong&gt; — Blind 75, NeetCode 150, Striver SDE, Striver A2Z, Striver 79, Love Babbar 450, Google Top 100, Amazon Top 100&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deep LeetCode Sync&lt;/strong&gt; — one import of your full accepted history auto-checks every matched problem on every sheet&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interview patterns&lt;/strong&gt; — DP, graphs, two pointers, sliding window and more, ranked by weightage with C++ templates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build-your-own revision&lt;/strong&gt; — random sets filtered by topic, difficulty, and solved state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adaptive quests&lt;/strong&gt; — daily, weekly, revision quests generated from weakest topics and target company, auto-verified against real solves&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Savage AI mentor&lt;/strong&gt; — context-aware coach with personality modes from supportive to savage (Pro unlocks full roast mode)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leaderboards&lt;/strong&gt; — global and friends boards by XP, level, streak, solve count, or contest rating&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiplayer rooms&lt;/strong&gt; — private 6-char codes, live solve progress, mock contests with your batch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public profiles&lt;/strong&gt; — shareable analytics, levels, streaks, badges for resumes and LinkedIn&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Deep Sync: One Import, Every Sheet Auto-Checked
&lt;/h2&gt;

&lt;p&gt;Basic LeetCode integrations show public profile stats. Deep Sync goes further.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User authenticates once with LeetCode session token
→ Backend fetches full accepted submission graph via GraphQL
→ Submissions normalised and matched against 1,500+ problem corpus
→ Every sheet row updates atomically
→ Client caches in localStorage SWR for instant repaint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reaction in user testing was always the same: &lt;em&gt;"Wait, it already knows I solved all of these?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Yes. That is the point.&lt;/p&gt;




&lt;h2&gt;
  
  
  Savage AI Mentor: Context Snapshot + RAG, Not a Chatbot Wrapper
&lt;/h2&gt;

&lt;p&gt;When a user asks LeetRun a question, we do not pass a bare prompt to Gemini or Groq. We compile a &lt;strong&gt;context snapshot&lt;/strong&gt; first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LeetCode stats and current streak&lt;/li&gt;
&lt;li&gt;Active daily quests&lt;/li&gt;
&lt;li&gt;Sheet completion percentages&lt;/li&gt;
&lt;li&gt;Weakest pattern families by weightage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On top of that, a &lt;strong&gt;RAG retrieval layer&lt;/strong&gt; searches a corpus of 1,500+ indexed problems, 21 interview pattern families, and system-design notes. Lexical scoring selects citeable chunks before generation — reducing hallucinated constraints and invented problem variants.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Both Gemini and Groq?
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Complex explanations, multi-step reasoning, system design&lt;/td&gt;
&lt;td&gt;Gemini&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low-latency mid-session coaching&lt;/td&gt;
&lt;td&gt;Groq&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The router sends queries to the optimal model based on complexity, expected response length, and whether the user is in savage mode (Pro) or standard coaching (Free).&lt;/p&gt;




&lt;h2&gt;
  
  
  Gamification That Respects the Grind
&lt;/h2&gt;

&lt;p&gt;Interview prep is a marathon. Consistency beats intensity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;XP system&lt;/strong&gt; — Easy 15, Medium 40, Hard 120, verified against real LeetCode accepts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streaks and levels&lt;/strong&gt; — visible on public profiles and leaderboards&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adaptive quests&lt;/strong&gt; — daily (Free), weekly and revision (Pro)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leaderboards&lt;/strong&gt; — global and friends, pre-fetched server-side with 60s revalidation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiplayer rooms&lt;/strong&gt; — 6-character codes, live member progress, mock contests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Badges and coins&lt;/strong&gt; — tied to verified solves and quest completion&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Pricing (Student-First, INR)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;th&gt;Highlights&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;₹0 forever&lt;/td&gt;
&lt;td&gt;Sync, daily quests, basic leaderboard, standard AI, 1 room&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;₹299/month&lt;/td&gt;
&lt;td&gt;Weekly + revision quests, savage AI, unlimited rooms, badges&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team&lt;/td&gt;
&lt;td&gt;Custom&lt;/td&gt;
&lt;td&gt;Up to 20 members, shared leaderboard, admin analytics&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Founding offer:&lt;/strong&gt; Pro free for the first 200 users, no credit card required.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why PostgreSQL Over a Document Store
&lt;/h2&gt;

&lt;p&gt;LeetRun's data model is deeply relational: users, problems, sheets, user-problem join tables, quest progress, XP events, leaderboard rankings, multiplayer room state, and friend graphs.&lt;/p&gt;

&lt;p&gt;Firebase could work for a MVP checklist app. It would fight you once you need ranked leaderboards, quest verification against historical solves, and room state with live member progress.&lt;/p&gt;




&lt;h2&gt;
  
  
  Five Caching Layers
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Next.js unstable_cache — leaderboard and profile data, 60s revalidation
2. HTTP Cache-Control (s-maxage + stale-while-revalidate) — analytics API routes
3. In-memory memoization — 1,500+ problem corpus loaded at boot
4. localStorage SWR — instant sheet and analytics repaints on client
5. Vercel Edge CDN — guest-preview routes (/sheets, /patterns, /analytics)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Stack Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Choices&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Next.js 16, TypeScript, Tailwind CSS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth &amp;amp; Data&lt;/td&gt;
&lt;td&gt;Supabase Auth, PostgreSQL, Prisma ORM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI&lt;/td&gt;
&lt;td&gt;Gemini API, Groq API, RAG retrieval, lexical scoring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;External&lt;/td&gt;
&lt;td&gt;LeetCode GraphQL (authenticated Deep Sync)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observability&lt;/td&gt;
&lt;td&gt;Sentry, PostHog&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy&lt;/td&gt;
&lt;td&gt;Vercel, Edge CDN, multi-layer SWR&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  What I Learned Building a Personal Product as SaaS
&lt;/h2&gt;

&lt;p&gt;LeetRun started as a tool I needed during my own prep cycle. Productising it forced decisions client work sometimes lets you defer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pricing in INR for Indian students&lt;/li&gt;
&lt;li&gt;Guest preview instead of hard paywalls&lt;/li&gt;
&lt;li&gt;Founding-member caps instead of fake urgency&lt;/li&gt;
&lt;li&gt;Caching architecture before traffic justifies it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The hardest engineering was not the UI. It was &lt;strong&gt;trust&lt;/strong&gt;. Users hand over LeetCode session tokens and expect every sheet to stay in sync forever. Deep Sync, quest verification, and XP integrity had to be boringly correct. The fun parts (savage AI roasts, leaderboard climbs, room codes) only work if the data layer never lies.&lt;/p&gt;




&lt;p&gt;Try it live: &lt;a href="https://leetrun.vercel.app" rel="noopener noreferrer"&gt;leetrun.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Guest preview at /sheets, /patterns, and /analytics — no signup needed.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Tags: &lt;code&gt;webdev&lt;/code&gt; &lt;code&gt;javascript&lt;/code&gt; &lt;code&gt;beginners&lt;/code&gt; &lt;code&gt;career&lt;/code&gt; &lt;code&gt;nextjs&lt;/code&gt; &lt;code&gt;ai&lt;/code&gt; &lt;code&gt;saas&lt;/code&gt; &lt;code&gt;leetcode&lt;/code&gt; &lt;code&gt;placement&lt;/code&gt; &lt;code&gt;buildinpublic&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;read more - &lt;a href="https://vishu.app/blog" rel="noopener noreferrer"&gt;https://vishu.app/blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How I Slashed a GCP Bill by 80%: The Hidden Trap of the Serverless CPU Toggle</title>
      <dc:creator>vishu</dc:creator>
      <pubDate>Fri, 28 Aug 2026 12:59:34 +0000</pubDate>
      <link>https://dev.to/vishurizz/how-i-slashed-a-gcp-bill-by-80-the-hidden-trap-of-the-serverless-cpu-toggle-1ohe</link>
      <guid>https://dev.to/vishurizz/how-i-slashed-a-gcp-bill-by-80-the-hidden-trap-of-the-serverless-cpu-toggle-1ohe</guid>
      <description>&lt;p&gt;How I Slashed My GCP Bill by 80%: The Hidden Trap of the Serverless CPU Toggle&lt;/p&gt;

&lt;p&gt;Key Takeaways&lt;br&gt;
• The --no-cpu-throttling (CPU always allocated) flag on Cloud Run opts you silently into 24/7 always-on billing, destroying the serverless cost model.&lt;br&gt;
• Cloud Run bills for active CPU milliseconds. With throttling off, containers log 168 billable instance-hours per week even when idle.&lt;br&gt;
• Google Cloud Tasks is purpose-built for this problem: explicit HTTP-targeted worker invocations with retries, rate-limiting, and backoff.&lt;br&gt;
• The architectural fix: Return 200 OK fast, enqueue a Cloud Tasks job, let the CPU scale to zero, and fire the worker separately.&lt;br&gt;
• Re-enabling CPU throttling plus Cloud Tasks cut billable instance-hours by ~80% while improving reliability.&lt;/p&gt;

&lt;p&gt;Last month I dropped my cloud computing bill by 80%. I didn't rewrite anything in Rust or migrate away from serverless. The savings came from realizing that a "genius" 30-second configuration fix I had applied weeks earlier was a silent budget assassin running 24 hours a day.&lt;/p&gt;

&lt;p&gt;If you are running Next.js, Node, or Go on Google Cloud Run and rely on background tasks, you are likely at risk of the exact same trap.&lt;/p&gt;

&lt;p&gt;The Problem: Scale-to-Zero Kills Background Jobs&lt;/p&gt;

&lt;p&gt;Serverless platforms like Cloud Run are cost-effective because they scale to zero. You pay only for the milliseconds a container is actively processing a request. The moment your handler fires a response, Cloud Run throttles the container CPU to near zero.&lt;/p&gt;

&lt;p&gt;This creates a hard problem for async work. I was building a standard webhook flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cloud Run API receives a webhook from a third-party service.&lt;/li&gt;
&lt;li&gt;The system needs to parse the payload, sync a batch of heavy images to a GCS bucket, and update the database.&lt;/li&gt;
&lt;li&gt;I need to return a 200 OK immediately so the third party does not time out.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The moment the 200 OK fires, GCP assumes the work is done. CPU is throttled to near zero. The Node.js event loop jobs — image sync, DB writes — stall, freeze, or fail silently. Network connections drop. The work vanishes.&lt;/p&gt;

&lt;p&gt;The Expensive Workaround: --no-cpu-throttling&lt;/p&gt;

&lt;p&gt;I hit the docs and found what looked like a magic wand: CPU always allocated (--no-cpu-throttling). I flipped the flag in 30 seconds. The background job issue vanished. The webhooks succeeded, the images synced, and I posted on LinkedIn about how easy the fix was.&lt;/p&gt;

&lt;p&gt;The hidden tradeoff nobody warns you about: By flipping --no-cpu-throttling, you quietly opt out of the entire serverless pricing model. You are now paying for 24/7 always-on compute at serverless prices.&lt;/p&gt;

&lt;p&gt;When I opened the GCP billing dashboard the next month, my Cloud Run instances were logging 168 billable instance-hours per week. The CPU was kept 'allocated' around the clock waiting for background jobs, so I was billed for 24/7 compute. I was paying premium serverless prices to run what was effectively a traditional always-on VM.&lt;/p&gt;

&lt;p&gt;Cost Impact: Throttling ON vs. OFF&lt;/p&gt;

&lt;p&gt;• Billing Model: Pay per active request ms (ON) vs. Always-on, pay 24/7 (OFF)&lt;br&gt;
• Idle Cost: Zero (ON) vs. Full instance-hour rate (OFF)&lt;br&gt;
• Weekly Instance-Hours: ~2–4 hrs (ON) vs. 168 hrs (OFF)&lt;br&gt;
• Background Reliability: Poor, jobs stall (ON) vs. Good (OFF)&lt;br&gt;
• Relative Monthly Cost: Baseline (ON) vs. ~10–15x baseline (OFF)&lt;/p&gt;

&lt;p&gt;The Real Fix: Event-Driven Decoupling&lt;/p&gt;

&lt;p&gt;To get that 80% reduction I re-architected the flow. The goal: let Cloud Run safely scale to zero the moment a request ends, while guaranteeing that the heavy background jobs actually execute.&lt;/p&gt;

&lt;p&gt;Step 1: Turn CPU throttling back on. Instant 24/7 billing leak plugged.&lt;/p&gt;

&lt;p&gt;Step 2: Migrate async work to Google Cloud Tasks. Cloud Tasks is specifically built for explicit, point-to-point HTTP execution. You target a specific worker endpoint, guarantee delivery, and get fine-grained control over retries, rate-limiting, and execution timing. (This is why I chose it over Pub/Sub — Pub/Sub is great for fan-out messaging, but for webhook processing with one worker and controlled retries, Cloud Tasks is the right primitive).&lt;/p&gt;

&lt;p&gt;The New, Cost-Optimized Architecture&lt;/p&gt;

&lt;p&gt;• Ingestion (fast and cheap): The main Cloud Run API receives the webhook. CPU is throttling-enabled.&lt;br&gt;
• The Handoff: Instead of executing the heavy image sync inline, the API parses the required IDs, builds a JSON payload, and enqueues a Cloud Tasks job targeting the dedicated worker endpoint.&lt;br&gt;
• The Quick Exit: The API returns 200 OK instantly. The request ends. Cloud Run throttles CPU to zero. Billing stops.&lt;br&gt;
• The Worker (on-demand compute): Cloud Tasks fires an HTTP request to the dedicated worker endpoint. Cloud Run spins up fresh compute for exactly this task. The worker completes the heavy sync and scales back down.&lt;/p&gt;

&lt;p&gt;Results: Faster, Cheaper, and Resilient&lt;/p&gt;

&lt;p&gt;• 80% cost reduction: Billable instance-hours plummeted. The platform idles for free between requests.&lt;br&gt;
• Bulletproof reliability: Cloud Tasks has built-in retries with exponential backoff. If an image sync fails due to a network hiccup or a database lock, Cloud Tasks retries the worker automatically without touching the main API or losing data in a frozen event loop.&lt;br&gt;
• Zero main-thread blocking: The webhook ingestion API now responds in milliseconds, completely decoupled from processing time.&lt;/p&gt;

&lt;p&gt;The Lesson: Serverless infrastructure is cheap because it idles for free. The moment you force it to stay awake to paper over an architectural flaw, you are paying always-on rates for always-on compute — and getting none of the resilience benefits of a real worker queue.&lt;/p&gt;

&lt;p&gt;If background jobs are stalling your APIs, don't flip the throttling flag. Build a worker, enqueue a task, and let the cloud scale to zero. The fix is never the flag. The fix is the architecture.&lt;/p&gt;




&lt;p&gt;Frequently Asked Questions&lt;/p&gt;

&lt;p&gt;What does the --no-cpu-throttling flag do on Google Cloud Run?&lt;br&gt;
It keeps a Cloud Run container's CPU active even after an HTTP request has completed. By default, Cloud Run throttles CPU to near zero once a response is sent, which is what makes serverless cheap. Disabling throttling means you pay for 24/7 compute regardless of actual traffic — effectively turning Cloud Run into an always-on VM billed at serverless prices.&lt;/p&gt;

&lt;p&gt;Why do background jobs stall on Cloud Run after returning a 200 OK?&lt;br&gt;
Cloud Run treats the end of an HTTP request as the signal to throttle the container CPU. Any background work still running in the Node.js event loop (image uploads, database writes, webhook fan-outs) is starved of CPU immediately. Network connections drop, promises hang unresolved, and the work disappears silently.&lt;/p&gt;

&lt;p&gt;What is the correct architecture for background jobs on Cloud Run?&lt;br&gt;
Event-driven decoupling via Google Cloud Tasks. The primary handler receives the webhook, enqueues a Cloud Tasks job targeting a dedicated worker endpoint, and returns 200 OK. Cloud Run scales to zero. Cloud Tasks then asynchronously calls the worker endpoint, spinning up fresh compute specifically for that task. You pay only for the milliseconds each container actively executes.&lt;/p&gt;

&lt;p&gt;Why use Cloud Tasks instead of Pub/Sub for background jobs?&lt;br&gt;
Cloud Tasks is built for explicit, point-to-point HTTP execution. You target a specific endpoint, control the exact delivery time, set per-task retry limits, and get fine-grained rate-limiting. Pub/Sub is optimized for high-throughput fan-out messaging where multiple subscribers need the same event.&lt;/p&gt;

&lt;p&gt;How much does the Cloud Run CPU throttling flag actually cost?&lt;br&gt;
With --no-cpu-throttling enabled, a container running 24/7 logs approximately 168 billable instance-hours per week. Depending on memory allocation and region, a single always-on instance can cost 10-15x more than the same workload processed on-demand with CPU throttling enabled.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>devops</category>
      <category>career</category>
    </item>
    <item>
      <title>How I Use Docker, GCP, and Supabase to Scale Production Apps</title>
      <dc:creator>vishu</dc:creator>
      <pubDate>Thu, 27 Aug 2026 06:21:17 +0000</pubDate>
      <link>https://dev.to/vishurizz/how-i-use-docker-gcp-and-supabase-to-scale-production-apps-17mf</link>
      <guid>https://dev.to/vishurizz/how-i-use-docker-gcp-and-supabase-to-scale-production-apps-17mf</guid>
      <description>&lt;p&gt;Most portfolio sites list “Docker, GCP, Supabase” as chips. This article is how I actually scale client apps: what each layer is for, what I refuse to put on it, and how that showed up on SVSFood and Ezlearn. [ &lt;a href="https://vishu.app/blog/docker-gcp-supabase-scale" rel="noopener noreferrer"&gt;https://vishu.app/blog/docker-gcp-supabase-scale&lt;/a&gt; ]&lt;/p&gt;

&lt;p&gt;The shape of the stack&lt;br&gt;
I treat infrastructure as three contracts:&lt;/p&gt;

&lt;p&gt;Docker is how software is packaged. If it is not in an image, it is not what production runs.&lt;br&gt;
Google Cloud Platform is where images run and where files live. Cloud Run, Cloud SQL or a VPC path to Supabase, Cloud Storage, Secret Manager, Cloud Build.&lt;br&gt;
Supabase is production PostgreSQL with auth, Row Level Security, and realtime when the product needs live order or presence updates - accessed from app code through Prisma.&lt;br&gt;
Frontends are often Next.js on Vercel when they are content and dashboard surfaces (Jara, LeetRun). APIs, workers, and anything that must stay warm or talk to hardware stay in Docker on GCP. Mixing those two is intentional, not indecision.&lt;/p&gt;

&lt;p&gt;Docker as the unit of deploy&lt;br&gt;
I containerize Node and Fastify services with multi-stage builds: a build stage with devDependencies, a runtime stage with only what the process needs. The image listens on a port, exposes a &lt;code&gt;/health&lt;/code&gt; route, and reads secrets from the environment. Cloud Run starts that process, routes HTTPS, and scales the container count with traffic.&lt;/p&gt;

&lt;p&gt;Why not a bare VM&lt;br&gt;
A Compute Engine VM is fine as a jump box or for a stateful exception. It is a poor default for app servers. Patch levels drift. Node versions drift. “I SSH’d and npm installed” is not a rollback plan. Docker plus Cloud Run gives me immutable deploys: revert means serving the previous digest. That matters when you are on-call for a restaurant kiosk at dinner rush.&lt;/p&gt;

&lt;p&gt;What goes in the image&lt;br&gt;
The compiled or bundled API (Fastify + TypeScript).&lt;br&gt;
Prisma client generated against the production schema.&lt;br&gt;
A non-root user and a pinned Node LTS base.&lt;br&gt;
No .env files. Secrets arrive from Secret Manager at runtime.&lt;br&gt;
Local &lt;code&gt;docker compose&lt;/code&gt; runs the API next to a Postgres that matches production (or a Supabase local stack). CI builds the same Dockerfile. The promotion path is an image tag, not a new ritual.&lt;/p&gt;

&lt;p&gt;GCP as the runtime&lt;br&gt;
I chose Google Cloud Platform for Ezlearn over AWS and over “put the whole product on Vercel” for three reasons that still hold:&lt;/p&gt;

&lt;p&gt;Pricing and latency in Asia for Compute Engine and Cloud SQL were better for a bootstrapped EdTech targeting Indian learners.&lt;br&gt;
Docker is a first-class citizen. Cloud Run is a container product, not an afterthought.&lt;br&gt;
Cloud Storage plus a CDN is the correct place for course video, certificates, and kiosk assets - not the Node process.&lt;br&gt;
Cloud Run for APIs&lt;br&gt;
SVSFood’s Fastify API - kiosk, admin, website, rider - is the kind of service Cloud Run is for: bursty lunch and dinner traffic, idle overnight, needs HTTPS and a custom domain, must not require me to size a VM. Concurrency is tuned so one instance can hold multiple in-flight orders without melting. CPU is allocated only during request processing unless a WebSocket path needs a minimum instance.&lt;/p&gt;

&lt;p&gt;Storage, SQL, and secrets&lt;br&gt;
Ezlearn course video never streamed from the application server. Objects live in a bucket; the app mints URLs. Certificates are rendered server-side as PDFs and stored the same way. Secrets (payment keys, session material, third-party tokens) sit in Secret Manager and are mounted as env on the Cloud Run service. I do not keep production secrets in GitHub or in a Vercel dashboard for the API layer.&lt;/p&gt;

&lt;p&gt;Supabase as the data plane&lt;br&gt;
Supabase is PostgreSQL I do not have to baby-sit, plus auth and realtime when I want them. On SVSFood, Prisma talks to Postgres hosted on Supabase. Orders, inventory, menus, coupons, riders, and audit logs are relational on purpose. I will not put that in a document store and then re-implement joins in application code.&lt;/p&gt;

&lt;p&gt;Auth and Row Level Security&lt;br&gt;
For products where the client app can talk to the database under a user JWT, Supabase Auth plus RLS is a force multiplier. Admin consoles and payment webhooks still go through Fastify - those paths need server secrets and idempotency. The split is: Supabase for identity and row-level rules; custom API for money and vendors.&lt;/p&gt;

&lt;p&gt;Realtime without a second architecture&lt;br&gt;
Kiosk and rider status can move over Supabase realtime or over WebSockets on Fastify. I pick based on who owns the write path. If the write already goes through Fastify (inventory reservation, payment capture), I broadcast from there. If the write is a simple presence or chat-like update, Supabase realtime is enough. I do not run Redis “because scale” on a product that does a few thousand orders.&lt;/p&gt;

&lt;p&gt;Case: SVSFood - four clients, one pipeline&lt;br&gt;
SVSFood needed a kiosk, an admin console, an online ordering site, and a rider app. The constraint: one menu, one inventory, one order state. Docker packaged the Fastify API. GCP hosted it. Supabase PostgreSQL was the source of truth. Next.js handled console and website. React Native handled kiosk and rider. PhonePe and Petpooja stayed behind the API so a tablet never held a settlement key.&lt;/p&gt;

&lt;p&gt;Scale here is not millions of QPS. Scale is correctness at dinner rush across three outlets, offline kiosks that sync, and an operator who can change a price once. The stack is sized for that. ₹40L+ in month one on owned devices is the outcome that matters.&lt;/p&gt;

&lt;p&gt;Case: Ezlearn - EdTech on GCP for 1,000+ MAU&lt;br&gt;
As CTO I owned architecture and shipping for Ezlearn: subscriptions, Hindi-first course delivery, AI learning roadmaps, certificates, a job portal. The platform ran on Next.js, Node, PostgreSQL, and GCP with 99.9% uptime and 1,000+ monthly active users. Video on CDN-backed storage kept the Node process small. Certificates were a server-side PDF pipeline into Cloud Storage. GCP’s Asia pricing made that viable for a bootstrapped company in Noida.&lt;/p&gt;

&lt;p&gt;What I do not do&lt;br&gt;
I do not run Kubernetes for a single API. Cloud Run is enough until it is not; I have not hit that wall on these products.&lt;br&gt;
I do not put the database in a container on the same Cloud Run service as the API.&lt;br&gt;
I do not use Supabase as a replacement for payment orchestration or complex vendor adapters.&lt;br&gt;
I do not multi-cloud a client MVP. One cloud, one database, one container registry.&lt;/p&gt;

&lt;p&gt;The architecture, simply&lt;br&gt;
Vishu Pratap scales production apps by packaging APIs in Docker, running them on Google Cloud Run, storing relational data and auth in Supabase PostgreSQL (or Cloud SQL), and putting media on Cloud Storage. The pattern is proven on SVSFood’s food-tech stack and Ezlearn’s EdTech platform. Deeper notes: Docker in production, GCP architecture, Supabase and PostgreSQL.&lt;/p&gt;

&lt;p&gt;Frequently asked questions&lt;br&gt;
How does Vishu Pratap use Docker, GCP, and Supabase together?&lt;br&gt;
Application servers (Fastify, Node) are packaged as Docker images and deployed to Google Cloud Run. Relational data, auth, and realtime live on Supabase PostgreSQL (or Cloud SQL when a project outgrows it). Object files go to Cloud Storage behind a CDN. The same Docker image is what ran in development.&lt;/p&gt;

&lt;p&gt;Why Docker instead of deploying Node directly on a VM?&lt;br&gt;
A VM drift problem - “it works on the server” - is expensive when you are the only operator. Docker pins the runtime, system libraries, and start command. Health checks, rolling deploys, and Cloud Run all assume a container contract.&lt;/p&gt;

&lt;p&gt;Why Google Cloud Platform instead of AWS or only Vercel?&lt;br&gt;
For Ezlearn, GCP won on Compute Engine and Cloud SQL pricing in Asia and on native Docker support. Vercel is excellent for Next.js frontends (Jara, LeetRun) but is the wrong home for long-running APIs, kiosk backends, and video-adjacent workloads. AWS would have worked; it was more expensive for the same region and shape.&lt;/p&gt;

&lt;p&gt;For more - &lt;a href="https://vishu.app/blog" rel="noopener noreferrer"&gt;https://vishu.app/blog&lt;/a&gt;&lt;br&gt;
medium article - &lt;a href="https://medium.com/@vishurizz0/how-i-use-docker-gcp-and-supabase-to-scale-production-apps-d41f611b5078?postPublishedType=initial" rel="noopener noreferrer"&gt;https://medium.com/@vishurizz0/how-i-use-docker-gcp-and-supabase-to-scale-production-apps-d41f611b5078?postPublishedType=initial&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>cloud</category>
      <category>docker</category>
      <category>gcp</category>
    </item>
  </channel>
</rss>
