Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

124 linesCodeBlameRaw
1---
2title: Architecture overview
3description: How g1t is put together, from the four public Workers at the edge to the nineteen services behind them, the event bus that connects them, and the platform each one runs on.
4---
5
6import { CardGrid } from '@astrojs/starlight/components';
7import Aside from '../../../components/Aside.astro';
8import Diagram from '../../../components/Diagram.astro';
9import LinkCard from '../../../components/LinkCard.astro';
10
11g1t is a set of small programs, each with one job, that run on Cloudflare
12Workers. A few face the internet. Almost all the rest can be reached only by the
13Workers that are bound to them. Every service that keeps data keeps it in its own
14database, and services learn what happened elsewhere from events instead of
15calling each other to find out.
16
17This section is for developers: people building on g1t, contributing to it,
18or running it themselves. It names the files, bindings and limits that
19decide how g1t behaves, so you can read the code next to it.
20
21<Diagram name="platform-map" />
22
23## The layers
24
25| Layer | What is in it | Reached by |
26| --- | --- | --- |
27| **Clients** | Browsers, the [desktop](/guides/desktop/) and [phone](/guides/mobile/) apps, git, the [CLI](/guides/cli/), coding agents, [self-hosted runners](/guides/self-hosted-runners/), and visitors to apps deployed on g1t. | The internet |
28| **Edge** | Four Workers with public routes: the site (`apps/web`), the API and MCP server (`apps/api`), the status page (`apps/status`) and the app dispatcher (`services/pages`). | Their hostnames |
29| **Core** | Nineteen services, each a Worker with `workers_dev` off. Seventeen have no route at all; `telemetry` takes OTLP at `otel.g1t.sh` and `og` draws social cards at `og.g1t.sh`. | Service bindings from the Workers that name them |
30| **Platform** | D1, Durable Objects, Queues, R2, KV, Artifacts for git, and Containers for sandboxes. | The one service that owns each, through its bindings |
31
32The edge does three things: it works out who is asking, enforces rate
33limits, and turns a request into calls to the services that own the
34answer. It keeps no state of its own. The services do the work and own the
35data.
36
37## Where each hostname goes
38
39| Hostname | Worker | Serves |
40| --- | --- | --- |
41| `g1t.sh` | `g1t` (`apps/web`) | The site, git over HTTPS, and the package registries, which it passes whole to `repos` and `packages` |
42| `g1tusercontent.com` | `g1t` (`apps/web`) | Raw files, avatars and attachments, on a domain that never sees the session cookie |
43| `api.g1t.sh`, `mcp.g1t.sh` | `g1t-api` (`apps/api`) | The REST API, the MCP server, OAuth, the runner protocol, and OTLP |
44| `*.g1t.page` and custom domains | `g1t-pages` (`services/pages`) | Apps deployed on g1t |
45| `otel.g1t.sh` | `g1t-telemetry` | OpenTelemetry from your software |
46| `status.g1t.sh` | `g1t-status` (`apps/status`) | The status page, with a database of its own so it answers when the rest does not |
47| `docs.g1t.sh` | `g1t-docs` (`apps/docs`) | These pages |
48
49`sudo.g1t.sh`, g1t's staff console, sits behind Cloudflare Access and is
50not part of what you can call.
51
52## Calls, events and ownership
53
54Three rules shape the code:
55
56- **A service owns its data.** Each of the sixteen D1 databases is bound
57 by exactly one Worker. To read another service's data, you call that
58 service. Three stores are deliberately shared, each with one writer:
59 the avatars KV, the custom domains KV, and the Actions cache bucket
60 ([Data and storage](/architecture/data/)).
61- **Calls are for answers; events are for news.** When the site needs a pull
62 request, it calls `work`. When a push lands, `repos` does not call the
63 dozen services that care: it publishes `git.push`, and each of them gets
64 its own copy on its own queue ([Events](/architecture/events/)).
65- **The viewer travels with the call.** The edge resolves the person or
66 token once, and passes the result to every service in the call's
67 arguments. Each service decides access itself with the same rules,
68 compiled in, rather than asking `identity` again
69 ([Identity and access](/architecture/identity/)).
70
71A call is an HTTP request over a service binding: `POST /rpc/<method>`
72with a JSON body. An expected failure, such as "not found" or "not
73allowed", comes back as a value, `{ "ok": false, "error": { "code",
74"message" } }`, with status 200. Only something unexpected, a thrown error
75or a busy store, becomes a non-200 status
76([Services and contracts](/architecture/services/)).
77
78## Rust and TypeScript
79
80The services that hold accounts, repositories, work, events, money and the
81API are written in Rust, compiled to WebAssembly with `worker-build`. The
82web apps and the services built around Durable Objects and live rooms are
83TypeScript.
84
85| Rust | TypeScript |
86| --- | --- |
87| `identity`, `repos`, `work`, `events`, `actions`, `packages`, `security`, `search`, `billing`, `integrations`, `webhooks`, and `apps/api` | `runner`, `deployments`, `projects`, `chat`, `artifacts`, `notify`, `telemetry`, `og`, `pages`, and `apps/web`, `apps/sudo`, `apps/status` |
88
89Both sides share their types through contracts: `crates/contracts` in Rust
90and `packages/contracts` in TypeScript. Where the two must agree exactly,
91such as the access rules and the scopes, a Rust test reads the TypeScript
92file and fails if they differ.
93
94## One codebase, two homes
95
96The same source runs on g1t.sh and in a [self-hosted
97installation](/guides/self-hosting/). Each Cloudflare product a service
98uses sits behind a port, and the self-hosted build binds an open
99adapter in its place: bare repositories served by `git http-backend` for
100Artifacts, any S3 store for R2, Mailpit for email. The service code does
101not change. [Data and storage](/architecture/data/#ports-and-adapters)
102shows each one.
103
104<Aside type="tip" title="Read the code next to this">
105 Every unit g1t deploys is listed in `deploy/stack.jsonc`, with its
106 language, its stage and what a self-hosted installation does with it.
107 Each service's `wrangler.jsonc` lists its bindings: its database, the
108 services it calls, and the queues it reads.
109</Aside>
110
111## In this section
112
113<CardGrid>
114 <LinkCard title="How a request is served" href="/architecture/requests/" icon="route" description="The site and the API, from the first byte to Server-Timing." />
115 <LinkCard title="Services and contracts" href="/architecture/services/" icon="boxes" description="Every unit, what it owns, what it calls, and how calls work." />
116 <LinkCard title="Git" href="/architecture/git/" icon="git-branch" description="Where repositories live, the push path, caches and forks." />
117 <LinkCard title="Events" href="/architecture/events/" icon="radio-tower" description="The bus, the log, fan-out, webhooks and following live." />
118 <LinkCard title="Work and the merge queue" href="/architecture/work/" icon="git-merge" description="Work items, pull requests, checks, merging and the queue." />
119 <LinkCard title="Actions, runners and sandboxes" href="/architecture/compute/" icon="cpu" description="Workflow jobs, hosted and self-hosted, and what walls them in." />
120 <LinkCard title="Deployments and telemetry" href="/architecture/deployments/" icon="rocket" description="Apps on g1t.page, packages, and observability." />
121 <LinkCard title="Data and storage" href="/architecture/data/" icon="database" description="Who owns what, migrations, and the ports that make self-hosting work." />
122 <LinkCard title="Identity and access" href="/architecture/identity/" icon="key-round" description="Credentials, the viewer, scopes, and where access is decided." />
123 <LinkCard title="How g1t ships" href="/architecture/shipping/" icon="ship" description="The monorepo, builds, staged deploys, and keeping these pages true." />
124</CardGrid>