Inngest SaaS Background Jobs: $0 Architecture

Forget the hype around serverless queues. One indie hacker built his entire SaaS background job system with five Inngest functions on a single route — for free. No Redis bills, no worker drama.

5 Functions, No Redis, Zero Bucks: The Lean SaaS Job Queue That Actually Works — theAIcatchup

Key Takeaways

  • Five Inngest functions replace Redis, BullMQ, cron — zero cost for drip email SaaS.
  • step.sleep() and independent retries enable 48-hour jobs without hacks.
  • Fan-out via events scales parallelism sans worker pools — indie hacker dream.

Serverless dreams hit reality at 3 AM last Sunday, when a forgotten image cleanup job fired off without waking a single container.

Drippery, this drip email SaaS scraping by on beta users, runs its whole background job architecture on Inngest. Five functions. One Next.js API route. Zero dollars a month. That’s the pitch — and damn if it doesn’t deliver, at least for a scrappy operation dodging infra bills.

I’ve seen Silicon Valley peddle “serverless everything” for years, promising to free devs from ops hell. Remember the early Lambda hype? Everyone rushed in, then crawled back to EC2 when cold starts bit. But here’s a guy — anonymous indie hacker — actually pulling it off without the pain. Who’s making money? Inngest, sure, on the free tier hook. But for now, it’s the users winning.

BullMQ needs Redis. Cron has no retries. I needed background jobs that can sleep for 48 hours, fan out to parallel workers, and survive server restarts — without paying for infrastructure I don’t have users to justify yet.

That quote nails it. Redis at $10/month on Render? Gone. BullMQ workers? Vaporized. Cron containers? Who needs ‘em.

How Does One Route Handle Five Functions?

Simple: Inngest webhooks hit a single Next.js endpoint. Register all functions there — boom, serverless magic. No persistent workers eating CPU. No distributed locks to babysit.

The scheduler ticks every 15 minutes, cron-style: sendPendingEmails. Grabs active subscribers, checks their drip sequence position, timezone windows (no 3 AM blasts), then fans out events. Fifty due emails? Fifty parallel sendSingleEmail invocations. Isolation baked in — one sub, one email, no shared state disasters.

Each step? Retryable independently. Send fails? Only that retries. DB record after crash? Resumes there. No double-sends haunting your inbox.

But.

Cynic hat on: This shines for low-volume SaaS. Ramp to thousands of subs, and those fan-outs could spike costs if you hit paid tiers. Still, for bootstrappers — gold.

Can Inngest’s step.sleep() Really Kill Long-Polling Nightmares?

Domain verification polling. User adds custom sender domain to Resend — DNS checks take minutes or days. Old way? Cron hacks, delayed BullMQ jobs, manual retries. Nightmare.

Inngest? checkDomainVerification grabs status, sleeps 5m if unverified, self-chains via step.sendEvent. Up to 576 attempts (48 hours). One line: await step.sleep('5m'). Resumes post-sleep like nothing happened. Server restarts? Inngest replays from storage.

This function can run for up to 48 hours. step.sleep() suspends the function, frees server resources, then resumes exactly where it left off.

BullMQ couldn’t touch this without glue code — delayed queues, persistence hacks, error-prone as hell.

Orphan cleanup? Sunday 3 AM cron: lists R2 keys, diffs against DB, deletes ghosts. Simple, but durable.

Beta user lifecycle — whatever that mops up. Point is, patterns repeat: cron triggers, event fan-out, sleeps, retries.

Why Ditch the Redis + BullMQ Stack Forever?

Look at the table this dev loves:

Without Inngest: Redis ($10/mo), BullMQ process, cron container, manual retries, DIY dashboard.

With: Nada. Free observability. Auto-locking. step.sendEvent for fan-out pools.

I’ve covered job queues since Sidekiq dominated Ruby land. Redis was king — reliable, but pricey for solos. BullMQ improved it, but still tethered to that cache beast. Inngest? Durables over HTTP. No infra. Echoes the 2014 serverless pivot, when Lambda ate cron for breakfast. Prediction: Niche queues like Resque die first. Big dogs (Celery) limp on enterprise FUD.

Catch? Vendor lock. Inngest’s steps are opinionated — love ‘em or port hell. Free tier caps? Unspoken gotcha till scale hits.

Yet for Drippery — scheduled emails, DNS polls, cleanups — flawless. Parallelism without config. Observability without Datadog bills.

Deeper dive: sendSingleEmail. Fetches sub/email/tenant in one retryable step. Merge tags, send via Resend, record sent. Crash mid-way? Smart resume.

Each step.run() is independently retryable. If the Resend API times out on send-email, only that step retries — the DB fetch doesn’t re-execute.

That’s the secret sauce. Granular durability devs dream of, minus the boilerplate.

The Money Angle: Who’s Cashing In?

Inngest’s free tier sucks you in — dashboard, retries, sleeps, all gratis. Scale to paid? They’ll getcha. But solos laugh last.

Resend integration? smoothly, but another API key hop. Cloudflare R2 for images — cheap storage win.

Skeptical take: This isn’t revolutionary; it’s evolution. Serverless queues were inevitable post-Kafka fatigue. But execution? Chef’s kiss for indies.

Historical parallel: Early Heroku dynos killed VPS pain. Inngest does it for jobs. Bold call — by 2026, 70% of sub-10k MRR SaaS run durable functions like this. Redis becomes boomer tech.

Is This Scalable, or Just a Hack?

Short bursts say yes. Fan-out to 50? Fine. 5k? Test it. Inngest claims concurrency without limits on free — but watch invocations.

No users yet? Perfect. Grow pains deferred.

Cleanup function sketches reliability:

export const cleanupOrphanImages = inngest.createFunction(
{ id: 'cleanup-orphan-images', triggers: [cron('0 3 * * 0')] },
async ({ step }) => {
const r2Keys = await step.run('list-r2', async () => // lists bucket

And so on — diffs, deletes. Retries if R2 hiccups.


🧬 Related Insights

Frequently Asked Questions

What is Inngest for SaaS background jobs?

Inngest is a serverless job queue that uses durable functions over webhooks — no Redis needed, with built-in sleeps, retries, and fan-out for emails, polls, cleanups.

How to replace BullMQ with Inngest?

Register functions in one API route, use cron triggers or events, swap loops for step.sendEvent fan-outs, and step.sleep for delays — cuts infra to zero.

Does Inngest cost money for small SaaS?

Free tier handles low-volume jobs indefinitely; scales to paid only when invocations spike with users.

Priya Sundaram
Written by

Hardware and infrastructure reporter. Tracks GPU wars, chip design, and the compute economy.

Frequently asked questions

What is Inngest for <a href="/tag/saas-background-jobs/">SaaS background jobs</a>?
Inngest is a serverless job queue that uses durable functions over webhooks — no Redis needed, with built-in sleeps, retries, and fan-out for emails, polls, cleanups.
How to replace BullMQ with Inngest?
Register functions in one API route, use cron triggers or events, swap loops for step.sendEvent fan-outs, and step.sleep for delays — cuts infra to zero.
Does Inngest cost money for small SaaS?
Free tier handles low-volume jobs indefinitely; scales to paid only when invocations spike with users.

Worth sharing?

Get the best AI stories of the week in your inbox — no noise, no spam.

Originally reported by Dev.to

Stay in the loop

The week's most important stories from theAIcatchup, delivered once a week.