Feature Flags with PostHog or GrowthBook | Coding Capybaras
How to add SaaS feature flags with PostHog or GrowthBook in a Next.js app: setup steps, pricing, rollout patterns, and when a simple config table is enough.
· Justin Boggs

Photo by Diogo Cardoso on Unsplash
The fastest way to add SaaS feature flags is to use a tool you already have: if PostHog is running in your app for analytics, its feature flags ship with the same SDK and a free tier of 1 million flag requests per month. If you'd rather own the whole thing, GrowthBook is MIT-licensed open source you can self-host for free. And if all you need is "turn this feature on for Pro users," you may not need a flag service at all — a config value does the job. This post walks through all three paths, with the setup steps and the rollout patterns that keep a solo founder out of trouble.
TL;DR
- A feature flag is a switch that changes app behavior without a deploy — turn features on/off, roll out gradually, or kill something broken in seconds.
- Already using PostHog for analytics? Use its flags. The free tier (1M requests/month) is more than an early-stage SaaS will touch.
- Want open source and self-hosting? GrowthBook is free under the MIT license; its cloud Starter plan is free for up to 3 users.
- Don't add a flag service for simple plan gating. A config-driven boolean is less machinery and zero latency.
What feature flags actually do for an indie SaaS
A feature flag is a conditional in your code whose value lives outside your code — in a dashboard, a config table, or a flag service — so you can change what users see without deploying. That separation of deploy from release is the whole point.
For a solo founder, three uses matter far more than the rest:
The kill switch. You ship a new billing page. Two hours later a customer emails you a screenshot of a blank screen. Without a flag, your options are "revert and redeploy under pressure" — the exact situation where non-technical founders make things worse. With a flag, you toggle the feature off in a dashboard and debug calmly. Unleash's feature flag best practices guide notes that kill switches invert the usual pattern: they default to on and get flipped off during an incident, no redeploy involved.
The gradual rollout. Instead of releasing to 100% of users, you release to 5%, watch your error tracker, then ramp to 25%, 50%, 100%. If something breaks, it broke for a handful of users instead of everyone. If you've already wired up error tracking the way I covered in the Sentry setup walkthrough, a gradual rollout turns "something's wrong" into a small, contained event.
Plan entitlements. "Pro users get the export feature, free users don't" is technically a feature flag too. But hold that thought — this is the case where a dedicated flag service is usually overkill, and I'll come back to it.
What indie founders mostly don't need on day one: multivariate experiments, A/B testing with statistical significance engines, or holdout groups. Those tools are built into both PostHog and GrowthBook, and they're great — once you have enough traffic that an experiment can reach significance in less than a quarter. With a few hundred users, you will not. Ship the flag infrastructure for safety first; run experiments later when the traffic justifies it.
PostHog vs GrowthBook: which one fits your SaaS?
Both are credible, both have generous free options, and both integrate cleanly with Next.js. The honest difference is about where you're starting from.
| Feature | PostHog | GrowthBook | | --- | --- | --- | | Open source | Yes (core) | Yes (MIT license) | | Free tier | 1M flag requests/month | Cloud: free up to 3 users; self-host: free, unlimited | | Paid pricing | ~$0.0001/request past free tier | Pro: $40/user/month (cloud) | | Bundled with | Analytics, session replay, error tracking, surveys | Experiments, analytics on your own data warehouse | | Self-hosting | Possible but not the happy path | First-class — MIT core, deploy anywhere | | Best for | Teams already on PostHog analytics | Founders who want to own the stack or avoid per-request billing |
Pick PostHog if it's already in your app. If you followed my PostHog analytics setup guide, you already have the SDK installed, users identified, and events flowing. Flags ride on that same installation — no new vendor, no new SDK, and flag evaluations correlate with your product analytics automatically. PostHog's pricing gives you 1 million flag requests a month free, and past that it's usage-based at roughly $0.0001 per request. For context: an app with 1,000 daily active users evaluating a handful of flags per session won't get near the free limit.
Pick GrowthBook if you want to own it. GrowthBook's core is MIT-licensed and free to self-host with unlimited flags, users, and experiments — you pay only for the server it runs on. The cloud version has a free Starter plan for up to 3 users, which for a solo founder means free, full stop. GrowthBook also evaluates flags from a locally-cached payload by default, so there's no per-evaluation network call and no per-request billing to think about.
There's a tradeoff worth saying out loud: PostHog is one more usage-billed service in your stack, and usage billing means a surprise is possible (you can set billing limits to cap it). GrowthBook self-hosted is one more thing you operate. Neither is wrong. I lean toward PostHog for non-technical founders because operating your own services is exactly the kind of invisible workload that eats weekends — but if the sovereignty matters to you, GrowthBook is the better citizen.
How do you set up PostHog feature flags in Next.js?
If PostHog analytics is already installed, flags require zero new packages. Here's the whole path, assuming a Next.js App Router project like the Coding Capybaras boilerplate:
1. Create the flag in PostHog. Dashboard → Feature Flags → New. Give it a key like new-billing-page, set the rollout to 0% (you'll ramp it later), and save. Flag keys are permanent identifiers — pick names you can grep for.
2. Read the flag on the client. PostHog's Next.js docs cover both routers; in a React component the hook does the work:
"use client";
import { useFeatureFlagEnabled } from "posthog-js/react";
export function BillingPage() {
const newBilling = useFeatureFlagEnabled("new-billing-page");
return newBilling ? <NewBillingPage /> : <LegacyBillingPage />;
}
3. Read the flag on the server when the decision affects what the server renders or which API path runs. The Node SDK evaluates flags server-side against a user's distinct ID — the same ID you passed to posthog.identify() after login. Server-side evaluation matters more than people expect: if you gate a page client-side only, the old version flashes before the flag loads.
4. Ramp it. Back in the dashboard, move the rollout from 0% → 5% → 25% → 100% over a few days while watching errors. Every step is a dashboard change, not a deploy.
Two gotchas I hit doing this on a real app. First, flags evaluate against identified users — if you evaluate before calling identify(), anonymous users get bucketed separately and your "5% of users" isn't the 5% you think. Second, flag evaluations count toward the request quota, so avoid calling flag checks inside loops or per-row in a table render. Evaluate once, pass the boolean down.
If you're doing this with an AI assistant, the failure mode to watch for is the assistant inventing a hook name or wiring the provider in the wrong layout file — the same class of problem I wrote about in when to trust your AI assistant. Paste the actual PostHog docs into context and the accuracy jumps.
Setting up GrowthBook instead
GrowthBook's flow is similar in shape, different in mechanics:
1. Create a project and get SDK keys. On GrowthBook cloud (or your self-hosted instance), create an SDK connection — GrowthBook's docs have a dedicated Next.js App Router guide that walks the whole flow. You get an API host and a client key, which go in .env.local as NEXT_PUBLIC_GROWTHBOOK_API_HOST and NEXT_PUBLIC_GROWTHBOOK_CLIENT_KEY.
2. Install and wrap. @growthbook/growthbook-react provides a GrowthBookProvider you mount near the root of your app. On load, the SDK fetches a JSON payload of all flag definitions once, then evaluates every flag locally. That's the architectural difference from PostHog's default: evaluation is instant and offline-safe after the initial fetch.
3. Use the flag:
import { useFeatureIsOn } from "@growthbook/growthbook-react";
export function BillingPage() {
const newBilling = useFeatureIsOn("new-billing-page");
return newBilling ? <NewBillingPage /> : <LegacyBillingPage />;
}
4. Target and ramp from the GrowthBook dashboard: percentage rollouts, attribute targeting (plan, signup date, email domain), and forced values for your own account so you can test in production before anyone else sees the feature.
The setup cost is one new provider and one new vendor dashboard. The payoff is no per-request math ever, and — if you self-host — no third party in the flag path at all.
What should you put behind a flag first?
Not everything deserves a flag. Wrapping every change in a conditional doubles your code paths and gives you the flag-sprawl problem without the safety payoff. When I audited what actually earned a flag in my own app, it came down to three categories.
Anything that touches money. Checkout flows, pricing page changes, billing logic, webhook handlers. This is where a bug costs you real revenue or — worse — double-charges a customer. My first flag ever was around a change to the upgrade flow, set to 5% for three days while I watched Stripe's dashboard and my error tracker for anything unusual. Nothing broke, but the point is that it could have, and the blast radius was a handful of users instead of every checkout that week.
Anything that replaces a working page. A redesigned dashboard, a new onboarding sequence, a rebuilt settings screen. The old version works; the new version probably works. "Probably" is what flags are for. Keep the old component in the tree, gate the new one, and delete the old code only after the flag has sat at 100% without complaints for a couple of weeks.
Anything an AI assistant built that you can't fully read. This one is specific to founders like me. When Claude Code writes a feature that touches parts of the codebase I only half understand, a flag is my safety margin. I can ship it to production — which is the only place some bugs ever show up — while keeping one hand on a switch I do understand. It converts "I hope this works" into "I'll know within an hour if it doesn't, and I can undo it in ten seconds."
What doesn't need a flag: copy changes, styling tweaks, new marketing pages, bug fixes. If reverting via git is just as fast and just as safe, the flag is ceremony. Deploys on Vercel roll back in one click; a flag has to earn its place by being meaningfully faster or more targeted than that.
Rollout patterns that keep you safe
Tooling is the easy half. The patterns are what actually protect you.
flowchart LR
A[Deploy code<br/>flag at 0%] --> B[Enable for<br/>yourself only]
B --> C[5% rollout]
C --> D{Errors or<br/>complaints?}
D -- yes --> E[Toggle off<br/>fix calmly]
E --> C
D -- no --> F[25% → 50% → 100%]
F --> G[Remove flag<br/>from code]
Never jump 0% to 100%. The rollout progression that the Unleash best-practices guide recommends — yourself, then a small percentage, then ramping with monitoring — costs you a few days of patience and buys you the ability to fail small. Both PostHog and GrowthBook bucket users consistently, so the same user stays in the same group as you ramp; nobody sees the feature flicker on and off between sessions.
Test on yourself in production first. Both tools let you force a flag on for a specific user. Turn it on for your own account, click through the feature on the live site, then start the percentage rollout. This one habit catches an embarrassing fraction of bugs.
Delete flags after they land. A flag that's been at 100% for a month is dead code with a dashboard dependency. Unleash's guidance suggests keeping active flags per service in the low dozens at most — past that, nobody remembers what's safe to remove. My rule: when a rollout completes, add a task to delete the flag and the old code path. A stale flag is exactly the kind of confusing conditional that makes an AI assistant guess wrong about how your app works.
Don't use a flag service for plan gating. Here's the thought I promised to come back to. "Pro users see the export button" isn't a rollout — it's an entitlement, it changes when the customer's subscription changes, and it should live next to your billing data. In the Coding Capybaras boilerplate, that kind of gating is config-driven: feature access lives in the platform config and the admin GUI, right beside pricing and branding, and the product code reads it through one interface. No network call, no external dashboard, no per-request billing for a check that runs on every page load. Use PostHog or GrowthBook for releasing things; use your config and billing state for entitling things. Keeping those separate also keeps your onboarding flow deterministic — a new customer's plan features should never depend on a third-party flag fetch racing your page render.
Frequently asked questions
Are PostHog feature flags really free?
Up to 1 million flag evaluation requests per month, yes — no credit card required to start. Past that it's usage-based at roughly $0.0001 per request, and you can set a billing limit so overage stops rather than bills. An early-stage SaaS with modest traffic and sensible evaluation patterns typically stays inside the free tier.
Is GrowthBook completely open source?
The core is MIT-licensed and free to self-host with unlimited flags and users; you pay only for your own infrastructure. The hosted cloud has a free Starter plan (up to 3 users) and a Pro plan at $40/user/month for advanced experimentation features.
Should I use Next.js middleware or client-side flags?
Client-side hooks are fine for cosmetic changes. For anything that changes page structure, gate it server-side (or bootstrap flags before render) so users don't see the old UI flash before the flag resolves. PostHog and GrowthBook both document server-side evaluation for exactly this reason.
How many feature flags is too many?
If you can't say from memory what each flag does, you have too many. Industry guidance puts a healthy ceiling at a few dozen active flags per service; a solo-founder SaaS should usually be under ten. Delete flags once their rollout hits 100% and stabilizes.
Can I A/B test with these tools?
Yes — both PostHog and GrowthBook include experimentation on top of their flag engines. But statistical significance needs traffic most early-stage products don't have. Use flags for safe releases now; run experiments when you have thousands of users moving through the funnel you're testing.
Do feature flags slow my app down?
GrowthBook evaluates locally against a cached payload, so per-check cost is effectively zero after the initial fetch. PostHog evaluates via API by default but supports bootstrapping and local evaluation for latency-sensitive paths. Either way, evaluate once per request and pass values down — don't re-check in every component.
Conclusion
SaaS feature flags with PostHog or GrowthBook come down to a starting-point question: PostHog if it's already handling your analytics and you want flags with zero new vendors, GrowthBook if you want MIT-licensed open source and no usage billing. Either way, the discipline matters more than the tool — ramp gradually, test on yourself first, delete flags when they're done, and keep plan entitlements in your config instead of a flag service. The PostHog integration guide on the Coding Capybaras marketplace has the copy-paste AI prompt that wires the SDK into a Next.js + Supabase app, flags included — from there, your first gradual rollout is a dashboard toggle away.