Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Prices keep themselves current with what g1t pays | 1 | import { ArrowUpRight } from "lucide-react"; |
| 2 | ||
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 3 | import { type FeaturePlan, type FreeTier, MICROS_PER_DOLLAR, type Price } from "@g1t/contracts"; |
| Prices keep themselves current with what g1t pays | 4 | |
| 5 | import type { Route } from "./+types/pricing"; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 6 | import { wholeDollars } from "../lib/billing"; |
| Social cards for every page: og.g1t.sh | 7 | import { page } from "../lib/meta"; |
| Prices keep themselves current with what g1t pays | 8 | import { TimeAgo } from "../components/ui"; |
| 9 | import { billing } from "../lib/services.server"; | |
| 10 | ||
| Social cards for every page: og.g1t.sh | 11 | export function meta(args: Route.MetaArgs) { |
| 12 | return page(args, { | |
| 13 | title: "Pricing · g1t", | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 14 | description: |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 15 | "The forge is free. One plan, $20 a month per workspace with $10 of usage included; usage at what it costs g1t plus 20%. No seats, ever.", |
| Social cards for every page: og.g1t.sh | 16 | }); |
| Prices keep themselves current with what g1t pays | 17 | } |
| 18 | ||
| 19 | export async function loader() { | |
| Billing accounts, terms and enterprises; g1t is no longer free | 20 | const [book, status] = await Promise.all([billing.prices().catch(() => null), billing.status().catch(() => null)]); |
| 21 | return { book, free: status?.free ?? false }; | |
| Prices keep themselves current with what g1t pays | 22 | } |
| 23 | ||
| 24 | /** A price in dollars, with as many digits as it needs to say anything. */ | |
| 25 | function money(micros: number): string { | |
| 26 | const dollars = micros / MICROS_PER_DOLLAR; | |
| 27 | if (dollars >= 1) return `$${dollars.toFixed(2)}`; | |
| 28 | if (dollars >= 0.01) return `$${dollars.toFixed(3)}`; | |
| 29 | return `$${dollars.toPrecision(2)}`; | |
| 30 | } | |
| 31 | ||
| 32 | /** Per second is easier to read per minute. */ | |
| 33 | function perUnit(price: Price, micros: number): string { | |
| 34 | return price.unit === "second" ? `${money(micros * 60)} a minute` : `${money(micros)} per ${price.unit}`; | |
| 35 | } | |
| 36 | ||
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 37 | function gigabytes(bytes: number): string { |
| 38 | return `${Math.round((bytes / 1e9) * 10) / 10} GB`; | |
| 39 | } | |
| 40 | ||
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 41 | function count(n: number): string { |
| 42 | return n.toLocaleString("en-US"); | |
| 43 | } | |
| 44 | ||
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 45 | /** Price-book rows the table shows in rows of their own, or not at all. */ |
| 46 | const SHOWN_APART = new Set(["app_month", "agent_models", "agent_tokens", "gateway_models", "card_fee_percent", "card_fee_fixed"]); | |
| 47 | ||
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 48 | /** What the page says when billing cannot be reached: the published defaults. */ |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 49 | const DEFAULT_FREE: Required<FreeTier> = { |
| 50 | trialWorkspaceMicros: 5_000_000, | |
| 51 | trialMonthlyPoolMicros: 100_000_000, | |
| 52 | ossPoolMicros: 25_000_000, | |
| 53 | ossRepoMicros: 2_000_000, | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 54 | freePrivateStorageBytes: 1_000_000_000, |
| Audit logs are kept by plan: a week on free, 90 days on the plan, and what staff set for an account in sudo | 55 | auditRetentionDays: 7, |
| 56 | planAuditRetentionDays: 90, | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 57 | minChargeMicros: 5_000_000, |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 58 | gitOperationsIncluded: 50_000, |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 59 | paidStartCeilingMicros: 100_000_000, |
| 60 | overageForgiveCostMicros: 50_000_000, | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 61 | }; |
| 62 | ||
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 63 | const DEFAULT_PLAN: FeaturePlan = { |
| 64 | feature: "plan", | |
| 65 | title: "g1t", | |
| 66 | monthlyCents: 2000, | |
| 67 | includes: [ | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 68 | "$10 of usage each month at cost plus 20%, used first", |
| 69 | "Everyone in the workspace at one price, never per person", | |
| 70 | "Unlimited projects, previews and repositories", | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 71 | "Agents, checks, workflows, the merge queue, deployments and semantic search", |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 72 | "Usage past $10 is charged at cost plus 20%, up to your spend limit", |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 73 | ], |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 74 | overage: "Everything is metered from the first unit at what it costs g1t plus 20%. Unused included usage does not roll over.", |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 75 | }; |
| 76 | ||
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 77 | /** The ways to reach g1t about an enterprise account. */ |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 78 | const ENTERPRISE_MAIL = "mailto:hey@flagon.io?subject=Enterprise%20billing%20for%20g1t"; |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 79 | |
| Prices keep themselves current with what g1t pays | 80 | const HOW = [ |
| 81 | { | |
| 82 | title: "Our cost, passed through", | |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 83 | body: "Every sandbox second, build and app request costs g1t money at Cloudflare. Each is metered and charged at that cost plus 20%, from the first second and the first request. Models are charged at the provider's price with no markup, plus a flat agent rate per million tokens for what g1t adds around them, from prepaid AI credit. Use a little, pay a little.", |
| Prices keep themselves current with what g1t pays | 84 | }, |
| 85 | { | |
| 86 | title: "Prices follow costs, by themselves", | |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 87 | body: "Model runs are charged at what Cloudflare's AI Gateway priced each request at, so a provider's price change reaches you the same day. Every day, sandbox, build and app costs are checked against what Cloudflare billed g1t; when one moves, its price moves with it, and the change is listed below. The rest are Cloudflare's published prices, marked as such.", |
| Prices keep themselves current with what g1t pays | 88 | }, |
| 89 | { | |
| Prices are what g1t pays plus 20%, from the first second | 90 | title: "The 20% is the overhead", |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 91 | body: "It pays for running g1t and for building and keeping up the features you use. The same 20% on everything but models, whose overhead is the agent rate, and nothing bundled in.", |
| Prices are what g1t pays plus 20%, from the first second | 92 | }, |
| 93 | { | |
| Prices keep themselves current with what g1t pays | 94 | title: "No seats, ever", |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 95 | body: "Add as many people and agents as you like. A workspace pays one flat price for the plan, and for what it uses past what the plan includes.", |
| Prices keep themselves current with what g1t pays | 96 | }, |
| 97 | ]; | |
| 98 | ||
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 99 | /** One row of the free-and-plan table. */ |
| 100 | type Row = { what: string; free: string; plan: string; note?: string }; | |
| 101 | ||
| 102 | function rows(tier: Required<FreeTier>): Row[] { | |
| 103 | return [ | |
| 104 | { | |
| 105 | what: "The forge", | |
| 106 | free: "Free", | |
| 107 | plan: "Included", | |
| 108 | note: "Public and private repositories, issues, pull requests, reviews, protected branches, code owners, search and Explore.", | |
| 109 | }, | |
| 110 | { | |
| 111 | what: "Agents, checks, workflows, merge queue", | |
| 112 | free: "After a card check: the trial, and the open-source pool for checks, workflows and the merge queue on public repositories", | |
| 113 | plan: "From the plan's included usage, then at cost plus 20%", | |
| 114 | }, | |
| 115 | { | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 116 | what: "Projects and previews", |
| 117 | free: "Not available: deployments run on g1t's machines", | |
| 118 | plan: "Unlimited, and never charged for. An app no one visits costs nothing.", | |
| 119 | }, | |
| 120 | { | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 121 | what: "Deployments", |
| 122 | free: "Not available", | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 123 | plan: "Builds by the second, app requests, CPU time and custom domains, each from the first at cost plus 20%", |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 124 | }, |
| 125 | { | |
| 126 | what: "Semantic search", | |
| 127 | free: "After a card check, from the trial", | |
| 128 | plan: "From the plan's included usage, then at cost plus 20%", | |
| 129 | }, | |
| 130 | { | |
| 131 | what: "Private storage", | |
| 132 | free: `${gigabytes(tier.freePrivateStorageBytes)}, never charged. Past it, pushes to private repositories stop until you make room or start the plan.`, | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 133 | plan: `${gigabytes(tier.freePrivateStorageBytes)} free, then at cost plus 20%. Pushes never stop.`, |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 134 | note: "Public repositories are never charged for storage.", |
| 135 | }, | |
| 136 | { | |
| 137 | what: "Git operations", | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 138 | free: `${count(tier.gitOperationsIncluded)} a month, never charged. Past it, slowed to 60 an hour until the month turns.`, |
| 139 | plan: `${count(tier.gitOperationsIncluded)} a month free, then at cost plus 20%. Never slowed.`, | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 140 | note: "Clones, fetches and pushes through g1t.", |
| 141 | }, | |
| 142 | { | |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 143 | what: "Actions cache", |
| 144 | free: "2 GiB an entry and 10 GiB a repository, never charged", | |
| 145 | plan: "The same limits, with what it stores at cost plus 20%", | |
| 146 | }, | |
| 147 | { | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 148 | what: "Audit log", |
| 149 | free: `${tier.auditRetentionDays} days, with export`, | |
| Audit logs are kept by plan: a week on free, 90 days on the plan, and what staff set for an account in sudo | 150 | plan: `${tier.planAuditRetentionDays} days, with export`, |
| 151 | note: "Longer by arrangement. Older entries are deleted each day.", | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 152 | }, |
| Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar | 153 | { |
| 154 | what: "Secret scanning, push protection, vulnerability alerts, security updates", | |
| 155 | free: "Included", | |
| 156 | plan: "Included", | |
| 157 | note: "Custom patterns, validity checks, code scanning, dependency review and the security overview on private repositories are the Security and quality activation. On public repositories they are free.", | |
| 158 | }, | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 159 | { what: "Single sign-on", free: "On every plan, once it is built", plan: "On every plan, once it is built" }, |
| 160 | { what: "Members", free: "Unlimited", plan: "Unlimited" }, | |
| 161 | { | |
| 162 | what: "Usage past what is included", | |
| 163 | free: "Not possible: a free workspace never runs up a bill", | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 164 | plan: "Charged at cost plus 20%, up to a spend limit you set. No quotas: only your limit stops anything.", |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 165 | }, |
| 166 | ]; | |
| 167 | } | |
| 168 | ||
| Prices keep themselves current with what g1t pays | 169 | export default function Pricing({ loaderData }: Route.ComponentProps) { |
| Billing accounts, terms and enterprises; g1t is no longer free | 170 | const { book, free } = loaderData; |
| Prices keep themselves current with what g1t pays | 171 | const checked = book?.prices.map((p) => p.checkedAt).filter((at): at is string => !!at).sort().at(-1); |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 172 | const given = Object.fromEntries(Object.entries(book?.free ?? {}).filter(([, value]) => value != null)); |
| 173 | const tier: Required<FreeTier> = { ...DEFAULT_FREE, ...given }; | |
| 174 | const plan = book?.plans?.find((p) => p.feature === "plan") ?? DEFAULT_PLAN; | |
| Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar | 175 | // The Security and quality activation, as the price book prices it. |
| 176 | const securityPlan = book?.plans?.find((p) => p.feature === "security") ?? null; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 177 | const price = plan.monthlyCents / 100; |
| 178 | const dollars = wholeDollars; | |
| Prices keep themselves current with what g1t pays | 179 | return ( |
| 180 | <main className="mx-auto max-w-4xl px-4 py-12"> | |
| 181 | <p className="text-sm font-medium text-accent">Pricing</p> | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 182 | <h1 className="mt-2 text-3xl font-semibold tracking-tight sm:text-4xl">One plan, and usage at cost plus 20%</h1> |
| Prices keep themselves current with what g1t pays | 183 | <p className="mt-3 max-w-2xl text-muted"> |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 184 | The forge is free for everyone. Work that runs on g1t's machines is metered at what it costs g1t, plus 20%. The |
| 185 | numbers on this page are the live price book g1t charges from. | |
| Prices keep themselves current with what g1t pays | 186 | </p> |
| Billing accounts, terms and enterprises; g1t is no longer free | 187 | {free && ( |
| 188 | <div className="mt-5 rounded-xl border border-accent/30 bg-accent/5 px-4 py-3 text-sm"> | |
| 189 | <span className="font-medium">Free while g1t is being built out.</span>{" "} | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 190 | <span className="text-muted">Usage is recorded at these prices but not charged for now. The plan is charged.</span> |
| Billing accounts, terms and enterprises; g1t is no longer free | 191 | </div> |
| 192 | )} | |
| Prices keep themselves current with what g1t pays | 193 | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 194 | <section className="mt-10 rounded-xl border border-accent/40 bg-surface p-6"> |
| 195 | <div className="flex flex-wrap items-baseline justify-between gap-3"> | |
| 196 | <h2 className="text-xl font-semibold tracking-tight">{plan.title}</h2> | |
| 197 | <p> | |
| 198 | <span className="text-3xl font-semibold tabular-nums">${price}</span>{" "} | |
| 199 | <span className="text-sm text-muted">a month per workspace</span> | |
| 200 | </p> | |
| 201 | </div> | |
| 202 | <ul className="mt-4 space-y-1.5 text-sm text-muted"> | |
| 203 | {plan.includes.map((line) => ( | |
| 204 | <li key={line} className="flex gap-2"> | |
| 205 | <span aria-hidden className="text-accent"> | |
| 206 | ✓ | |
| 207 | </span> | |
| 208 | {line} | |
| 209 | </li> | |
| 210 | ))} | |
| 211 | </ul> | |
| 212 | <p className="mt-3 text-xs text-faint">{plan.overage}</p> | |
| 213 | <div className="mt-5 grid gap-5 border-t border-line pt-5 text-sm sm:grid-cols-2"> | |
| 214 | <div> | |
| 215 | <p className="font-medium">Where the ${price} goes</p> | |
| 216 | <p className="mt-1 text-muted"> | |
| 217 | $10 comes back to you as usage: agents, sandboxes, builds and deployments at cost plus 20%, used before | |
| 218 | anything else. The other $10 pays for running g1t, the free forge for everyone, and the people building it. | |
| 219 | </p> | |
| 220 | </div> | |
| 221 | <div> | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 222 | <p className="font-medium">No quotas</p> |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 223 | <p className="mt-1 text-muted"> |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 224 | No count of projects, previews, builds, requests or git operations ever stops a workspace on the plan. Past |
| 225 | the $10, usage is charged at cost plus 20%, and only your spend limit stops it. Unused included usage does | |
| 226 | not roll over. | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 227 | </p> |
| 228 | </div> | |
| 229 | </div> | |
| 230 | <p className="mt-5 text-sm text-muted">An owner starts the plan from the workspace's Billing page.</p> | |
| 231 | </section> | |
| 232 | ||
| Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar | 233 | {securityPlan && ( |
| 234 | <section id="security" className="mt-6 rounded-xl border border-line bg-surface p-6"> | |
| 235 | <div className="flex flex-wrap items-baseline justify-between gap-3"> | |
| 236 | <h2 className="text-xl font-semibold tracking-tight">{securityPlan.title}</h2> | |
| 237 | <p> | |
| 238 | <span className="text-3xl font-semibold tabular-nums">${(securityPlan.monthlyCents / 100).toFixed(securityPlan.monthlyCents % 100 ? 2 : 0)}</span>{" "} | |
| 239 | <span className="text-sm text-muted">a month per workspace</span> | |
| 240 | </p> | |
| 241 | </div> | |
| 242 | <p className="mt-2 text-sm text-muted"> | |
| 243 | An activation, with or without the plan: the security suite's paid parts for a workspace's private repositories. | |
| 244 | </p> | |
| 245 | <ul className="mt-4 space-y-1.5 text-sm text-muted"> | |
| 246 | {securityPlan.includes.map((line) => ( | |
| 247 | <li key={line} className="flex gap-2"> | |
| 248 | <span aria-hidden className="text-accent"> | |
| 249 | ✓ | |
| 250 | </span> | |
| 251 | {line} | |
| 252 | </li> | |
| 253 | ))} | |
| 254 | </ul> | |
| 255 | <p className="mt-3 text-xs text-faint">{securityPlan.overage}</p> | |
| 256 | </section> | |
| 257 | )} | |
| 258 | ||
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 259 | <h2 className="mt-14 text-xl font-semibold tracking-tight">Free and the plan, side by side</h2> |
| Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar | 260 | <p className="mt-1 text-sm text-muted"> |
| 261 | Secret scanning, push protection, vulnerability alerts and security updates are free everywhere, on every plan. | |
| 262 | </p> | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 263 | {/* On a phone, one row at a time with both answers under it; a table that wide would scroll. */} |
| 264 | <ul className="mt-4 divide-y divide-line rounded-xl border border-line text-sm sm:hidden"> | |
| 265 | {rows(tier).map((row) => ( | |
| 266 | <li key={row.what} className="px-4 py-3"> | |
| 267 | <p className="font-medium">{row.what}</p> | |
| 268 | {row.note && <p className="text-xs text-faint">{row.note}</p>} | |
| 269 | <dl className="mt-2 grid grid-cols-[4.5rem_1fr] gap-x-3 gap-y-1.5"> | |
| 270 | <dt className="text-xs leading-5 text-faint">Free</dt> | |
| 271 | <dd className="text-muted">{row.free}</dd> | |
| 272 | <dt className="text-xs leading-5 text-faint">{plan.title}</dt> | |
| 273 | <dd className="text-muted">{row.plan}</dd> | |
| 274 | </dl> | |
| 275 | </li> | |
| 276 | ))} | |
| 277 | </ul> | |
| 278 | <div className="mt-4 hidden overflow-x-auto rounded-xl border border-line sm:block"> | |
| 279 | <table className="w-full min-w-[36rem] text-left text-sm"> | |
| 280 | <thead className="border-b border-line text-xs text-muted"> | |
| 281 | <tr> | |
| 282 | <th className="px-4 py-2.5 font-medium"> | |
| 283 | <span className="sr-only">What</span> | |
| 284 | </th> | |
| 285 | <th className="px-4 py-2.5 font-medium">Free</th> | |
| 286 | <th className="px-4 py-2.5 font-medium"> | |
| 287 | {plan.title}, ${price} a month | |
| 288 | </th> | |
| 289 | </tr> | |
| 290 | </thead> | |
| 291 | <tbody className="divide-y divide-line"> | |
| 292 | {rows(tier).map((row) => ( | |
| 293 | <tr key={row.what} className="align-top"> | |
| 294 | <td className="px-4 py-3"> | |
| 295 | <p className="font-medium">{row.what}</p> | |
| 296 | {row.note && <p className="text-xs text-faint">{row.note}</p>} | |
| 297 | </td> | |
| 298 | <td className="px-4 py-3 text-muted">{row.free}</td> | |
| 299 | <td className="px-4 py-3 text-muted">{row.plan}</td> | |
| 300 | </tr> | |
| 301 | ))} | |
| 302 | </tbody> | |
| 303 | </table> | |
| 304 | </div> | |
| 305 | <p className="mt-3 text-sm text-muted"> | |
| 306 | Git operations cost g1t money too: Cloudflare charges g1t $0.15 per 1,000. {count(tier.gitOperationsIncluded)} a | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 307 | month is far more than an active workspace uses; an agent run takes two to four. |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 308 | </p> |
| 309 | ||
| 310 | <h2 className="mt-14 text-xl font-semibold tracking-tight">No card, no compute</h2> | |
| 311 | <div className="mt-3 max-w-3xl space-y-3 text-sm text-muted"> | |
| 312 | <p> | |
| 313 | Agents, checks, workflows, the merge queue, deployments and semantic search run on g1t's machines. They need | |
| 314 | the plan, or a card check. | |
| 315 | </p> | |
| 316 | <p> | |
| 317 | The reason: compute costs g1t real money from the first second, and free compute draws people who use it to | |
| 318 | mine cryptocurrency. A card check is the smallest gate that stops that, with one trial per card. | |
| 319 | </p> | |
| 320 | <p> | |
| 321 | A card check is never charged. Stripe saves and verifies the card, with 3-D Secure where your bank asks for it. | |
| 322 | Nothing is charged until an owner starts the plan, and then the same card is used, without asking for it again. | |
| 323 | The trial needs a credit or debit card; prepaid cards can still pay for the plan. | |
| 324 | </p> | |
| 325 | </div> | |
| 326 | ||
| 327 | <div className="mt-5 grid gap-4 sm:grid-cols-2"> | |
| 328 | <section className="rounded-xl border border-line bg-surface p-5"> | |
| 329 | <h3 className="font-medium">The trial</h3> | |
| 330 | <p className="mt-1.5 text-sm text-muted"> | |
| 331 | {dollars(tier.trialWorkspaceMicros)} of usage, once per workspace and once per card, after a card check with a credit or | |
| 332 | debit card. It comes from a{" "} | |
| 333 | {dollars(tier.trialMonthlyPoolMicros)} pool each month for everyone; when a month's pool is given out, new | |
| 334 | trials wait until the 1st. The trial does not cover deployments and never turns into a charge. If the last | |
| 335 | run on a trial goes past it, g1t covers the difference. | |
| 336 | </p> | |
| 337 | </section> | |
| 338 | <section className="rounded-xl border border-line bg-surface p-5"> | |
| 339 | <h3 className="font-medium">The open-source pool</h3> | |
| 340 | <p className="mt-1.5 text-sm text-muted"> | |
| 341 | Checks, workflows and the merge queue on public repositories, after a card check:{" "} | |
| 342 | {dollars(tier.ossPoolMicros)} a month in all, up to {dollars(tier.ossRepoMicros)} a month per repository. | |
| 343 | Agents do not run from the pool. When the pool or a repository's share is used up, the work waits for the | |
| 344 | month to turn, or the workspace pays as usual. | |
| 345 | </p> | |
| 346 | </section> | |
| 347 | </div> | |
| 348 | ||
| 349 | <h2 className="mt-14 text-xl font-semibold tracking-tight">Limits, and how to raise them</h2> | |
| 350 | <p className="mt-1 max-w-3xl text-sm text-muted"> | |
| 351 | g1t lets usage run ahead of payment only so far. Limits keep a mistake small, for you and for g1t. | |
| 352 | </p> | |
| 353 | <ul className="mt-4 grid gap-3 text-sm sm:grid-cols-2"> | |
| 354 | <li className="rounded-xl border border-line bg-surface p-4"> | |
| 355 | <p className="font-medium">{dollars(tier.paidStartCeilingMicros)} in the first month</p> | |
| 356 | <p className="mt-1 text-muted"> | |
| 357 | A workspace on the plan can use up to {dollars(tier.paidStartCeilingMicros)} in its first month. After that, | |
| 358 | the limit grows with payments that clear. | |
| 359 | </p> | |
| 360 | </li> | |
| 361 | <li className="rounded-xl border border-line bg-surface p-4"> | |
| 362 | <p className="font-medium">Your own spend limit</p> | |
| 363 | <p className="mt-1 text-muted"> | |
| 364 | Owners set a monthly spend limit anywhere up to the highest limit the workspace has had, with no approval. | |
| 365 | Once, you can raise it yourself to twice that. | |
| 366 | </p> | |
| 367 | </li> | |
| 368 | <li className="rounded-xl border border-line bg-surface p-4"> | |
| 369 | <p className="font-medium">Prepay to raise it now</p> | |
| 370 | <p className="mt-1 text-muted"> | |
| 371 | Prepaying from $25 raises what you can use by the same amount, at once. From $1,000 you can also pay by bank | |
| 372 | transfer. | |
| 373 | </p> | |
| 374 | </li> | |
| 375 | <li className="rounded-xl border border-line bg-surface p-4"> | |
| 376 | <p className="font-medium">Raise my limit</p> | |
| 377 | <p className="mt-1 text-muted"> | |
| 378 | Need more? Ask from Billing with the amount, why, and what you expect to spend. You get an answer within one | |
| 379 | business day, in the app and by email. | |
| 380 | </p> | |
| 381 | </li> | |
| 382 | </ul> | |
| 383 | ||
| 384 | <h2 className="mt-14 text-xl font-semibold tracking-tight">When usage runs high</h2> | |
| 385 | <ul className="mt-4 grid gap-3 text-sm sm:grid-cols-2"> | |
| 386 | <li className="rounded-xl border border-line bg-surface p-4"> | |
| 387 | <p className="font-medium">A spike pauses new work</p> | |
| 388 | <p className="mt-1 text-muted"> | |
| 389 | When an hour's spend is five times your usual hour, and at least $5, new compute waits for an owner to choose | |
| 390 | Keep going or Stop. Runs already going finish. | |
| 391 | </p> | |
| 392 | </li> | |
| 393 | <li className="rounded-xl border border-line bg-surface p-4"> | |
| 394 | <p className="font-medium">Caps per run and per issue</p> | |
| 395 | <p className="mt-1 text-muted"> | |
| 396 | One agent run stops at $2 and the agents on one issue at $10 in all, so a run stuck in a loop stops on its own. | |
| 397 | Owners change both on Billing. | |
| 398 | </p> | |
| 399 | </li> | |
| 400 | <li className="rounded-xl border border-line bg-surface p-4"> | |
| 401 | <p className="font-medium">Alerts at 50, 75, 90 and 100%</p> | |
| 402 | <p className="mt-1 text-muted"> | |
| 403 | Of the plan's included usage, your spend limit and g1t's limit: in the app and by email. | |
| 404 | </p> | |
| 405 | </li> | |
| 406 | <li className="rounded-xl border border-line bg-surface p-4"> | |
| 407 | <p className="font-medium">Spent more than you meant to? Tell us</p> | |
| 408 | <p className="mt-1 text-muted"> | |
| 409 | Tell us from Billing what happened. Once in 12 months, g1t can credit back usage you did not mean, always | |
| 410 | including its 20% on it. Larger credits, or a second one within 12 months, are reviewed by a person. | |
| 411 | </p> | |
| 412 | </li> | |
| 413 | </ul> | |
| 414 | <p className="mt-3 text-sm text-muted"> | |
| 415 | No card is charged less than {dollars(tier.minChargeMicros)} when a month closes, so a payment's fee is never most | |
| 416 | of it. Smaller amounts carry over to the next invoice. Charges at a limit always go through. | |
| 417 | </p> | |
| 418 | ||
| 419 | <div className="mt-14 grid gap-4 sm:grid-cols-2"> | |
| Prices keep themselves current with what g1t pays | 420 | {HOW.map((item) => ( |
| 421 | <section key={item.title} className="rounded-xl border border-line bg-surface p-5"> | |
| 422 | <h2 className="font-medium">{item.title}</h2> | |
| 423 | <p className="mt-1.5 text-sm text-muted">{item.body}</p> | |
| 424 | </section> | |
| 425 | ))} | |
| 426 | </div> | |
| 427 | ||
| 428 | <h2 className="mt-14 text-xl font-semibold tracking-tight">Usage</h2> | |
| 429 | <p className="mt-1 text-sm text-muted"> | |
| 430 | {checked ? ( | |
| 431 | <> | |
| 432 | Last checked against Cloudflare's bill <TimeAgo at={checked} />. | |
| 433 | </> | |
| 434 | ) : ( | |
| 435 | "Starting from Cloudflare's published prices; checked against its bill daily." | |
| 436 | )} | |
| 437 | </p> | |
| 438 | <div className="mt-4 overflow-x-auto rounded-xl border border-line"> | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 439 | <table className="w-full text-left text-sm sm:min-w-[36rem]"> |
| Prices keep themselves current with what g1t pays | 440 | <thead className="border-b border-line text-xs text-muted"> |
| 441 | <tr> | |
| 442 | <th className="px-4 py-2.5 font-medium">What</th> | |
| 443 | <th className="px-4 py-2.5 font-medium">Costs g1t</th> | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 444 | {/* The markup is in what you pay; on a phone the column gives way. */} |
| 445 | <th className="hidden px-4 py-2.5 font-medium sm:table-cell">Markup</th> | |
| Prices keep themselves current with what g1t pays | 446 | <th className="px-4 py-2.5 font-medium">You pay</th> |
| 447 | </tr> | |
| 448 | </thead> | |
| 449 | <tbody className="divide-y divide-line"> | |
| 450 | <tr> | |
| 451 | <td className="px-4 py-3"> | |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 452 | <p className="font-medium">Agent models</p> |
| 453 | <p className="text-xs text-faint">g1t's hosted models for agent runs, paid from AI credit</p> | |
| Prices keep themselves current with what g1t pays | 454 | </td> |
| 455 | <td className="px-4 py-3 text-muted">What the provider charges, per request</td> | |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 456 | <td className="hidden px-4 py-3 tabular-nums sm:table-cell">{book?.modelMarginPercent ?? 0}%</td> |
| 457 | <td className="px-4 py-3 text-muted">{book?.modelMarginPercent ? `Cost + ${book.modelMarginPercent}%` : "The provider's price"}</td> | |
| Prices keep themselves current with what g1t pays | 458 | </tr> |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 459 | {(() => { |
| 460 | const rate = book?.prices.find((p) => p.meter === "agent_tokens"); | |
| 461 | const gateway = book?.prices.find((p) => p.meter === "gateway_models"); | |
| 462 | const feePercent = book?.prices.find((p) => p.meter === "card_fee_percent"); | |
| 463 | const feeFixed = book?.prices.find((p) => p.meter === "card_fee_fixed"); | |
| 464 | const coming = book?.changes.find((c) => c.meter === "agent_tokens" && c.effectiveAt); | |
| 465 | return ( | |
| 466 | <> | |
| 467 | <tr> | |
| 468 | <td className="px-4 py-3"> | |
| 469 | <p className="font-medium">g1t agent rate</p> | |
| 470 | <p className="text-xs text-faint">Context, memory, routing and orchestration, on every token an agent run uses</p> | |
| 471 | </td> | |
| 472 | <td className="px-4 py-3 text-muted">A flat rate</td> | |
| 473 | <td className="hidden px-4 py-3 tabular-nums sm:table-cell">—</td> | |
| 474 | <td className="px-4 py-3 font-mono text-xs tabular-nums"> | |
| 475 | {rate && rate.priceMicros > 0 ? `${money(rate.priceMicros)} per million tokens` : coming ? `${money(coming.newCostMicros)} per million tokens from ${coming.effectiveAt!.slice(0, 10)}` : "$0.25 per million tokens"} | |
| 476 | </td> | |
| 477 | </tr> | |
| 478 | <tr> | |
| 479 | <td className="px-4 py-3"> | |
| 480 | <p className="font-medium"> | |
| 481 | AI Gateway <span className="ml-1 rounded bg-accent/15 px-1.5 py-0.5 text-xs text-accent">Free during beta</span> | |
| 482 | </p> | |
| 483 | <p className="text-xs text-faint">Your own apps calling models through g1t; your own key is free on the plan</p> | |
| 484 | </td> | |
| 485 | <td className="px-4 py-3 text-muted">What the provider charges</td> | |
| 486 | <td className="hidden px-4 py-3 tabular-nums sm:table-cell">{gateway?.markupPercent ?? 0}%</td> | |
| 487 | <td className="px-4 py-3 text-muted">{gateway?.markupPercent ? `Cost + ${gateway.markupPercent}%` : "The provider's price"}</td> | |
| 488 | </tr> | |
| 489 | {feePercent && feeFixed && ( | |
| 490 | <tr> | |
| 491 | <td className="px-4 py-3"> | |
| 492 | <p className="font-medium">Card processing fee</p> | |
| 493 | <p className="text-xs text-faint">On AI credit bought by card, as its own line at checkout; never on invoices</p> | |
| 494 | </td> | |
| 495 | <td className="px-4 py-3 text-muted">Stripe's fee</td> | |
| 496 | <td className="hidden px-4 py-3 tabular-nums sm:table-cell">—</td> | |
| 497 | <td className="px-4 py-3 font-mono text-xs tabular-nums"> | |
| 498 | {(feePercent.priceMicros / 10_000).toFixed(1)}% + {money(feeFixed.priceMicros)} | |
| 499 | </td> | |
| 500 | </tr> | |
| 501 | )} | |
| 502 | </> | |
| 503 | ); | |
| 504 | })()} | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 505 | <tr> |
| 506 | <td className="px-4 py-3"> | |
| 507 | <p className="font-medium">Projects, previews and apps</p> | |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 508 | <p className="text-xs text-faint">Having them. An app's requests and CPU time are charged below.</p> |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 509 | </td> |
| 510 | <td className="px-4 py-3 text-muted">Next to nothing</td> | |
| 511 | <td className="hidden px-4 py-3 tabular-nums sm:table-cell">—</td> | |
| 512 | <td className="px-4 py-3 text-muted">Not charged</td> | |
| 513 | </tr> | |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 514 | {(book?.prices ?? []).filter((price) => !SHOWN_APART.has(price.meter)).map((price) => ( |
| Prices keep themselves current with what g1t pays | 515 | <tr key={price.meter}> |
| 516 | <td className="px-4 py-3"> | |
| 517 | <p className="font-medium">{price.title}</p> | |
| 518 | <p className="text-xs text-faint"> | |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 519 | {price.meter === "actions_cache" ? "On the plan only. A free workspace is never charged for it. " : ""} |
| Prices keep themselves current with what g1t pays | 520 | {price.source === "cloudflare" ? "Measured from Cloudflare's bill" : "Cloudflare's published price"} |
| 521 | </p> | |
| 522 | </td> | |
| 523 | <td className="px-4 py-3 font-mono text-xs tabular-nums text-muted">{perUnit(price, price.costMicros)}</td> | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 524 | <td className="hidden px-4 py-3 tabular-nums sm:table-cell">{price.markupPercent}%</td> |
| Prices keep themselves current with what g1t pays | 525 | <td className="px-4 py-3 font-mono text-xs tabular-nums">{perUnit(price, price.priceMicros)}</td> |
| 526 | </tr> | |
| 527 | ))} | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 528 | </tbody> |
| 529 | </table> | |
| 530 | </div> | |
| 531 | ||
| 532 | <h2 className="mt-14 text-xl font-semibold tracking-tight">Enterprise</h2> | |
| 533 | <p className="mt-1 text-sm text-muted"> | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 534 | For organizations with several workspaces: one invoice and one limit. The prices are the ones on this page. |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 535 | </p> |
| Prices keep themselves current with what g1t pays | 536 | <section className="mt-4 rounded-xl border border-line bg-surface p-5"> |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 537 | <ul className="grid gap-3 text-sm sm:grid-cols-2"> |
| 538 | <li> | |
| 539 | <p className="font-medium">Consolidated invoicing</p> | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 540 | <p className="text-muted">One monthly invoice for every workspace, paid by card or bank transfer.</p> |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 541 | </li> |
| 542 | <li> | |
| 543 | <p className="font-medium">Custom terms</p> | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 544 | <p className="text-muted">One limit across every workspace, invoice terms and a billing contact, set with you.</p> |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 545 | </li> |
| 546 | <li> | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 547 | <p className="font-medium">Security on every plan</p> |
| 548 | <p className="text-muted"> | |
| Audit logs are kept by plan: a week on free, 90 days on the plan, and what staff set for an account in sudo | 549 | The audit log with export, {tier.planAuditRetentionDays} days or longer by arrangement, and secret push |
| 550 | protection, for every workspace. | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 551 | </p> |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 552 | </li> |
| 553 | <li> | |
| 554 | <p className="font-medium"> | |
| 555 | Single sign-on <span className="ml-1 rounded bg-raised px-1.5 py-0.5 text-xs text-muted">Coming</span> | |
| 556 | </p> | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 557 | <p className="text-muted">Through your identity provider, on every plan once it is built. Not available yet.</p> |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 558 | </li> |
| 559 | </ul> | |
| 560 | <a | |
| 561 | href={ENTERPRISE_MAIL} | |
| 562 | className="mt-5 inline-flex items-center gap-1.5 rounded-md border border-line px-3 py-1.5 text-sm hover:border-line-strong" | |
| 563 | > | |
| 564 | Write to us about enterprise | |
| 565 | <ArrowUpRight size={14} /> | |
| 566 | </a> | |
| Prices keep themselves current with what g1t pays | 567 | </section> |
| 568 | ||
| 569 | <h2 className="mt-14 text-xl font-semibold tracking-tight">Price changes</h2> | |
| 570 | {book && book.changes.length > 0 ? ( | |
| 571 | <ul className="mt-4 divide-y divide-line rounded-xl border border-line"> | |
| 572 | {book.changes.map((change) => { | |
| 573 | const title = book.prices.find((p) => p.meter === change.meter)?.title ?? change.meter; | |
| Prices are what g1t pays plus 20%, from the first second | 574 | // What you pay moved: the cost, the markup, or both. |
| 575 | const before = change.oldCostMicros * (100 + (change.oldMarkupPercent ?? change.markupPercent)); | |
| 576 | const after = change.newCostMicros * (100 + change.markupPercent); | |
| 577 | const up = after > before; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 578 | const fresh = after === before || before === 0; |
| Prices keep themselves current with what g1t pays | 579 | return ( |
| 580 | <li key={`${change.meter}-${change.createdAt}`} className="px-4 py-3 text-sm"> | |
| 581 | <p> | |
| 582 | <span className="font-medium">{title}</span>{" "} | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 583 | {fresh ? ( |
| 584 | <span className="text-muted">new</span> | |
| 585 | ) : ( | |
| 586 | <span className={up ? "text-warn" : "text-accent"}> | |
| 587 | {up ? "up" : "down"} {Math.abs((after / before - 1) * 100).toFixed(1)}% | |
| 588 | </span> | |
| 589 | )} | |
| Prices keep themselves current with what g1t pays | 590 | </p> |
| 591 | <p className="mt-0.5 text-xs text-faint"> | |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 592 | {change.effectiveAt ? ( |
| 593 | <> | |
| 594 | {change.reason} · <span className="text-fg-soft">takes effect {change.effectiveAt.slice(0, 10)}</span> | |
| 595 | </> | |
| 596 | ) : ( | |
| 597 | <> | |
| 598 | {change.reason} · <TimeAgo at={change.createdAt} /> | |
| 599 | </> | |
| 600 | )} | |
| Prices keep themselves current with what g1t pays | 601 | </p> |
| 602 | </li> | |
| 603 | ); | |
| 604 | })} | |
| 605 | </ul> | |
| 606 | ) : ( | |
| Prices are what g1t pays plus 20%, from the first second | 607 | <p className="mt-2 text-sm text-muted">None yet. When a price moves, it is listed here with why.</p> |
| Prices keep themselves current with what g1t pays | 608 | )} |
| 609 | ||
| 610 | <a | |
| 611 | href="https://docs.g1t.sh/guides/usage-and-billing/" | |
| 612 | className="mt-12 inline-flex items-center gap-1.5 text-sm text-accent hover:underline" | |
| 613 | > | |
| 614 | How usage and billing work | |
| 615 | <ArrowUpRight size={14} /> | |
| 616 | </a> | |
| 617 | </main> | |
| 618 | ); | |
| 619 | } |