Docs / Architecture
System overview
The parts of ChannelForge and how they fit: the web app, the control plane, the gateway, the GPU fleet, storage and the platforms.
This section explains how ChannelForge is built, for developers who integrate with it and for technical buyers who need to know what runs their channels. It describes the parts, how they talk, and the guarantees they keep — the design, not the deployment: it names no machines, addresses or internal paths.
The parts#
| Part | What it does |
|---|---|
| Edge | Cloudflare terminates TLS and absorbs attacks. The servers accept web traffic only from it. |
| Web app | The public site, the app every member uses, the admin console, the REST API, the MCP server and its sign-in. It runs as more than one instance, so a deploy never drops a request. |
| Database | PostgreSQL, the single source of truth: accounts, workspaces, projects, channels, episodes' records, posts, jobs, the credit ledger, the audit log. The job queue lives here too. |
| Control plane | The services that do the work: workers for short jobs (research, drafts, planning, posting, reading platforms), the GPU fleet, the scheduler, the sentinel, the mailer and the billing reconciler. |
| Model gateway | Every model call goes through it. It holds the only model credential (Claude models, through AWS Bedrock), checks each job's budget before a call, meters every call per workspace and job, and switches to another model when one is out of capacity. |
| Voice service | Narration. It speaks the lines a job sends with Google's text-to-speech voices, so that no GPU machine ever needs Google's credential. |
| GPU fleet | Render machines with NVIDIA L4 GPUs, in Google Cloud and AWS regions in Europe, the United States and Asia. They are started for work and stopped when idle; each runs several jobs side by side, each in its own slot. |
| Object storage | A private, encrypted bucket: every video, thumbnail, kit and brand file, organised by workspace and handed out only as short-lived signed links. |
| Cache | Redis: rate limits, short caches, budget counters and live job progress. It is never the source of truth — everything in it can be lost without losing anything that matters. |
| Amazon SES, for verification, security alerts, notifications and digests. | |
| Platforms | YouTube, Facebook, Instagram, TikTok, X, Threads, LinkedIn, Bluesky and Pinterest, reached through each platform's own API with the accounts each workspace connected, under the permissions its members granted. |
How they fit#
people · your code · assistants
│ HTTPS
▼
┌───────┐
│ edge │ TLS, DDoS protection
└───┬───┘
▼
┌───────────────────────────┐ ┌──────────────────────────┐
│ web app │ ───────▶ │ database │
│ site · app · admin │ ◀─────── │ the truth · the queue · │
│ REST API · MCP · sign-in │ │ the ledger │
└────────────┬──────────────┘ └─────────────▲────────────┘
│ a nudge (it also polls) │
▼ │
┌──────────────────────────────────────────────────────┴───────────┐
│ control plane │
│ workers · scheduler · sentinel · mailer · billing · GPU fleet │
└───────┬──────────────────────────────┬───────────────────────────┘
│ one encrypted session a job │ each workspace's own accounts
▼ ▼
┌─────────────────────┐ YouTube · Facebook · Instagram · TikTok
│ GPU machines │ X · Threads · LinkedIn · Bluesky · Pinterest
│ one job per slot │
└──┬───────────┬──────┘
│ └── narration ──▶ voice service ──▶ Google's voices
└── model calls ──▶ model gateway ──▶ Claude models (AWS Bedrock)
media ⇄ object storage (private; signed links only)From a click to a finished job#
- A request. A member presses a button, your code calls the API, an assistant calls a tool, or the scheduler decides it is time. The web app checks who is asking, their role in the workspace and the plan, and works out the price.
- One transaction. The job's row and its credit hold are written together, under the workspace's and the channel's spending caps, or not at all. Then the control plane is nudged; it also polls, so a lost nudge costs a few seconds, never the job.
- A worker or a GPU slot. Short jobs are claimed by workers with a row lock, so two workers never take the same job and a workspace never runs more than its share at once. GPU jobs go to the fleet, which assigns free slots by fair share and starts a machine when the queue needs one.
- The work. A GPU job gets its channel's files, runs as its own user on its slot, and reaches the model gateway and the voice service only through its own encrypted session, with tokens that name the job and cap what it may spend.
- Back home. What the job made goes to storage under the workspace, its records to the database. The job is settled: charged what it really used — model time, narration and GPU time, at the plan's rate — and the rest of the hold is released. A failure on our side is not charged.
- Told. The member who started it gets a notification; the workspace's webhooks get their events; a browser that has the page open sees the progress live.
The episode pipeline follows an episode through these steps in detail.
Design principles#
- One workspace boundary, everywhere. Every page and action resolves the workspace from the request and the member's role in it; every query names the workspace. Another workspace's id answers "not found", exactly like one that does not exist — in the app, the API and MCP alike.
- Secrets stay with the part that needs them. The model credential is read only by the gateway. Google Cloud's credential stays on the control plane, for narration and for starting and stopping machines. Platform tokens are sealed in the database and opened only by the jobs that post or read for that workspace. GPU machines hold no cloud, model or platform credential at all: they reach models and voices only through the gateway and the voice service.
- Money lives in the database. Holds, charges, grants, expiry, rollover and spending caps are database functions that the web app and the control plane both call, atomic under the workspace's lock, so the rules are the same whichever side starts a job.
- Work is a row, not a memory. Every job is a database row with a lease and a heartbeat. When a worker or a GPU machine is lost, its job is noticed and taken back, never silently dropped.
- Nothing stays on a GPU machine. A job's folder is laid out for that job and removed after it; the machines are interchangeable and can be rebuilt from a recipe.
- A price before work. Everything that costs credits shows its price first and respects the caps; held episodes and failures on our side are free.
- Our data out, platforms' data in. The REST API, MCP and webhooks carry ChannelForge's own data. YouTube's data never leaves through them, and no platform's numbers leave through MCP or webhooks.
Where it runs#
The service is hosted in the European Union: the web app, the control plane, the database, object storage and email run in AWS in Frankfurt. Rendering runs on GPU machines in Google Cloud and AWS, in Europe, the United States and Asia, chosen job by job for capacity and cost; they receive only what a job needs, for as long as it runs. Model calls go to Claude models through AWS Bedrock, narration to Google Cloud. The sub-processors page lists every provider and what it does.
The sections that follow#
| Page | What it covers |
|---|---|
| The episode pipeline | every step from a topic to a published post, who runs it, where failures go |
| The quality system | the measured gates, the independent critic, fix rounds, budgets, lessons |
| The GPU fleet and isolation | starting, sharing and stopping render machines; keeping tenants apart |
| The publishing engine | slots, the never-twice rule, quotas, cadence, retries |
| Data, storage and retention | what is kept where, encryption, how long, deletion |
| Reliability and recovery | retries, self-healing, backups and the standby |
Related#
- Security — accounts, tokens, isolation and monitoring.
- Privacy at a glance — what is collected and why.
- Developer overview — the ways in from outside.
Something missing or unclear? Tell us and we will improve this page.