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.

518 linesCodeBlameRaw
1---
2title: What g1t can't do yet
3description: The limits you can hit on g1t today, why each one exists, what to do instead, and whether it is planned.
4---
5
6This page lists what g1t cannot do today. Each entry says what you can't
7do, why, what to do instead, and where it stands.
8
9Where it stands is one of:
10
11- **Planned**: we intend to build it. We don't give dates we can't keep.
12- **Depends on Cloudflare**: g1t runs on Cloudflare, and this needs
13 something the platform does not offer yet.
14- **Not scheduled**: no work is planned on it now.
15
16Several of these depend on Cloudflare; [we wrote to them about it](/about/open-letter-to-cloudflare/).
17
18If you hit a limit that is not here, tell us at
19[g1t.sh/support](https://g1t.sh/support), and we will add it.
20
21## Git
22
23### No git over SSH
24
25You can reach repositories only over HTTPS. A `git@g1t.sh:…` remote does
26not work.
27
28- **Why.** SSH needs inbound TCP connections on port 22. g1t runs on
29 Cloudflare Workers, which accept HTTP, not raw TCP. Cloudflare has a beta
30 for inbound TCP; we have applied and are waiting.
31- **Instead.** Use the HTTPS remote with an
32 [access token](/guides/git/#authentication). It does everything SSH would:
33 clone, fetch and push. SSH keys you add under **Settings → SSH keys** are
34 kept for when SSH arrives.
35- **Status.** Depends on Cloudflare. See [Git](/guides/git/#ssh).
36
37### Repositories up to 1 GB, files up to 32 MB, no LFS
38
39A repository can hold up to 1 GB and a single file up to 32 MB. Git LFS is
40not supported. A push that would cross either is declined before it is
41stored, and git prints why. See [Size limits](/guides/git/#size-limits).
42
43- **Why.** These are the limits of Cloudflare Artifacts, where every
44 repository is stored.
45- **Instead.** Keep large binaries out of the repository: in a release
46 bucket, a package registry or object storage, fetched at build time.
47- **Status.** Large file storage is planned. Raising the limits themselves
48 depends on Cloudflare.
49
50### Pushes up to 100 MB each
51
52A single push can carry up to 100 MB. A larger one is refused with HTTP
53`413` before g1t sees it.
54
55- **Why.** Cloudflare's network limits the size of one request body on the
56 plan g1t.sh is on.
57- **Instead.** Push history in steps, oldest first:
58 `git push origin <older-commit>:refs/heads/main`, then a newer one, then
59 `main`. Each push sends only what the last did not.
60- **Status.** Depends on Cloudflare.
61
62### Imports up to 40 MB
63
64Importing a repository copies it in one piece of at most 40 MB, after
65compression.
66
67- **Why.** The copy is held in memory while it moves, and a Worker has
68 128 MB for everything it is doing at once.
69- **Instead.** Clone the repository yourself and push it to g1t, in steps if
70 it is over 100 MB. See [Import a repository](/guides/github/#what-comes-across).
71- **Status.** Streaming the copy, so size stops mattering, is planned.
72
73### Partial clone works, but is not promised
74
75`git clone --filter=blob:none` returns a real partial clone today. We don't
76promise it will keep doing so.
77
78- **Why.** Cloudflare's documentation says filters are not supported, but
79 they work with git's protocol version 2. We have asked whether that is
80 intended.
81- **Instead.** Use it, and fall back to `--depth=1` for a shallow clone,
82 which is supported.
83- **Status.** Depends on Cloudflare.
84
85### No server-side hooks of your own
86
87You can't run a script of your own on g1t when a push arrives, before or
88after its refs move.
89
90- **Why.** The git store has no hook for this. g1t's own checks run in front
91 of it, in g1t's code: [protected branches](/guides/git/#protected-branches)
92 and [push protection](/guides/security/#push-protection).
93- **Instead.** Protect the default branch and make your workflows
94 [required checks](/guides/pull-requests/#required-status-checks). To react
95 after a push, use a [webhook](/guides/webhooks/) or a workflow on `push`.
96- **Status.** Not scheduled for your own scripts. A hook in the store,
97 which would let g1t enforce more before refs move, depends on Cloudflare.
98
99### Very large pushes are scanned after they land, not before
100
101A very large push is too large for push protection to read before it is
102stored, so it is let through, and g1t scans every commit it added
103afterwards, in the background. A secret found that way is an open alert
104rather than a refused push, and the workspace's owners are emailed when one
105looks real. Most pushes are scanned before they land.
106
107- **Why.** Scanning reads the whole push inside a Worker, which has 128 MB
108 for everything it is doing at once. Past a certain size, scanning could fail
109 the push outright, and refusing such pushes would block importing real
110 repositories.
111- **Instead.** To have a large history checked before it lands, push it in
112 steps (see above), so each push is scanned first. Secrets already in
113 history are listed under
114 [Secrets in history](/guides/security/#secrets-in-history).
115- **Status.** Planned: scanning while the push streams, at any size.
116
117### Deleting history does not free storage
118
119Storage is counted from what is pushed, and the count only grows. Deleting
120a branch, or force-pushing over commits, does not lower it.
121
122- **Why.** The git store does not say whether or when it reclaims space
123 from objects nothing points to any more, or report how much a repository
124 holds. So g1t cannot see it either.
125- **Instead.** Keep large mistakes out with a `.gitignore`. If one landed in
126 a private repository and counts against you, tell us at
127 [g1t.sh/support](https://g1t.sh/support).
128- **Status.** Depends on Cloudflare. See
129 [private repository storage](/guides/usage-and-billing/#private-repository-storage).
130
131## Pull requests and forks
132
133### A fork's storage counts in full
134
135A fork counts toward its workspace's private repository storage at its
136whole size, even where it is the same as the repository it came from.
137
138- **Why.** Cloudflare has not documented whether a fork shares stored
139 objects with its source or copies them, so g1t never assumes a fork is
140 cheaper than a copy.
141- **Instead.** Fork with **Copy the default branch only** (the default)
142 unless you need every branch and tag, and delete forks you no longer use.
143- **Status.** Depends on Cloudflare. See
144 [What a fork costs](/concepts/forks/#what-a-fork-costs).
145
146### Pull requests' working copies are removed a day after they close
147
148A day after a pull request merges or closes, its working copy's git data
149is removed. The pull request's changes stay readable: its head is kept in the
150repository as `refs/pull/<pull request id>/head`. Pushing to the working
151copy, or reopening the pull request, makes it again from there.
152
153- **Why.** Cloudflare has not documented whether a fork shares stored
154 objects with its source or copies them, so working copies are not
155 kept longer than they are useful.
156- **Instead.** Nothing you need to do. To keep working on a closed pull
157 request's change, fetch `refs/pull/<pull request id>/head` and push it
158 to a branch.
159- **Status.** Clear storage rules for copies depend on Cloudflare.
160
161### Some dependency update options are not applied yet
162
163g1t reads and checks every option of a `dependabot.yml` file, but does not
164act on all of them yet:
165
166- Version update pull requests are opened for npm, Cargo, Go and pip only.
167 Entries for other ecosystems are checked and listed, and open nothing.
168- A multi-ecosystem group opens one pull request per ecosystem, not one
169 for the group.
170- Registries that sign in with OIDC are not used.
171
172**Instead.** Keep a separate entry per ecosystem and directory, and check
173the Security page, which lists what each entry reads but does not act on.
174See [Dependency updates](/guides/dependency-updates/#options).
175**Status.** Planned.
176
177### Very large changes are shown in parts
178
179A pull request, commit or comparison lists at most 300 changed files. Of
180those, lines are read for the first ones until about 20,000 lines; the
181rest are listed without their counts and load one batch at a time as you
182scroll to them. A single file over 512 KB is not shown at all, and one
183with a diff over 1,000 lines waits for **Load diff**.
184
185- **Instead.** For a change of more than 300 files, compare the commits
186 with git (`git diff --stat base...head`). From the API, ask for the files
187 a large answer left out by `paths`.
188 See [Files changed](/guides/pull-requests/#files-changed).
189- **Status.** Not planned to change.
190
191### No conflict resolution in the browser
192
193You can't resolve a merge conflict on the pull request's page.
194
195- **Instead.** Fix it on the command line.
196 See [Conflicts](/guides/pull-requests/#conflicts).
197- **Status.** Planned.
198
199### Large merges, squashes and rebases
200
201g1t merges, squashes, rebases and updates a pull request's branch by itself
202up to 1,000 changed files, 100 files merged line by line (each up to 1 MiB)
203and 250 commits in a rebase. Beyond them it refuses, and nothing changes.
204
205- **Instead.** Squash or merge instead of rebasing, or merge the base into
206 the branch in a clone and push. See
207 [Merge methods](/guides/pull-requests/#merge-methods).
208- **Status.** Not scheduled.
209
210## Actions and runners
211
212### Docker shares the job's network
213
214A job's Docker Engine runs its containers on the job's own network, not on
215networks of their own. A service is reached at `localhost` and by its
216name, as on GitHub, but two containers cannot listen on the same port, and
217`docker network create` gives no separation between containers.
218
219- **Why.** Jobs run in Cloudflare Containers, which let a container run
220 Docker but not route a container network of its own out, or change its
221 packet filter.
222- **Instead.** Give containers that would clash different ports.
223- **Status.** Not scheduled.
224
225### No `type=gha` build cache
226
227Buildx's GitHub Actions cache backend (`cache-to: type=gha`) is skipped on
228g1t, and the build runs without a cache.
229
230- **Why.** It talks to GitHub's cache service, which g1t's cache does not
231 speak yet.
232- **Instead.** Use a registry cache in g1t's container registry
233 (`type=registry`), or `type=local` with `actions/cache`. See
234 [caching image builds](/guides/actions/#caching-image-builds).
235- **Status.** Planned.
236
237### No multi-platform image builds on g1t's machines
238
239Building an image for another platform, such as `linux/arm64`, needs QEMU's
240emulators, which g1t's machines do not have set up.
241
242- **Instead.** Build other platforms on a
243 [self-hosted runner](/guides/self-hosted-runners/) of that architecture,
244 or one with QEMU set up.
245- **Status.** Planned.
246
247### Linux only on g1t's machines
248
249A job with `runs-on: windows-latest` or `macos-latest` fails on g1t's own
250machines.
251
252- **Instead.** [Self-hosted runners](/guides/self-hosted-runners/) run Linux,
253 macOS and Windows, on x64 and arm64.
254- **Status.** Not scheduled.
255
256### No background steps
257
258GitHub's background steps (`background: true` on a step, and `wait`,
259`wait-all`, `cancel` and `parallel` steps) are refused: a workflow with one
260does not run on g1t. A schedule's `timezone`, `concurrency.queue`,
261`cancel-timeout-minutes` and `snapshot` are read but not applied: schedules
262run in UTC, a concurrency group keeps one run waiting, a cancelled job stops
263in its usual time, and no runner image is made from a job. The workflow's
264page says so.
265
266- **Why.** They are newer than g1t's runner, which runs a job's steps one
267 after another.
268- **Instead.** Start a long-running process with `&` in a `run:` step and
269 stop it in a later one; write a schedule's `cron` in UTC.
270- **Status.** Not scheduled.
271
272### Self-hosted macOS jobs run on the host
273
274On a self-hosted runner, a job native to macOS runs directly on the Mac,
275unsandboxed, in host mode, which is deprecated. Linux jobs run in a
276sandbox of their own on every computer, and Windows jobs in a Windows
277Sandbox per job on Windows 11 Pro, Enterprise and Education. Windows 11
278Home has no Windows Sandbox, so it runs Linux jobs only.
279
280- **Why.** Sandboxed macOS jobs are designed, not built: an ephemeral
281 macOS virtual machine per job, at most two per Mac by Apple's licence.
282- **Instead.** Run Linux jobs in
283 [the sandbox on your computer](/guides/self-hosted-runners/#sandbox-on-your-computer),
284 and keep host-mode Mac runners for repositories whose code you trust.
285 Host mode refuses public repositories' work.
286- **Status.** Planned. See
287 [how each computer runs it](/guides/self-hosted-runners/#how-each-computer-runs-it).
288
289### The runner's sandbox is checked end to end on Windows only
290
291The sandbox for Linux jobs on macOS (a VM under Apple's Virtualization
292framework) and on Linux without Sysbox (a VM under QEMU with KVM) is
293built to the same design as on Windows, but has not yet been run on a
294Mac or on such a Linux machine.
295
296- **Instead.** Run `g1t-runner sandbox status` first: it says what the
297 computer lacks. On Linux, the runner's container under Sysbox needs no
298 VM. See [what it cannot stop](/guides/self-hosted-runners/#what-it-cannot-stop).
299- **Status.** Planned.
300
301### A self-hosted job's Docker can reach its runner's container
302
303On a runner in its container under Sysbox, a job that uses Docker gets an
304engine of its own that is privileged inside the runner's container. It
305cannot reach the machine, but it can reach the runner's container,
306including the runner's credential.
307
308- **Instead.** Use ephemeral runners for code you do not trust, or
309 register with `--no-job-docker`.
310- **Status.** Not scheduled.
311
312### `actions/checkout` with Git LFS, or without git on a large repository
313
314`actions/checkout` is the action itself. With `lfs: true`, it finds no
315LFS files: g1t keeps none. In a job container whose image has no git, it
316downloads the commit as a tarball from
317`GET /repos/{owner}/{repo}/tarball/{ref}`, as on GitHub. g1t makes that
318tarball when it is asked, of up to 10,000 files and 24 MB, so the
319checkout of a larger repository fails there.
320
321- **Why.** The tarball is made in a Worker, which holds the files and the
322 archive in memory at once.
323- **Instead.** Keep large files out of Git LFS for now. For a large
324 repository, use an image with git, or install git in a step before the
325 checkout.
326- **Status.** Planned.
327
328### No `gh` command in jobs
329
330The runner does not include the `gh` command, and pointing it at g1t
331(`GH_HOST=g1t.sh`) does not work.
332
333- **Why.** Most of `gh`'s commands use a GraphQL API, and the rest expect
334 the REST API under `/api/v3` on the same host. g1t's API is REST, at
335 `api.g1t.sh`.
336- **Instead.** Call the API with `curl` and the job's token. See
337 [calling g1t's API from a job](/guides/actions/#calling-g1ts-api-from-a-job).
338- **Status.** Not scheduled.
339
340### One Ruby for `ruby/setup-ruby`
341
342On g1t's machines, `ruby/setup-ruby` finds Ruby 3.3, which the runner
343includes, and fails for any other version.
344
345- **Why.** Its prebuilt Rubies are for other Linux systems, so on Debian it
346 uses only the Rubies already in `RUNNER_TOOL_CACHE`.
347- **Instead.** Use 3.3, run the job in a `container:` with the Ruby you
348 need (such as `ruby:3.4`), or build it in a step with `ruby-build`. See
349 [languages and their setup actions](/guides/actions/#languages-and-their-setup-actions).
350- **Status.** Not scheduled.
351
352### Machine sizes, time and storage
353
354| Limit | Value |
355| --- | --- |
356| Largest machine | 4 vCPUs, 12 GiB of memory, 20 GB of disk (`g1t-4core`). No GPUs. |
357| Standard machine | 2 vCPUs, 8 GiB of memory, 16 GB of disk (`ubuntu-latest`, every other hosted label, and `g1t-2core`). |
358| One job on g1t's machines | 60 minutes. On a self-hosted runner, 24 hours. |
359| One cache entry | 2 GiB, compressed. A larger one is not saved. |
360| A repository's caches | 10 GiB together. Past it, the entries restored longest ago are removed. |
361| One artifact | 5 GiB, zipped. Kept 14 days unless the repository says otherwise, at most 90. |
362| A run's artifacts | 10 GiB together. |
363
364The machine sizes are Cloudflare Containers' instance sizes. For more, use a
365[self-hosted runner](/guides/self-hosted-runners/). See
366[Machine sizes](/guides/actions/#machine-sizes) and [the cache](/guides/actions/#the-cache).
367
368### Workflow features not supported yet
369
370- Actions that upload or download artifacts with the toolkit's artifact
371 library themselves. The library refuses to run against any server but
372 github.com. `actions/upload-artifact`, `actions/download-artifact` and
373 `actions/upload-artifact/merge` work, as g1t runs them itself.
374- A cache entry between 100 and 128 MB saved by `actions/cache` or another
375 action built on the toolkit, such as `setup-node` with `cache: npm`. The toolkit sends an
376 entry under 128 MB in one request, and g1t takes at most 100 MB in one
377 request, as for [pushes](#pushes-up-to-100-mb-each). The step warns and
378 the job goes on; smaller and larger entries are saved.
379- `on: label`: creating, editing or deleting a label starts no workflows.
380 Putting a label on a work item or a pull request starts `work_item` and
381 `pull_request` workflows with the `labeled` type.
382- The `pull_request` activity types `unassigned`, `locked`, `unlocked`,
383 and `edited` for a new title or description, and the `work_item` types
384 `unassigned`, `locked`, `unlocked`, `pinned` and `unpinned`: g1t starts
385 no workflows for them.
386
387See [Not yet](/guides/actions/#not-yet). **Status.** Planned.
388
389### No npm trusted publishing or provenance
390
391A workflow on g1t can't publish to npm with trusted publishing, or with
392`--provenance`.
393
394- **Why.** Both trade the job's OIDC token with npm and Sigstore, which
395 accept tokens only from the CI services they list. g1t's
396 [OIDC tokens](/guides/actions/#oidc-tokens) work with any cloud that
397 lets you add an issuer, and npm does not.
398- **Instead.** Publish with a granular access token in a secret
399 (`NODE_AUTH_TOKEN`); see [npm](/guides/actions/#npm).
400- **Status.** Depends on npm.
401
402## Deployments
403
404### A container is one instance, and keeps nothing
405
406A container app runs one instance at a time, sleeps after five minutes
407without a request, and starts from its image each time it wakes.
408
409- **Why.** Each app's container is one Durable Object's, and Cloudflare
410 Containers' disks last only as long as the container runs.
411- **Instead.** Keep data in a database or a bucket the app reaches over
412 the network. A larger **Container size** gives one instance more room.
413
414### What a container sends out is not counted
415
416The data a container sends back to visitors is metered; what it sends to
417other hosts on the internet (a database elsewhere, an API) is not.
418
419- **Why.** It leaves the container without passing through g1t.
420- **Instead.** Nothing to do: it is not charged.
421- **Status.** A runtime for servers is planned.
422
423### Some Workers bindings are not provisioned
424
425A Workers project deploys without D1, KV, R2, Durable Objects, Queues,
426service bindings, Vectorize, Hyperdrive, Workers AI or Workflows, and its
427cron triggers are not scheduled.
428
429- **Why.** Each of these is a resource g1t has to create and bill per
430 project, and that is not built yet.
431- **Instead.** Check that a binding exists before using it. The deployment
432 lists each binding it left out, and warns when its cron triggers will
433 not run.
434- **Status.** Planned. See [Workers projects](/guides/deployments/#workers-projects).
435
436### Build and size limits
437
438A build stops after 45 minutes. A static site can have up to 20,000 files
439and 25 MiB per file, which are Cloudflare's limits. See
440[Static sites](/guides/deployments/#static-sites).
441
442## Data residency
443
444You can't choose where a workspace's data is stored. g1t's databases keep
445their primary copy in the United States, with read copies in other regions
446so pages load fast. Repositories are not pinned to a region.
447
448- **Why.** Cloudflare fixes the region of a repository store when it is
449 created, and g1t has one store so far.
450- **Instead.** None today, if your data must stay in the EU.
451- **Status.** EU residency, with an EU-only repository store and databases,
452 is planned.
453
454## Billing
455
456### Some costs are not fully defined yet
457
458Cloudflare Artifacts, where every repository is stored, started billing in
459mid-October 2026. Its [pricing](https://developers.cloudflare.com/artifacts/platform/pricing/)
460counts repository operations such as create, push, pull and clone, and
461storage measured from daily peaks. g1t's own counts are still being
462reconciled against that bill.
463
464- **What g1t does.** It counts every clone, fetch and push through its git
465 endpoints. Each day it checks what Cloudflare billed it for containers and
466 apps against what was used. When a cost moves,
467 g1t's price moves with it, and every change is listed with its reason on
468 [g1t.sh/pricing](https://g1t.sh/pricing).
469- **What this means for you.** Prices can change while Cloudflare's beta
470 products settle. They follow cost.
471 See [How prices are set](/guides/usage-and-billing/#how-prices-are-set)
472 and [git operations](/guides/usage-and-billing/#git-operations).
473- **Status.** Depends on Cloudflare.
474
475### Payments in test mode
476
477A g1t whose payments use Stripe's test mode, such as a self-hosted one set
478up with test keys, charges no real card, so a card check there proves
479nothing. g1t.sh takes live payments: the card check and every charge are
480real. **Status.** By design
481for test setups.
482
483## Accounts, status and self-hosting
484
485### Tokens for one workspace you belong to
486
487A personal access token can be made for one workspace only when you are a
488member of it. For a repository where you are an outside collaborator, make
489a token for all your workspaces. A workspace's
490[rules for tokens](/guides/authentication/#a-workspaces-rules-for-tokens)
491cover personal access tokens only, not applications you signed in to with
492OAuth. **Status.** Planned.
493
494### No uptime commitment during the alpha
495
496g1t does not promise a particular uptime or offer a service level agreement
497unless you have a written agreement with us. Several of the Cloudflare
498products g1t is built on are in beta and have none either.
499[status.g1t.sh](https://status.g1t.sh/) shows how each part of g1t is doing,
500and every incident. Sandboxes are not checked there yet. See
501[Status and incidents](/guides/status/). **Status.** Not scheduled during
502the alpha.
503
504### Self-hosting is early
505
506[Running g1t yourself](/guides/self-hosting/) gives you the core forge:
507accounts, repositories over HTTP, work items and pull requests, the REST API
508and MCP, container images, search, webhooks and observability. Hosted
509runners, deployments, billing and git over SSH are off. The merge queue
510can accept pull requests, but cannot test or land them without g1t's
511runner. Use the hosted service to try that integration loop. Self-hosting
512is not ready for the open internet. **Status.** Planned, in phases.
513
514### No wikis
515
516A repository has no wiki. **Instead.** Keep docs in the repository, or
517write them together in [Artifacts](/guides/artifacts/). **Status.** Not
518scheduled.