From da23c87f5a61e60449d46a1cdd99b9eea43466ed Mon Sep 17 00:00:00 2001 From: Nicholas Kissel Date: Tue, 2 Dec 2025 13:22:35 -0800 Subject: [PATCH] chore(site): pricing --- website/public/llms-full.txt | 256 ---- .../(index)/sections/RedesignedHero.tsx | 2 + .../(marketing)/pricing/PricingPageClient.tsx | 1338 +++++++++-------- .../solutions/collaborative-state/page.tsx | 2 + .../solutions/user-session-store/page.tsx | 2 + website/src/app/(v2)/[section]/doc-page.tsx | 2 + website/src/app/(v2)/[section]/util.ts | 2 + website/src/components/Header.jsx | 2 +- website/src/components/Navigation.jsx | 2 +- website/src/components/v2/Header.tsx | 6 +- .../posts/2025-11-02-weekly-updates/page.mdx | 6 +- 11 files changed, 764 insertions(+), 856 deletions(-) diff --git a/website/public/llms-full.txt b/website/public/llms-full.txt index 6744fdbd6a..af3dfd6eda 100644 --- a/website/public/llms-full.txt +++ b/website/public/llms-full.txt @@ -182,262 +182,6 @@ See [helper types](/docs/actors/helper-types) for more details on using `ActionC - [`ActorDefinition`](/typedoc/interfaces/rivetkit.mod.ActorDefinition.html) - Interface for defining actors with actions - [`ActorHandle`](/typedoc/types/rivetkit.client_mod.ActorHandle.html) - Handle for calling actions from client - [`ActorActionFunction`](/typedoc/types/rivetkit.client_mod.ActorActionFunction.html) - Type for action functions -## AI and User-Generated Rivet Actors - -# AI and User-Generated Rivet Actors - -Deploy AI or user-generated Rivet Actor code with sandboxed namespaces and serverless infrastructure. - -Complete example showing how to deploy user-generated Rivet Actor code. - -## Overview - -This guide shows you how to programmatically create isolated Rivet environments and deploy custom actor code to them. This pattern is useful for: - -- **AI-generated code deployments** - Deploy code generated by LLMs in isolated environments -- **User sandbox environments** - Give users their own isolated Rivet namespace to experiment -- **Preview deployments** - Create ephemeral environments for testing pull requests -- **Multi-tenant applications** - Isolate each customer in their own namespace - -## How It Works - -The deployment process involves four key steps: - -1. **Create sandboxed Rivet namespace** - Programmatically create an isolated Rivet namespace using the Cloud API or self-hosted Rivet API -2. **Generate tokens** - Create the necessary tokens for authentication (runner, publishable, and access tokens) -3. **Deploy to Freestyle** - Deploy the actor code and frontend to Freestyle's serverless platform -4. **Configure runner** - Connect Rivet to the Freestyle deployment so actors can be executed - -## Sandboxed Rivet Namespaces - -Rivet provides the ability to create sandboxed namespaces programmatically. Each namespace is completely isolated with its own: - -- Actor instances and state -- Authentication tokens -- Configuration settings -- Resource limits - -Namespaces can be created on-demand through the Rivet API, making them perfect for scenarios where you need to quickly spin up isolated environments. - -## Deploying Code to Freestyle - -[Freestyle](https://docs.freestyle.sh/web/overview) is a serverless platform optimized for deploying JavaScript/TypeScript code, particularly code written by users or AI systems. It provides: - -- Fast cold starts (around 5ms) -- Automatic TLS certificates -- Built-in security for untrusted code -- Easy deployment API - -We use Freestyle to host the backend logic for your Rivet Actors, making it easy to deploy custom code without managing infrastructure. - -## Setup - - 1. Visit your project on [Rivet Cloud](https://dashboard.rivet.dev/) - 2. Click on "Tokens" in the sidebar - 3. Under "Cloud API Tokens" click "Create Token" - 4. Copy the token for use in your deployment script - - Create a deployment script that handles namespace creation, token generation, Freestyle deployment, and runner configuration. - - This code demonstrates the complete flow for deploying user-generated Rivet Actor code to Freestyle with Rivet Cloud: - - ```typescript - // Configuration - const CLOUD_API_URL = "https://api.rivet.dev/cloud"; - const CLOUD_API_TOKEN = "your-cloud-api-token"; - const ENGINE_ENDPOINT = "https://api.rivet.dev"; - const FREESTYLE_DOMAIN = "your-app.style.dev"; - const FREESTYLE_API_KEY = "your-freestyle-api-key"; - const DATACENTER = "us-west-1"; - - async function deploy(registryCode: string, appCode: string) ); - - const = await cloudRivet.apiTokens.inspect(); - const namespaceName = `ns-$-$`; - - const = await cloudRivet.namespaces.create(project, ); - - // Step 2: Generate tokens - const = await cloudRivet.namespaces.createSecretToken( - project, - namespace.name, - -runner-token`, - org: organization, - }, - ); - - const = await cloudRivet.namespaces.createPublishableToken( - project, - namespace.name, - , - ); - - const = await cloudRivet.namespaces.createAccessToken( - project, - namespace.name, - , - ); - - // Step 3: Deploy to Freestyle - // Build your project directory with the custom registry and app code - // See the example repository for the complete template structure - const freestyle = new FreestyleSandboxes(); - const deploymentSource = prepareDirForDeploymentSync(projectDir); - - const = await freestyle.deployWeb(deploymentSource, `, - RIVET_RUNNER_KIND: "serverless", - VITE_RIVET_ENDPOINT: ENGINE_ENDPOINT, - VITE_RIVET_NAMESPACE: namespace.access.engineNamespaceName, - VITE_RIVET_TOKEN: publishableToken, - VITE_RIVET_DATACENTER: DATACENTER, - RIVET_ENDPOINT: ENGINE_ENDPOINT, - RIVET_NAMESPACE: namespace.access.engineNamespaceName, - RIVET_RUNNER_TOKEN: runnerToken, - RIVET_PUBLISHABLE_TOKEN: publishableToken, - }, - timeout: 60 * 5, - entrypoint: "src/backend/server.ts", - domains: [FREESTYLE_DOMAIN], - build: false, - }); - - // Step 4: Configure Rivet runner - const engineRivet = new RivetClient(); - - await engineRivet.runnerConfigsUpsert("default", /api/rivet`, - headers: , - runnersMargin: 1, - minRunners: 1, - maxRunners: 1, - slotsPerRunner: 1, - requestLifespan: 60 * 4 + 30, - }, - }, - }, - namespace: namespace.access.engineNamespaceName, - }); - - return /projects/$/ns/$`, - freestyleUrl: `https://admin.freestyle.sh/dashboard/deployments/$`, - }; - } - ``` - - **Step 1: Create sandboxed namespace** - Uses the Cloud API to create a new isolated namespace with a unique name. - - **Step 2: Generate tokens** - Creates three types of tokens: runner token (for executing actors), publishable token (for frontend clients), and access token (for API access). - - **Step 3: Deploy to Freestyle** - Deploys the actor code and frontend to Freestyle with all necessary environment variables configured. The deployment uses a 5-minute timeout to handle long-running operations. - - **Step 4: Configure runner** - Configures Rivet to route actor execution requests to the Freestyle deployment. The runner config specifies scaling limits and request lifespans. - - See the [example repository](https://github.com/rivet-dev/rivet/tree/main/examples/ai-and-user-generated-actors-freestyle) for the complete project structure including the template directory and build process. - - For self-hosted Rivet, you'll need: - - Your Rivet Engine endpoint (e.g., `http://your-rivet-instance:6420`) - - An API token with permissions to create namespaces - - See the [self-hosting documentation](/docs/self-hosting) for details on setting up authentication. - - Create a deployment script for self-hosted Rivet. - - This code demonstrates the complete flow for deploying user-generated Rivet Actor code to Freestyle with self-hosted Rivet: - - ```typescript - // Configuration - const RIVET_ENDPOINT = "http://your-rivet-instance:6420"; - const RIVET_TOKEN = "your-rivet-token"; - const FREESTYLE_DOMAIN = "your-app.style.dev"; - const FREESTYLE_API_KEY = "your-freestyle-api-key"; - const DATACENTER = "us-west-1"; - - async function deploy(registryCode: string, appCode: string) ); - - const namespaceName = `ns-$-$`; - - const = await rivet.namespaces.create(); - - // Step 2: Generate tokens (use the same token for self-hosted) - // For self-hosted, you typically use the same token for all operations - const token = RIVET_TOKEN; - - // Step 3: Deploy to Freestyle - // Build your project directory with the custom registry and app code - // See the example repository for the complete template structure - const freestyle = new FreestyleSandboxes(); - const deploymentSource = prepareDirForDeploymentSync(projectDir); - - const = await freestyle.deployWeb(deploymentSource, `, - RIVET_RUNNER_KIND: "serverless", - VITE_RIVET_ENDPOINT: RIVET_ENDPOINT, - VITE_RIVET_NAMESPACE: namespace.name, - VITE_RIVET_TOKEN: token, - VITE_RIVET_DATACENTER: DATACENTER, - RIVET_ENDPOINT: RIVET_ENDPOINT, - RIVET_NAMESPACE: namespace.name, - RIVET_RUNNER_TOKEN: token, - RIVET_PUBLISHABLE_TOKEN: token, - }, - timeout: 60 * 5, - entrypoint: "src/backend/server.ts", - domains: [FREESTYLE_DOMAIN], - build: false, - }); - - // Step 4: Configure Rivet runner - await rivet.runnerConfigsUpsert("default", /api/rivet`, - headers: , - runnersMargin: 1, - minRunners: 1, - maxRunners: 1, - slotsPerRunner: 1, - requestLifespan: 60 * 4 + 30, - }, - }, - }, - namespace: namespace.name, - }); - - return `, - }; - } - ``` - - **Step 1: Create sandboxed namespace** - Creates a new isolated namespace using the self-hosted Rivet API. - - **Step 2: Generate tokens** - For self-hosted Rivet, you typically use the same token for all operations. The token system is simpler than Rivet Cloud. - - **Step 3: Deploy to Freestyle** - Deploys the actor code and frontend to Freestyle with environment variables pointing to your self-hosted Rivet instance. - - **Step 4: Configure runner** - Configures your self-hosted Rivet to route actor execution requests to the Freestyle deployment. - - See the [example repository](https://github.com/rivet-dev/rivet/tree/main/examples/ai-and-user-generated-actors-freestyle) for the complete project structure including the template directory and build process. - -## Project Structure - -The example uses this structure: - -``` -src/ - backend/ # Backend used to deploy sandboxed Rivet code - frontend/ # Frontend for the deploy UI -template/ # Template Rivet project to deploy - src/ - backend/ # Actor code (registry.ts gets replaced with user code) - frontend/ # Frontend code (App.tsx gets replaced with user code) -``` - -The deployment script: -1. Copies the template directory -2. Replaces `registry.ts` and `App.tsx` with user-provided code -3. Builds and deploys to Freestyle -4. Configures Rivet to connect to the deployment - -## Next Steps - -- Explore the [complete example](https://github.com/rivet-dev/rivet/tree/main/examples/ai-and-user-generated-actors-freestyle) -- Learn more about [Freestyle deployment](https://docs.freestyle.sh/web/overview) -- Read about [Rivet namespaces and tokens](/docs/actors/authentication) ## Authentication # Authentication diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/RedesignedHero.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/RedesignedHero.tsx index 12efcba67f..e8fafec21f 100644 --- a/website/src/app/(v2)/(marketing)/(index)/sections/RedesignedHero.tsx +++ b/website/src/app/(v2)/(marketing)/(index)/sections/RedesignedHero.tsx @@ -250,3 +250,5 @@ export const chatRoom = actor({ ); + + diff --git a/website/src/app/(v2)/(marketing)/pricing/PricingPageClient.tsx b/website/src/app/(v2)/(marketing)/pricing/PricingPageClient.tsx index f6788ba809..be96c7c812 100644 --- a/website/src/app/(v2)/(marketing)/pricing/PricingPageClient.tsx +++ b/website/src/app/(v2)/(marketing)/pricing/PricingPageClient.tsx @@ -1,604 +1,758 @@ "use client"; -import { CheckIcon, MinusIcon, PlusIcon } from "@heroicons/react/16/solid"; + +import React, { useState } from 'react'; +import Link from 'next/link'; +import { + Terminal, + Zap, + Globe, + Github, + ArrowRight, + Box, + Database, + Layers, + Check, + Copy, + Cpu, + Server, + Clock, + Cloud, + Activity, + Wifi, + LayoutGrid, + Settings, + CreditCard, + BarChart3, + Command, + ChevronRight, + Play, + Network, + Container, + X, + HardDrive, + Workflow, + FileJson, + Braces, + Users, + Laptop +} from 'lucide-react'; import { MobilePricingTabs } from "./components/MobilePricingTabs"; -import { useState } from "react"; -import clsx from "clsx"; -import Link from "next/link"; -import { Icon, faArrowRight } from "@rivet-gg/icons"; - - -const tiers = [ - { - name: "Free", - priceMonthly: "$0", - href: "https://dashboard.rivet.dev/", - highlights: [ - { description: "5GB Limit", icon: "check" }, - { description: "5 Million Writes /mo Limit", icon: "check" }, - { description: "200 Million Reads /mo Limit", icon: "check" }, - { description: "100GB Egress Limit", icon: "check" }, - { description: "Community Support", icon: "check" }, - ], - }, - { - name: "Hobby", - priceMonthly: "$5", - href: "https://dashboard.rivet.dev/", - highlights: [ - { description: "25 Billion Reads /mo included", icon: "gift" }, - { description: "50 Million Writes /mo included", icon: "gift" }, - { description: "5GB Storage included", icon: "gift" }, - { description: "1TB Egress included", icon: "gift" }, - { description: "Email Support", icon: "check" }, - ], - }, - { - name: "Team", - priceMonthly: "$200", - href: "https://dashboard.rivet.dev/", - highlights: [ - { description: "25 Billion Reads /mo included", icon: "gift" }, - { description: "50 Million Writes /mo included", icon: "gift" }, - { description: "5GB Storage included", icon: "gift" }, - { description: "1TB Egress included", icon: "gift" }, - { description: "MFA", icon: "check" }, - { description: "Slack Support", icon: "check" }, - ], - }, - { - name: "Enterprise", - priceMonthly: "Custom", - href: "/sales", - highlights: [ - { description: "Everything in Team", icon: "check" }, - { description: "Priority Support", icon: "check" }, - { description: "SLA", icon: "check" }, - { description: "OIDC SSO provider", icon: "check" }, - { description: "On-Prem Deployment", icon: "check" }, - { description: "Audit Logs", icon: "check" }, - { description: "Custom Roles", icon: "check" }, - { description: "Device Tracking", icon: "check" }, - { description: "Volume Pricing", icon: "check" }, - ], - }, -]; - -const sections = [ - { - name: "Usage Included", - features: [ - { - name: "Storage", - tiers: { - Free: "5GB", - Hobby: "5GB included", - Team: "5GB included", - Enterprise: "Custom", - }, - }, - { - name: "Reads per month", - tiers: { - Free: "200 Million", - Hobby: "25 Billion included", - Team: "25 Billion included", - Enterprise: "Custom", - }, - }, - { - name: "Writes per month", - tiers: { - Free: "5 Million", - Hobby: "50 Million included", - Team: "50 Million included", - Enterprise: "Custom", - }, - }, - { - name: "Egress", - tiers: { - Free: "100GB Limit", - Hobby: "1TB included", - Team: "1TB included", - Enterprise: "Custom", - }, - }, - ], - }, - { - name: "Support", - features: [ - { - name: "Support", - tiers: { - Free: "Community Support", - Hobby: "Email", - Team: "Slack & Email", - Enterprise: "Slack & Email", - }, - }, - ], - }, - { - name: "Security & Enterprise", - features: [ - { - name: "MFA", - tiers: { - Free: false, - Hobby: false, - Team: true, - Enterprise: true, - }, - }, - { - name: "Custom Regions", - tiers: { - Free: false, - Hobby: false, - Team: false, - Enterprise: true, - }, - }, - { - name: "SLA", - tiers: { - Free: false, - Hobby: false, - Team: false, - Enterprise: true, - }, - }, - { - name: "Audit Logs", - tiers: { - Free: false, - Hobby: false, - Team: false, - Enterprise: true, - }, - }, - { - name: "Custom Roles", - tiers: { - Free: false, - Hobby: false, - Team: false, - Enterprise: true, - }, - }, - { - name: "Device Tracking", - tiers: { - Free: false, - Hobby: false, - Team: false, - Enterprise: true, - }, - }, - { - name: "Volume Pricing", - tiers: { - Free: false, - Hobby: false, - Team: false, - Enterprise: true, - }, - }, - ], - }, -]; - -function PricingTable() { - return ( - - - - - - - - - - - - {tiers.slice(1).map((_, idx) => ( - - - - ))} - - - {sections.map((section) => ( - - {section.features.map((feature) => ( - - - {tiers.map((tier) => ( - - ))} - - ))} - - ))} -
Pricing plan comparison
- Compare Rivet Cloud Plans - - ))} -
- {tiers.map((tier) => ( - -
- {tier.name}{" "} - plan -
-
- {feature.name} - - {typeof feature.tiers[tier.name] === - "string" ? ( - feature.name === "Regions" ? ( - - - Learn more about regions:{" "} - - {feature.tiers[tier.name]} - - ) : ( - <> - - {tier.name} includes: - - - {feature.tiers[tier.name]} - - - ) - ) : ( - <> - {feature.tiers[tier.name] === - true ? ( -
- ); -} -function PricingTiers() { - return ( -
- {tiers.map((tier) => ( -
-
-
-

- {tier.name}{" "} - plan -

-
- {(tier.name === "Hobby" || - tier.name === "Team") && ( -
- From -
- )} -
-
- {tier.priceMonthly} -
- {tier.name !== "Enterprise" && ( - - /mo - - )} -
- {(tier.name === "Hobby" || - tier.name === "Team") && ( -
- + Usage -
- )} -
-
-

- Includes: -

-
    - {tier.highlights.map((highlight, idx) => ( -
  • - {highlight.icon === "gift" ? ( - - - ) : ( - - - )} - {highlight.description} -
  • - ))} -
-
- -
-
-
- ))} -
- ); -} +// --- Shared Design Components --- -function UsagePricingTable() { - return ( -
-
-

- Usage Pricing -

-

- Pay only for what you use beyond the included allowances -

-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
- Resource - - Price -
- Storage - - $0.40 per GB-month -
- Reads - - $1.00 per billion reads -
- Writes - - $1.00 per million writes -
- Egress - - $0.15 per GB -
-
-
-
- ); -} +const Badge = ({ text, color = "orange" }) => { + const colorClasses = { + orange: "text-[#FF4500] border-[#FF4500]/20 bg-[#FF4500]/10", + blue: "text-blue-400 border-blue-500/20 bg-blue-500/10", + red: "text-red-400 border-red-500/20 bg-red-500/10", + zinc: "text-zinc-400 border-zinc-500/20 bg-zinc-500/10", + }; + + return ( +
+ + {text} +
+ ); +}; + +const CodeBlock = ({ code, fileName = 'rivet.json' }) => { + return ( +
+
+
+
+
+
+
+
+
+ {fileName} +
+
+
+
+          {code}
+        
+
+
+ ); +}; + +const FeatureCard = ({ title, description, icon: Icon, color = "orange" }) => { + const getColorClasses = (col) => { + switch (col) { + case "orange": + return { + iconBg: "bg-[#FF4500]/10 text-[#FF4500] group-hover:bg-[#FF4500]/20", + glow: "rgba(255, 69, 0, 0.15)", + borderColor: "border-[#FF4500]", + iconShadow: "group-hover:shadow-[0_0_15px_rgba(255,69,0,0.5)]" + }; + case "blue": + return { + iconBg: "bg-blue-500/10 text-blue-400 group-hover:bg-blue-500/20", + glow: "rgba(59, 130, 246, 0.15)", + borderColor: "border-blue-500", + iconShadow: "group-hover:shadow-[0_0_15px_rgba(59,130,246,0.5)]" + }; + case "red": + return { + iconBg: "bg-red-500/10 text-red-400 group-hover:bg-red-500/20", + glow: "rgba(239, 68, 68, 0.15)", + borderColor: "border-red-500", + iconShadow: "group-hover:shadow-[0_0_15px_rgba(239,68,68,0.5)]" + }; + default: + return { + iconBg: "bg-zinc-500/10 text-zinc-400 group-hover:bg-zinc-500/20", + glow: "rgba(161, 161, 170, 0.15)", + borderColor: "border-zinc-500", + iconShadow: "group-hover:shadow-[0_0_15px_rgba(161,161,170,0.5)]" + }; + } + }; + + const colors = getColorClasses(color); + + return ( +
+ {/* Top Shine Highlight */} +
+ + {/* Top Left Reflection/Glow */} +
+ + {/* Sharp Edge Highlight (Masked to Fade) */} +
+ +
+
+ +
+

{title}

+
+

+ {description} +

+
+ ); +}; + +// --- Page Sections --- + +const Hero = () => ( +
+
+ +
+
+
+

+ Rivet Cloud +

+ +

+ Rivet Cloud handles the coordination, networking, and persistence across regions—connecting your AWS, Vercel, or other cloud deployments instantly. +

+ +
+ + Get Started for Free + + + +
+
+
+
+
+); + +const ArchitectureExplainer = () => { + return ( +
+
+
+

The Hybrid Architecture

+

+ Rivet sits between your clients and your infrastructure. We manage the persistent connections, global routing, and actor state—orchestrating your logic wherever it runs. +

+
+ + {/* Main Diagram Container */} +
+ + {/* 1. Source: Clients */} +
+
+ +
+

Any Client

+

Web • Mobile • Console • CLI

+
+ + {/* Connection Line 1 */} +
+ {/* Desktop Horizontal Line */} +
+
+
+ {/* Mobile Vertical Line */} +
+
+
+
+ + {/* 2. The Gateway: Rivet */} +
+
+ +
+ +
+

Rivet Cloud

+
+ Gateway & Orchestrator +
+
+ + {/* Connection Line 2 - The Branching System */} + {/* This container manages the split lines */} +
+ + {/* Desktop: The Branch Connector */} +
+ {/* Main Feed Line from Gateway */} +
+
+
+ + {/* Top Branch - Added overflow-hidden */} +
+
+
+ + {/* Middle Branch - Added overflow-hidden */} +
+
+
+ + {/* Bottom Branch - Added overflow-hidden */} +
+
+
+
+ + {/* Mobile: Vertical Line */} +
+
+
+
+ + {/* 3. Destination: User Backend */} +
+ {/* 1. Docker */} +
+
+ +
+
+
Docker Containers
+
AWS ECS • Kubernetes
+
+
+ + {/* 2. Serverless */} +
+
+ +
+
+
Serverless Functions
+
Vercel • Cloudflare
+
+
+ + {/* 3. Dedicated */} +
+
+ +
+
+
Dedicated Servers
+
Bare Metal • EC2
+
+
+
-interface ToggleProps { - options: { value: string; label: string }[]; - activeValue: string; - onChange: (value: string) => void; +
+ + + +
+
+ ); } -function Toggle({ options, activeValue, onChange }: ToggleProps) { - return ( -
-
- {options.map((option) => ( - - ))} -
-
- ); +const CloudFeatures = () => { + const features = [ + { title: "Orchestration", desc: "The control plane handles actor placement, lifecycle management, and health checks across your cluster automatically.", icon: Command, color: "zinc" }, + { title: "Managed Persistence", desc: "State is persisted with strict serializability using FoundationDB, ensuring global consistency without the ops burden.", icon: HardDrive, color: "orange" }, + { title: "Edge Routing", desc: "Intelligent routing directs client requests to the nearest active actor replica to minimize latency.", icon: Globe, color: "blue" }, + { title: "Bring Your Own Compute", desc: "Run your business logic on AWS, Vercel, Railway, or bare metal. Rivet connects them all into a unified platform.", icon: Network, color: "zinc" }, + { title: "Serverless & Containers", desc: "Deploy your logic as lightweight V8 isolates for speed or standard Docker containers for maximum flexibility.", icon: Box, color: "orange" }, + { title: "Observability", desc: "Instant access to real-time logs, metrics, and tracing for every actor without configuring external agents.", icon: Activity, color: "blue" } + ]; + + return ( +
+
+
+

Platform Features

+

Everything you need to run stateful workloads in production.

+
+
+ {features.map((f, i) => ( + + ))} +
+
+
+ ); } -export default function PricingPageClient() { - const [activeTab, setActiveTab] = useState("cloud"); - - const toggleOptions = [ - { value: "cloud", label: "Cloud" }, - { value: "selfhost", label: "Self-Host" }, - ]; - - return ( -
-
-
-
-

- Rivet {activeTab === "cloud" ? "Cloud Pricing" : "Self-Host"} -

-

- {activeTab === "cloud" - ? "Start with free and scale as you grow." - : "Deploy Rivet on your own infrastructure." - } -

-
- -
-
-
-
- - {activeTab === "cloud" ? ( - <> -
- - -
- -
- - -
- - ) : ( -
-
-

- Self-Hosted Rivet -

-

- Deploy Rivet on your own infrastructure with full control and no usage limits. -

- -
-
-

Open Source

-

- Rivet is open source and free to use on your own infrastructure. -

-
    -
  • - - No usage limits -
  • -
  • - - Full source code access -
  • -
  • - - Community support -
  • -
- -
- -
-

Enterprise Support

-

- Get professional support and additional features for your self-hosted deployment. -

-
    -
  • - - Priority support -
  • -
  • - - SLA guarantees -
  • -
  • - - Custom integrations -
  • -
- -
-
-
-
- )} -
- ); +const SelfHostingComparison = () => { + const burdens = [ + "Provisioning a Distributed Store", + "Configuring Cross-Region VPC Peering", + "Managing TLS Certificates & Rotation", + "Scaling the Coordination Plane", + "Handling Partition Tolerance", + "Implementing Zero-Downtime Drains" + ]; + + return ( +
+
+
+

Compare Deployment Models

+

+ Rivet is open source. Run it yourself for total control, or use Rivet Cloud for a hands-off experience. +

+
+ +
+ {/* Rivet Cloud Card */} +
+
+
+
+ +
+

Rivet Cloud

+
+

+ Managed cloud solution for personal projects to enterprise. +

+ +
+
+ Scaling + Managed +
+
+ Database + FoundationDB +
+
+ Networking + Global Mesh +
+
+ Updates + Automatic +
+
+ + + Get Started + +
+ + {/* Open Source Card */} +
+
+
+
+ +
+

Open Source

+
+

+ Maximum control for air-gapped environments or specific compliance requirements. +

+ +
+
+ Scaling + You Manage +
+
+ Database + BYO +
+
+ Networking + Manual VPC +
+
+ Updates + Manual +
+
+ + + View on Github + +
+
+
+
+ ) } +const ComparisonTable = () => { + const features = [ + { name: "Storage", free: "5GB", hobby: "5GB", team: "5GB", ent: "Custom" }, + { name: "Reads / mo", free: "200 Million", hobby: "25 Billion", team: "25 Billion", ent: "Custom" }, + { name: "Writes / mo", free: "5 Million", hobby: "50 Million", team: "50 Million", ent: "Custom" }, + { name: "Egress", free: "100GB", hobby: "1TB", team: "1TB", ent: "Custom" }, + { name: "Support", free: "Community", hobby: "Email", team: "Slack & Email", ent: "Slack & Email" }, + { name: "MFA", free: false, hobby: false, team: true, ent: true }, + { name: "Custom Regions", free: false, hobby: false, team: false, ent: true }, + { name: "SLA", free: false, hobby: false, team: false, ent: true }, + { name: "Audit Logs", free: false, hobby: false, team: false, ent: true }, + { name: "Custom Roles", free: false, hobby: false, team: false, ent: true }, + { name: "Device Tracking", free: false, hobby: false, team: false, ent: true }, + { name: "Volume Pricing", free: false, hobby: false, team: false, ent: true }, + ]; + + const renderCell = (value) => { + if (typeof value === 'boolean') { + return value ? +
: +
; + } + return {value}; + }; + + return ( +
+

Compare Plans

+
+ + + + + + + + + + + + {features.map((feature, i) => ( + + + + + + + + ))} + +
FeatureFreeHobbyTeamEnterprise
{feature.name}{renderCell(feature.free)} + {renderCell(feature.hobby)} + {renderCell(feature.team)}{renderCell(feature.ent)}
+
+
+ ); + }; + +const Pricing = () => { + const [isCloud, setIsCloud] = useState(true); + + const cloudPlans = [ + { + name: "Free", + price: "$0", + period: "/mo", + desc: "For prototyping and small projects.", + features: [ + "5GB Limit", + "5 Million Writes /mo Limit", + "200 Million Reads /mo Limit", + "100GB Egress Limit", + "Community Support" + ], + cta: "Get Started", + highlight: false + }, + { + name: "Hobby", + prefix: "From", + price: "$5", + period: "/mo + Usage", + desc: "For scaling applications.", + features: [ + "25 Billion Reads /mo included", + "50 Million Writes /mo included", + "5GB Storage included", + "1TB Egress included", + "Email Support" + ], + cta: "Get Started", + highlight: true + }, + { + name: "Team", + prefix: "From", + price: "$200", + period: "/mo + Usage", + desc: "For growing teams and businesses.", + features: [ + "25 Billion Reads /mo included", + "50 Million Writes /mo included", + "5GB Storage included", + "1TB Egress included", + "MFA", + "Slack Support" + ], + cta: "Get Started", + highlight: false + }, + { + name: "Enterprise", + price: "Custom", + period: "", + desc: "For high-volume, mission-critical workloads.", + features: [ + "Everything in Team", + "Priority Support", + "SLA", + "OIDC SSO provider", + "Audit Logs", + "Custom Roles", + "Device Tracking", + "Volume Pricing" + ], + cta: "Contact", + highlight: false + } + ]; + + const selfHostedPlans = [ + { + name: "Open Source", + price: "Free", + period: "Forever", + desc: "Rivet is open source and free to use on your own infrastructure.", + features: [ + "No usage limits", + "Full source code access", + "Community support" + ], + cta: "Get Started", + highlight: false + }, + { + name: "Enterprise Support", + price: "Custom", + period: "", + desc: "Get professional support and additional features for your self-hosted deployment.", + features: [ + "Priority support", + "SLA guarantees", + "Custom integrations" + ], + cta: "Contact Sales", + highlight: false + } + ]; + const plans = isCloud ? cloudPlans : selfHostedPlans; + + const usagePricing = [ + { resource: "Active Actors", price: "$0.05", unit: "per 1k actor-hours" }, + { resource: "State Storage", price: "$0.40", unit: "per GB-month" }, + { resource: "Egress", price: "$0.10", unit: "per GB" }, + { resource: "Compute", price: "BYO", unit: "Paid to your provider" }, + ]; + + return ( +
+
+
+

+ {isCloud ? "Simple, Predictable Pricing" : "Rivet Self-Host"} +

+

+ {isCloud + ? "Pay for coordination and state. Compute costs are billed directly by your chosen cloud provider." + : "Deploy Rivet on your own infrastructure." + } +

+ + {/* Toggle */} +
+ + +
+
+ +
+ {plans.map((plan, idx) => ( +
+ {/* Highlight Effects for Pro Card */} + {plan.highlight && ( + <> + {/* Top Shine */} +
+ + )} + + {!plan.highlight && ( +
+ )} + +
+

{plan.name}

+ +
+ {plan.prefix && {plan.prefix}} +
+ {plan.price} + {plan.period && {plan.period}} +
+
+ + {plan.desc &&

{plan.desc}

} + +
+ {plan.features.map((feat, i) => ( +
+ + {feat} +
+ ))} +
+
+ + + {plan.cta} + +
+ ))} +
+ + {/* Only show usage and comparison for Cloud */} + {isCloud && ( + <> + {/* Usage Pricing Section */} +
+
+

Usage Pricing

+

Metered costs for scaling beyond plan limits.

+
+ +
+ {usagePricing.map((item, i) => ( +
+
{item.resource}
+
{item.price}
+
{item.unit}
+
+ ))} +
+
+ + + + )} +
+
+ ); +}; + + +export default function PricingPageClient() { + return ( +
+
+ + + + + +
+
+ ); +} diff --git a/website/src/app/(v2)/(marketing)/solutions/collaborative-state/page.tsx b/website/src/app/(v2)/(marketing)/solutions/collaborative-state/page.tsx index 20ce09b027..3a8cd10a86 100644 --- a/website/src/app/(v2)/(marketing)/solutions/collaborative-state/page.tsx +++ b/website/src/app/(v2)/(marketing)/solutions/collaborative-state/page.tsx @@ -673,3 +673,5 @@ export default function CollaborativeStatePage() { ); } + + diff --git a/website/src/app/(v2)/(marketing)/solutions/user-session-store/page.tsx b/website/src/app/(v2)/(marketing)/solutions/user-session-store/page.tsx index bb06e9a0ee..0a6c577c8b 100644 --- a/website/src/app/(v2)/(marketing)/solutions/user-session-store/page.tsx +++ b/website/src/app/(v2)/(marketing)/solutions/user-session-store/page.tsx @@ -715,3 +715,5 @@ export default function UserSessionStorePage() { ); } + + diff --git a/website/src/app/(v2)/[section]/doc-page.tsx b/website/src/app/(v2)/[section]/doc-page.tsx index 334662ec70..997e6289a6 100644 --- a/website/src/app/(v2)/[section]/doc-page.tsx +++ b/website/src/app/(v2)/[section]/doc-page.tsx @@ -204,3 +204,5 @@ export async function getAllDocParams(): Promise> { return staticParams; } + + diff --git a/website/src/app/(v2)/[section]/util.ts b/website/src/app/(v2)/[section]/util.ts index 9015299740..1175a2a06e 100644 --- a/website/src/app/(v2)/[section]/util.ts +++ b/website/src/app/(v2)/[section]/util.ts @@ -17,3 +17,5 @@ export function buildFullPath(pathComponents: string[]): string { return `/${pathComponents.join("/")}`; } + + diff --git a/website/src/components/Header.jsx b/website/src/components/Header.jsx index 1fabac3ee5..6a7e4c6e00 100644 --- a/website/src/components/Header.jsx +++ b/website/src/components/Header.jsx @@ -200,7 +200,7 @@ export const Header = forwardRef(function Header( Changelog - Pricing + Cloud
diff --git a/website/src/components/Navigation.jsx b/website/src/components/Navigation.jsx index 5c19b4589b..c5c99d090e 100644 --- a/website/src/components/Navigation.jsx +++ b/website/src/components/Navigation.jsx @@ -114,7 +114,7 @@ export function Navigation({ navigation, ...props }) { Changelog - Pricing + Cloud {/* Sidebar */} diff --git a/website/src/components/v2/Header.tsx b/website/src/components/v2/Header.tsx index cd93bb08c2..eb02f83746 100644 --- a/website/src/components/v2/Header.tsx +++ b/website/src/components/v2/Header.tsx @@ -260,7 +260,7 @@ export function Header({ active === "pricing" ? "page" : undefined } > - Pricing + Cloud - Pricing + Cloud