# How to use Codex Cloud

> How to use Codex Cloud: prepare a reusable cloud environment, run Codex tasks on OpenAI's VMs while your laptop sleeps, and review the diff or open a PR.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2026-10-01 | Topics: [AI](https://flaviocopes.com/tags/ai/) | Canonical: https://flaviocopes.com/codex-cloud/

Codex Cloud runs Codex tasks on a virtual machine at OpenAI instead of on your computer. You prepare a **cloud environment** once, with your repositories, dependencies and tools, and every task starts from its own copy of it.

The task keeps working when you close the laptop. You can follow it from the web, the ChatGPT desktop app or your phone, and when it's done you review the diff and the test results, ask for changes, and open a pull request.

This guide covers the version OpenAI launched at DevDay 2026, where Codex prepares the environment for you in a conversation. I checked every step against the [official Codex Cloud docs](https://learn.chatgpt.com/docs/cloud) at the end of September 2026.

If you haven't used Codex yet, start with [my complete guide to Codex](https://flaviocopes.com/codex/). It covers the desktop app and the CLI, and here we only look at the cloud part.

## What changed at DevDay 2026

A cloud environment used to be a container based on OpenAI's `codex-universal` image. Codex installed dependencies for the common package managers, and for anything more you wrote a setup script yourself, plus an optional maintenance script for cached containers.

Now you pick the repositories and Codex does the setup. It inspects the code, installs what the project needs, runs the workflow to check it works, and asks you when something is missing. You review what it prepared and publish it.

The old experience is still there as **Codex Cloud (Legacy)**. It keeps running code review, `@codex review` comments on GitHub pull requests and the Linear integration, and OpenAI plans to deprecate it. If a tutorial tells you to paste a setup script into the environment settings, it's describing the legacy version.

## What you need

- A ChatGPT **Plus**, **Pro**, **Business**, **Enterprise** or **Edu** plan. Free and Go include Codex in the desktop app, but not the cloud.
- Your ChatGPT account. With an OpenAI API key, Codex works locally but the cloud features are off.
- A repository on GitHub. GitLab and self-hosted GitHub Enterprise Server aren't supported yet.

Cloud tasks draw from the same usage allowance as your local Codex chats, and OpenAI says a cloud task can use more of it than a local message. The usage page in ChatGPT shows where you stand and when the limits reset.

Each task runs in its own VM. The default size depends on the plan:

| Plan | vCPUs | Memory | Disk |
| --- | ---: | ---: | ---: |
| Plus, Edu Plus | 2 | 8 GiB | 8 GiB |
| Pro, Business, Enterprise | 4 | 16 GiB | 32 GiB |
| Edu, Edu Pro | 4 | 16 GiB | 32 GiB |

Enterprise workspaces can ask OpenAI for larger VMs.

## Cloud or your computer?

In the desktop app, a new Codex chat can run in your local checkout or in a worktree, and both of those live on your computer. **Work in** > **Cloud** sends it to OpenAI's VM instead.

The difference that matters is what the agent can see. A local chat sees your whole machine: the `.env` files, the database you have running, the tools you installed, your personal skills. A cloud task sees only what the environment gives it.

So cloud fits a task that takes a while, can check itself with tests and a build, and doesn't need anything that only exists on your machine. It also fits when you won't be at your desk, because nothing runs on your computer.

Don't confuse it with **Codex Remote**, which has a similar pitch. Remote lets you start and approve tasks from your phone, but they run on your own Mac or PC, and that computer has to stay awake and online.

## The example project

We'll set up an environment for [Waiting Lists](https://flaviocopes.com/software/waiting-lists/), a small open source app of mine. It's an email-only waiting list service built with Astro that runs as a Cloudflare Worker, with a D1 database, Vitest tests and a command-line client.

It needs more than `npm install` before the tests pass, which makes it a fair test for a cloud environment. Its [`AGENTS.md`](https://flaviocopes.com/agents-md/) lists the local setup:

```sh
npm ci
cp .dev.vars.example .dev.vars
npm run db:migrate:local
npm run check
npm test
npm run dev
```

The checks it expects before handing work back are `npm run check`, `npm test` and `npm run build`.

Follow along with your own repository. The steps are the same, and a README or `AGENTS.md` that lists your setup commands gives Codex less to guess.

## Step 1: create the environment

Open ChatGPT on the web or in the desktop app and sign in. In a new task, choose **Work in** > **Cloud**, open **Select environment** and select **Create environment**.

You can also get there from **Settings** > **Codex Cloud** > **Environments** > **Create environment**.

Pick the GitHub repositories to check out. The first time, ChatGPT asks you to connect GitHub. Then select **Get started**.

Codex now inspects the repositories, installs dependencies and tools, and tests the workflow. This part is a conversation, so you can steer it. For Waiting Lists I would say what a working setup looks like and where to stop:

```text
Set up this repository for development and testing. Use Node 22.
Run npm ci, copy .dev.vars.example to .dev.vars, and apply the local
D1 migrations. Then run npm run check, npm test and npm run build.
Don't create Cloudflare resources and don't deploy anything.
```

The last line is there because Waiting Lists can deploy itself with `wrangler`. None of these commands needs a Cloudflare account: the local migrations, the type check, the tests and the build all pass with the example `.dev.vars` copied as is. So the environment never gets a Cloudflare token, and deploys stay on my computer.

When Codex needs something it can't work out on its own, like a secret or a version number, it asks in the chat. You can also ask for specific versions, commands or services.

It records the tested setup in two fields:

- **Install script**: the commands that install dependencies and prepare the project.
- **Start skill**: instructions to start services and check they're ready.

You don't write either of them. You read them, and if something is off you tell Codex in the conversation.

## Step 2: review and publish

When Codex finishes, it shows a setup report with the configuration and the files it prepared. Read it before publishing. Check that the commands you care about ran and passed, and resolve anything it left unfinished.

Then save the changes, select **Publish**, and wait for **Environment published**.

Saving and publishing are different steps. Saving stores the configuration, and some settings apply to the setup you're working in right away. Publishing captures the prepared filesystem, and that snapshot is what every new task starts from.

An environment you saved but never published shows an **Unpublished** badge in **Settings** > **Codex Cloud** > **Environments**, and you can't start tasks from it yet.

Who else can use the environment is a separate setting, under **Privacy** > **Who can use**. **Only me** keeps it private. Sharing it with your workspace is an Enterprise feature, and it shares the setup, not your tasks or your personal credentials. The prepared files and the values saved on the environment do go with it, so review them before you share.

## Step 3: start a task

After publishing, select **Start a new task**. Next time, pick the environment from **Select environment** and start right away.

Describe the task the same way you would locally. Here's a real one for Waiting Lists. The subscriber export supports Sendy, Kit and Mailchimp, and Buttondown is missing:

```text
Add a buttondown export format next to sendy, kit and mailchimp in
src/lib/csv-export.ts. Use Buttondown's import docs at
https://docs.buttondown.com/importing-your-data for the columns.
Add it to the format options and to the CLI help, and add tests in
src/lib/csv-export.test.ts like the existing ones.
Run npm run check, npm test and npm run build before you finish.
```

Codex edits the files, runs the commands and comes back with the changed files and the check results. Each task gets its own workspace, so two tasks started from the same environment never edit each other's files.

Notice the link to Buttondown's docs in the prompt. The task can open that page only if the environment allows it, which we'll set up in a minute.

Review the diff and the results, then ask for follow-ups in the same task:

```text
Also add Buttondown to the export section of the README.
```

When it's right, commit or open a pull request from the task. My public repositories have pull requests turned off on GitHub, so for Waiting Lists I would pull the diff onto my computer with the CLI instead. We'll see how later.

Either way, the agent hands you a change and you decide whether it goes in. It's the same boundary I keep for every agent I'm not sitting with, and I wrote the rest of that list in [things I let coding agents do unattended](https://flaviocopes.com/agents-unattended/).

## Follow the task from your phone

To continue a task on another device, reopen the same task on the web, in the desktop app, or under **Codex** in the ChatGPT mobile app. Starting a new task instead starts separate work from the published environment.

The phone can run and continue tasks, but it can't create environments. Create and publish them on the web or in the desktop app first.

A task keeps its own files between turns, including uncommitted changes and the tools it installed. That saved state stays recoverable for up to seven days after you last started a turn or resumed the task. It's not a backup, so commit what you want to keep.

## Let the environment reach the internet

The environment decides which domains its VM can reach. Open its configuration and turn on **Allow Codex to access internet**, then pick a policy under **Allow domains**:

- **Package managers** allows a preset list of registries and download hosts: npm and Yarn, PyPI, crates.io, the Go proxy, Maven and Gradle, the Ubuntu and Debian archives, GitHub source and releases, and a few more.
- **Custom domains only** allows only the hosts you add.
- **All (unrestricted)** allows everything, for workflows that need broad access.

Add extra hosts under **Additional allowed domains**. For Waiting Lists, **Package managers** covers the npm registry, and the Buttondown task needs one more host, `docs.buttondown.com`. Add the exact host, because an entry for a root domain doesn't cover its other subdomains.

Save, test the access during setup, then publish or republish and check it again in a new task.

Allowing a domain doesn't give Codex an account there. It can reach the host, and credentials are a separate step.

## Environment variables and network secrets

You can give an environment values in two ways:

| Type | Use it for | What programs receive |
| --- | --- | --- |
| Environment variable | A value a program reads directly, like `APP_MODE=development` | The value |
| Network secret | A credential for an HTTPS service, like a private npm registry token | A placeholder |

The raw value of a network secret never lands in a process or a file in the environment. Programs get a placeholder, and the network proxy swaps in the real value on requests to the domains you listed. A script that prints its environment prints the placeholder.

That's why a network secret has three fields: **Key**, **Value** and **Allowed domains**. The swap happens only for HTTPS on port 443, both during setup and during tasks. Saving one also adds its domains to the environment's allowed list.

The catch is a program that needs to read the raw value itself. It only ever sees the placeholder, so it fails. Put that one under **Environment variables** instead, with a different key from any network secret.

You manage both from the environment configuration, with **Manage** next to **Environment variables** or **Network secrets**.

There's also a **Personal vault** under **Settings** > **Codex Cloud**, for your own values. A shared environment can ask each person for a value, and each one fills it in from their own account.

Waiting Lists doesn't need either. Its `.dev.vars` is a local file the setup copies from the example, and the tests pass with its empty values.

## Update the environment

When the project changes, say a new dependency or a new service, update the environment. Open **Settings** > **Codex Cloud** > **Environments**, choose **Edit** from the environment's **…** menu, and describe the change. Codex prepares and tests it, you save, and you select **Republish**.

Only new tasks get the update. A task that already exists keeps its own state.

You don't need to republish after every commit. The repository is refreshed in the background, and the dependency caches are kept without rerunning the install and start steps.

## Start cloud tasks from the terminal

The Codex CLI has a `codex cloud` command, still marked experimental in its help. I checked these options against the latest release at the end of September 2026.

Run `codex cloud` alone to open an interactive picker for your tasks and environments. That's also where you find an environment's ID.

To submit a task, run `codex cloud exec` from inside the repository with the environment ID:

```bash
codex cloud exec --env "$ENV_ID" "Add a buttondown export format next to sendy, kit and mailchimp"
```

The task runs on your current Git branch. Pass `--branch` to pick another one.

`--attempts` asks for up to four attempts at the same task, so you can compare them and keep the best one:

```bash
codex cloud exec --env "$ENV_ID" --attempts 3 "Improve the empty state of the dashboard when there are no waiting lists yet"
```

`codex cloud list` shows your recent tasks, 20 at a time, with `--env` to filter by environment and `--cursor` for the next page. Add `--json` for scripts. With no tasks yet, you get this:

```json
{
  "tasks": [],
  "cursor": null
}
```

Each task in that array has an `id`, a `url`, a `title`, a `status`, an `updated_at` date, the environment, a `summary` and an `attempt_total`.

To check one task and read its changes:

```bash
codex cloud status "$TASK_ID"
codex cloud diff "$TASK_ID" --attempt 2
```

To bring the changes onto your computer:

```bash
codex cloud apply "$TASK_ID" --attempt 2
```

It runs `git apply` on your working tree and exits with an error if the patch doesn't apply cleanly, for example because of a conflict. Without `--attempt` it takes the first attempt. There's also a shorter `codex apply "$TASK_ID"` that applies the task's latest diff.

This is how I would close the Buttondown task: apply the diff, read it in my editor, run the checks, and commit it myself.

## Start tasks from Slack or Teams

In an Enterprise workspace with Cloud delegation turned on, you can mention `@ChatGPT` in Slack or Microsoft Teams and ask it to work on a repository:

```text
@ChatGPT add a buttondown export format to the waiting-lists repo and run the tests.
```

ChatGPT picks a published environment shared with the workspace and runs the work as a separate Codex Cloud task under your account. Your personal environments aren't included, so share the one you want first. The result comes back in the thread, and everyone in the channel can read it, so keep secrets out of the conversation.

If your team used `@Codex` before, start new requests with `@ChatGPT` once your admin turns on the ChatGPT app.

## What Codex Cloud can't do yet

- There's no browser use or computer use in cloud environments. A task can't open the app it just changed and click through it.
- GitLab and self-hosted GitHub Enterprise Server aren't supported.
- Skills stored in the repository work in cloud tasks. Personal skills from your computer don't sync, so commit a skill to the repo if a cloud task needs it.
- Private networks go through a VPN, and Tailscale is the only supported provider. It covers HTTP and HTTPS services over IPv4, with no private DNS, no SSH and no native database protocols.
- Short-lived cloud credentials through OIDC are Enterprise-only, and you have to ask OpenAI to turn them on.

## When the setup or a request fails

If the setup fails or a tool is missing, find the command that failed in the setup conversation and ask Codex to diagnose it and run it again, with something like "Install pnpm and run the project's tests". For a failed first setup, **Try again** retries with the same repositories. If the fix means changing source files, the package manifest or the lockfile, do that in a normal task, then come back to the setup.

The failure you'll probably hit first is a package download or an HTTPS request that doesn't go through. Check the host and the credentials separately:

1. Is the exact hostname allowed? A private registry at `packages.acme.dev` might also download from `downloads.acme.dev`, and that host needs its own entry.
2. Does the package manager point at the right URL with the right credentials? Allowing a domain doesn't log you in.
3. If the credential is a network secret, do its **Allowed domains** include that host, and does the request use HTTPS on port 443?

If a value seems missing, check where you put it. A program that reads the value directly needs an environment variable, not a network secret. For a personal value, check that its key matches what the environment asks for and that **Applies to** includes this environment.

And if an environment doesn't show up when you start a task, look for the **Unpublished** badge in **Settings** > **Codex Cloud** > **Environments**.

## How I would use Codex Cloud

Most days I work with local agents that can see my computer, one task at a time, and I commit to master myself. Codex Cloud goes the other way, so I would use it for a narrow set of jobs.

The first is the kind I already hand to cloud agents. Every two weeks a [Grok Bot](https://flaviocopes.com/grok-bot/) checks the provider prices behind HostingPicker and Payment Processor and hands the changes to a Cursor cloud agent, which comes back with a PR I read line by line. Codex Cloud has the same shape: a task with a clear end, checked by tests, that finishes with a diff I review.

The second is maintenance on my open source packages, the apps on [my software page](https://flaviocopes.com/software/). They're small and they don't need anything from my Mac, and Waiting Lists runs its whole test suite in under a second. A dependency upgrade or a feature like the Buttondown export is a good fit. I could start it from my phone while I'm away and apply the diff when I'm back at my desk. The deploy would still happen from my computer.

One of my complaints about Codex in [the Codex guide](https://flaviocopes.com/codex/) is that local scheduled tasks need the computer awake. A cloud task doesn't care if the laptop is closed.

Where it doesn't fit is anything that needs my computer. There's no browser use in the cloud, so a change I want to check by clicking through the UI stays local. The same goes for tasks that use the models I run in Ollama and LM Studio, and for work that depends on the skills in my home folder.

My advice is to try it first on a repository whose tests you trust. From your phone, the test results are most of what you'll have to judge the change by.
