# How I fixed a stuck Cloudflare Pages build queue

> My Cloudflare Pages deploys froze: one build stuck for five hours and 35 queued behind it. How to inspect the build queue and cancel builds with the API.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2026-08-05 | Topics: [Cloudflare](https://flaviocopes.com/tags/cloudflare/) | Canonical: https://flaviocopes.com/fix-stuck-cloudflare-pages-build-queue/

The other night my Cloudflare Pages deploys stopped.

I pushed commits, nothing went live. When I looked at the deployments list I found the problem: one build had been sitting in the "building" stage for **five hours**, and 35 builds were queued behind it.

Cloudflare Pages runs one build at a time. If a build hangs, everything behind it waits. In my case, forever.

Here is how I diagnosed it and fixed it with two API calls.

## How did it happen?

I had several coding agents working on the site in parallel, each committing and pushing as it finished a task.

The result was about 60 pushes in 20 minutes. Every push to the production branch queues a full build — Pages does not skip superseded builds like some CI systems do.

The first batch built fine. Then one build started and never finished. It just sat there in `build: active` while the queue behind it grew.

## How do you see the build queue?

The dashboard shows deployments, but the API gives a clearer picture. You need your account ID and an API token with Pages edit permission:

```bash
API="https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/pages/projects/$PROJECT"

curl -s "$API/deployments?per_page=15" \
  -H "Authorization: Bearer $CF_API_TOKEN" |
  jq -r '.result[] | .created_on + "  " + .latest_stage.name + ":" + .latest_stage.status'
```

A healthy deployment ends with `deploy:success`. Mine looked like this:

```text
2026-08-03T15:32:24  queued:active
2026-08-03T15:31:27  queued:active
2026-08-03T15:30:42  queued:active
...
2026-08-03T15:17:17  build:active     <- stuck here for 5 hours
```

There was another clue before I even opened the deployments list: POSTing a deploy hook returned HTTP `304`. Pages refuses to create a new build while builds for the same branch are already queued.

If your deploy hooks start answering `304` and nothing ships, check the queue.

## Cancel the stuck build

The fix is one API call, the same thing the dashboard's Cancel button does:

```bash
curl -s -X POST "$API/deployments/<deployment_id>/cancel" \
  -H "Authorization: Bearer $CF_API_TOKEN"
```

The `<deployment_id>` is the `id` field of the stuck deployment from the previous command.

The moment the stuck build was canceled, the queue started moving again.

## Skip the stale builds

There was a second problem. The queue drains oldest first, and my 35 queued builds were all intermediate commits.

Building them one by one would have taken a couple of hours, producing 34 deployments of stale code and one useful deployment at the end.

Only the newest queued build matters — it builds the latest commit. So I canceled all the others:

```bash
curl -s "$API/deployments?per_page=25" \
  -H "Authorization: Bearer $CF_API_TOKEN" |
  jq -r '[.result[] | select(.latest_stage.name == "queued")]
         | sort_by(.created_on) | .[:-1][] | .id' |
  while read id; do
    curl -s -X POST "$API/deployments/$id/cancel" \
      -H "Authorization: Bearer $CF_API_TOKEN" > /dev/null
    echo "canceled $id"
  done
```

The `jq` filter selects the queued deployments, sorts them by creation time, and drops the last one — the newest — so it survives.

A few minutes later the newest build finished, and production was up to date again.

## What I learned

**Every push queues a full build.** Pages doesn't collapse a burst of pushes into one build. If you run parallel agents (or any automation) that pushes often, expect the queue to grow fast.

**A stuck build blocks everything.** If deploys look frozen, check for a deployment in `build: active` that has been there far longer than your normal build time before assuming anything else is wrong.

**The `304` from a deploy hook is a signal.** I hit it while setting up [my daily scheduled rebuild](https://flaviocopes.com/scheduled-cloudflare-pages-rebuilds/), and it's what led me to the stuck queue in the first place.
