← All posts
2026-08-05 · Austin

Behind the scenes: how Poster works

I get a lot of questions from other operators about how Poster is actually built. Most of them expect me to say "AWS + a big serverless bill." The real answer is smaller, cheaper, and mostly boring. I want to walk through it because I think more people should build this way, and because I get tired of watching indie devs get talked into $2,000-a-month infra bills for a product with 300 users.

The stack, in one sentence

Next.js 15 on Vercel, Supabase for Postgres and auth, Vercel Blob for media, FFmpeg for video, Stripe for money, a handful of AI provider APIs, and a Node worker for anything that runs longer than 30 seconds. That's it.

Let me go through each one and say why.

Next.js on Vercel

I know, I know. "Vercel is expensive." Vercel gets expensive if you have huge egress or you're running Edge functions on a hot loop. For a normal SaaS with reasonable traffic, the Pro plan covers a lot of ground and the DX is worth it. I've built on Cloudflare Workers, on Fly, on Railway, on bare EC2. Vercel is the fastest way to ship for a solo person, full stop. When I outgrow it I'll move something, but I'll do that when the bill actually justifies the migration instead of pre-optimizing for a scale I don't have.

Next 15 App Router is genuinely good now. Server Actions removed 80% of the code I used to write for form handlers. RSC lets me put database calls directly in a page component and stream. It's not perfect — the mental model of "which of these components can use hooks?" is still confusing to new devs — but the productivity is real.

Supabase for everything data

Postgres, auth, row-level security, storage, edge functions, realtime. It's a lot in one product. I use maybe 60% of it.

The killer feature is the shared auth. Poster lives on poster.abmediax.com. The hub lives on abmediax.com. The account center at abmediax.com/account shows both. All of them share one Supabase auth session because we set the cookie domain to .abmediax.com. One getUser() call, no matter which subdomain you're on, and it works. Try doing that with Auth0 or Clerk without a lot of custom glue.

Postgres itself is boring in the best way. create table, create index, RLS policy, done. I don't use an ORM — just raw SQL through Supabase's client. My migrations are numbered .sql files in the repo. I've never regretted this.

Vercel Blob for media

Users upload videos. Videos are big. You don't want to store them in Postgres.

Vercel Blob is basically S3 with a nicer API and it lives on the same billing account as the Next app. For the volume Poster does, it's plenty. When we get to the point where storage is 30% of the bill, I'll move to Cloudflare R2 (zero egress) or Backblaze B2. Not before.

FFmpeg for video

Every "AI video" SaaS charges you $99/mo and under the hood they're calling FFmpeg. So I just call FFmpeg. The @ffmpeg-installer/ffmpeg npm package gives you a portable binary that works on Vercel's build server. Add a fluent-ffmpeg wrapper and you can concatenate clips, add captions, resize to 9:16 or 1:1 or 16:9, and burn subtitles in — all locally, no external API call.

For the parts that actually need AI — script writing, voiceover, transcription — I call OpenAI, Anthropic, or ElevenLabs directly through the AI SDK. No middleman SaaS.

The whole "AI content" wrapper industry is going to collapse in 18 months when everyone realizes they're paying a 10x markup on API calls their intern could make. Build directly on the models.

Stripe for money

Stripe is Stripe. There's no alternative that's actually an alternative for a US business. Their fee is fair, the API is good, the docs are the best in the industry.

The one thing I did that not everyone does: I put all the pricing logic in a single lib/plans.ts file. Products, prices, feature flags, per-plan limits — all in one place. When I want to change a plan, I edit one file. The Stripe price IDs live in env vars. There's a webhook handler that syncs subscription status back into Postgres and that's it. Total Stripe code is maybe 400 lines. I've seen people write 4,000.

The worker

Some things take too long for a serverless function. Uploading a 200MB video to TikTok. Running FFmpeg on a 10-minute source. Generating a 30-second AI video with Sora or Veo.

For those I have a small Node worker on a separate Fly.io machine. It polls a jobs table in Postgres, picks up work, does it, writes results back. That's the whole architecture. It's 800 lines. It costs $5/mo. It's more reliable than any managed queue service I've tried, because when it breaks I just look at the logs and fix the code.

Everything a serverless-purist will tell you is impossible with a worker like this — retries, backoff, idempotency, dead-letter — is about 40 lines each.

What I didn't use

For completeness, here's what I looked at and rejected, and why:

  • Prisma / Drizzle. Nice tools. I don't need them. Raw SQL is fine, the types come from a generated Supabase file.
  • tRPC. Server Actions cover what I needed tRPC for.
  • Redux / Zustand. RSC + URL state covers it.
  • Kubernetes. Please.
  • A "posting API" like Ayrshare or Blotato. They charge $1-2 per platform per post. On Poster's scale that would be $8,000/mo of pass-through cost. I wrote adapters directly against each platform's API. It took two weekends. It saves five figures a year.
  • Auth0 / Clerk. Supabase Auth handles it. And it doesn't cost per-MAU.
  • Segment / RudderStack. I log events to Postgres. If I outgrow that I'll move. I haven't.
  • DataDog. Vercel logs + a $9/mo Axiom account.

The general pattern: pay for infrastructure, not for wrappers on top of infrastructure. If a SaaS costs 10x the raw API it wraps, the API is usually available to you directly.

The bill

For the curious. Rough monthly costs at current scale:

  • Vercel Pro: $20 base + usage (around $80/mo in practice)
  • Supabase Pro: $25 base + usage (around $40/mo)
  • Vercel Blob: ~$25/mo
  • Fly worker: $5/mo
  • OpenAI / Anthropic / ElevenLabs: variable, mostly billed through to users' AI credits
  • Stripe: 2.9% + 30¢ (pass-through)
  • Domain, DNS, misc: ~$15/mo

That's it. That's the whole company. I could run it on a plane with satellite wifi and it would keep working.

Why I'm telling you this

Two reasons.

One, because I want you to build this way too. There is nothing here that's exotic. It's off-the-shelf tools used the way their docs suggest. If you're staring at a $1,500/mo infra bill on a small SaaS, you have been sold something.

Two, because I want the choice to be legible. When you sign up for Poster you should know what's under the hood. If you ever want to leave, you should know exactly what to take with you and where to put it. Software companies that hide their architecture usually have something to hide.

Next post I'll write is probably about how the AI caption thing actually works — the prompt engineering, the "voice fingerprint," the eval loop. It's more interesting than most of this.

Thanks for reading.

— Austin