page.tsx211 lines · main
1import Link from 'next/link';
2
3import { DocsShell } from '../../components/shell';
4
5export const metadata = { title: 'pricing' };
6
7interface PlanRow {
8 label: string;
9 free: string;
10 pro: string;
11 team: string;
12}
13
14// Caps are the single source of truth from apps/api/src/services/tiers.ts
15// (TIERS). Keep this table in sync with that file if the limits move.
16const CAPS: readonly PlanRow[] = [
17 { label: 'price', free: '$0', pro: '$29.99 / mo', team: '$99.99 / mo' },
18 { label: 'projects per org', free: '3', pro: '20', team: '100' },
19 { label: 'functions per project', free: '20', pro: '200', team: '2,000' },
20 {
21 label: 'function invocations / month',
22 free: '100,000',
23 pro: '1,000,000',
24 team: '10,000,000',
25 },
26 { label: 'database storage', free: '1 GB', pro: '100 GB', team: '500 GB' },
27 {
28 label: 'realtime connection-seconds / month',
29 free: '1,000,000 (~12 days)',
30 pro: '10,000,000 (~115 days)',
31 team: '100,000,000 (~1,158 days)',
32 },
33 {
34 label: 'concurrent realtime subscriptions',
35 free: '100',
36 pro: '1,000',
37 team: '10,000',
38 },
39 {
40 label: 'auth monthly active users',
41 free: '1,000',
42 pro: '25,000',
43 team: '250,000',
44 },
45 {
46 label: 'support',
47 free: 'community (github)',
48 pro: 'email · 48h target',
49 team: 'priority email · 99.9% SLA',
50 },
51];
52
53export default function PricingPage() {
54 return (
55 <DocsShell>
56 <h1 className="font-mono text-2xl tracking-tight">pricing</h1>
57 <p className="mt-2 font-mono text-sm text-[var(--color-text-muted)]">
58 three tiers, one engine. start free, upgrade when a project outgrows the caps. prices
59 are in USD and exclude tax — VAT (or your local equivalent) is added at checkout for EU
60 customers, calculated from your billing country. billing runs on{' '}
61 <Link href="https://polar.sh" className="underline hover:text-[var(--color-text)]">
62 Polar
63 </Link>
64 , which is the merchant of record.
65 </p>
66
67 <div className="mt-8 grid gap-4 sm:grid-cols-3">
68 <PlanCard
69 name="free"
70 price="$0"
71 blurb="for kicking the tyres, side projects, and local dogfooding. no card required."
72 />
73 <PlanCard
74 name="pro"
75 price="$29.99"
76 period="/ mo"
77 blurb="for a production app: bigger caps, email support, and the 99.5% uptime SLA."
78 highlight
79 />
80 <PlanCard
81 name="team"
82 price="$99.99"
83 period="/ mo"
84 blurb="for teams shipping at scale: the largest caps, priority support, and a 99.9% SLA."
85 />
86 </div>
87
88 <section className="mt-12">
89 <h2 className="font-mono text-lg tracking-tight">what each tier includes</h2>
90 <div className="mt-3 overflow-x-auto">
91 <table className="w-full border-collapse font-mono text-xs">
92 <thead>
93 <tr className="border-b border-[var(--color-border-subtle)] text-left text-[var(--color-text-muted)]">
94 <th className="py-2 pr-4 font-normal">limit</th>
95 <th className="py-2 pr-4 font-normal">free</th>
96 <th className="py-2 pr-4 font-normal">pro</th>
97 <th className="py-2 pr-4 font-normal">team</th>
98 </tr>
99 </thead>
100 <tbody className="text-[var(--color-text)]">
101 {CAPS.map((row) => (
102 <tr key={row.label} className="border-b border-[var(--color-border-subtle)]">
103 <td className="py-2 pr-4 text-[var(--color-text-muted)]">{row.label}</td>
104 <td className="py-2 pr-4">{row.free}</td>
105 <td className="py-2 pr-4">{row.pro}</td>
106 <td className="py-2 pr-4">{row.team}</td>
107 </tr>
108 ))}
109 </tbody>
110 </table>
111 </div>
112 <p className="mt-3 font-mono text-xs text-[var(--color-text-subtle)]">
113 most caps are <em>soft</em> — they surface on the dashboard usage widget and feed
114 metered billing rather than hard-stopping your project. concurrent subscriptions and
115 the per-org project / function counts are hard caps, enforced at subscribe and deploy
116 time. invocations, storage, and connection-seconds bill as metered overage above the
117 included amount.
118 </p>
119 </section>
120
121 <section className="mt-10">
122 <h2 className="font-mono text-lg tracking-tight">how to upgrade</h2>
123 <p className="mt-2 font-mono text-sm text-[var(--color-text-muted)]">
124 upgrades happen in the dashboard — there is no sales call and no invoice to chase.
125 open your project, go to the <strong>billing</strong> page, pick Pro or Team, and
126 you&apos;ll be taken to a hosted Polar checkout. when the subscription is active the
127 project&apos;s tier flips automatically (usually within seconds). manage payment
128 method, see invoices, or cancel any time from the same billing page&apos;s customer
129 portal link.
130 </p>
131 <p className="mt-3 font-mono text-sm text-[var(--color-text-muted)]">
132 <Link
133 href="https://briven.tech"
134 className="text-[var(--color-text-link)] underline-offset-2 hover:underline"
135 >
136 open the dashboard → billing
137 </Link>{' '}
138 to upgrade. questions about a plan? reach us via{' '}
139 <Link
140 href="https://briven.tech/contact?topic=sales"
141 className="text-[var(--color-text-link)] underline-offset-2 hover:underline"
142 >
143 the contact form
144 </Link>
145 .
146 </p>
147 </section>
148
149 <section className="mt-10">
150 <h2 className="font-mono text-lg tracking-tight">tax + billing notes</h2>
151 <ul className="mt-3 flex list-disc flex-col gap-2 pl-5 font-mono text-sm text-[var(--color-text-muted)]">
152 <li>
153 prices shown are exclusive of tax. EU customers see VAT added at checkout based on
154 their billing country; valid business VAT numbers can be entered in the Polar
155 checkout for reverse-charge where applicable.
156 </li>
157 <li>
158 you&apos;re billed monthly. metered overage (extra invocations, storage,
159 connection-seconds beyond the included amount) is reconciled on the following
160 invoice.
161 </li>
162 <li>
163 free-tier projects are best-effort with no SLA; see the{' '}
164 <Link
165 href="/sla"
166 className="text-[var(--color-text-link)] underline-offset-2 hover:underline"
167 >
168 service level agreement
169 </Link>{' '}
170 for the Pro / Team uptime commitments and credit schedule.
171 </li>
172 </ul>
173 </section>
174 </DocsShell>
175 );
176}
177
178function PlanCard({
179 name,
180 price,
181 period,
182 blurb,
183 highlight,
184}: {
185 name: string;
186 price: string;
187 period?: string;
188 blurb: string;
189 highlight?: boolean;
190}) {
191 return (
192 <div
193 className={`rounded-md border p-5 ${
194 highlight
195 ? 'border-[var(--color-primary)] bg-[var(--color-surface)]'
196 : 'border-[var(--color-border-subtle)]'
197 }`}
198 >
199 <p className="font-mono text-xs uppercase tracking-[0.12em] text-[var(--color-text-subtle)]">
200 {name}
201 </p>
202 <p className="mt-2 font-mono text-2xl tracking-tight text-[var(--color-text)]">
203 {price}
204 {period ? (
205 <span className="text-sm text-[var(--color-text-subtle)]">{period}</span>
206 ) : null}
207 </p>
208 <p className="mt-3 font-mono text-xs text-[var(--color-text-muted)]">{blurb}</p>
209 </div>
210 );
211}