# Run your whole Fly.io Machine fleet from one screen

> See every Machine across all your Fly.io apps in one table, spot the ones that are down or restarting, and start, stop or restart them without a terminal.

- Workflow type: app
- Services: Fly.io, Slack Bot
- Categories: Engineering, Operations
- Published: 2026-08-21

## What it does

- One table of every Machine across all your Fly.io apps, showing its app, ID, region, size, current state and how long it has been in that state, with filters for app, region and state.
- Anything stopped, failed or stuck in a restart loop is highlighted at the top, so the problems find you instead of you hunting through a command line.
- Click any Machine to see its recent activity, what is actually running inside it, and how its setup has changed over time, then start, stop, restart or suspend it right there. Permanently deleting a Machine is possible but sits behind an explicit confirmation.
- A Diagnose button hands the Machine to an assistant that reads its recent history and writes a plain-English explanation of what likely went wrong and what to do next, which you can then post to your incident channel in Slack with one click.

## What you'll need

- A Fly.io account, plus an access key that covers your whole organization rather than a single app, so the board can see every app you run.
- A Slack workspace, if you want to post diagnoses into an incident channel. The board works fine without it.
- Nothing else. The whole point is that engineers who have never touched Fly's command line tool can work this board.

## Prompt

I want an app that works as a control room for every Fly.io Machine we run. The Fly dashboard is minimal and the workflow is command-line first, so today nobody can see the whole fleet on one screen without running flyctl. Build this so an on-call engineer who has never touched flyctl can work it confidently.

The main view is a single table of every Machine across all of my apps. Load it with List Apps to get the apps in my organization, then List All Machines for the org to pull every Machine in one org-wide read rather than looping List Machines per app. Each row shows the app name, the Machine ID, the region, the size (CPU kind, CPU count and memory), the current state, and how long the Machine has been in that state, shown as a readable relative duration like "stopped for 4h 12m" and derived from the timestamp of its most recent state change. Give me filters for app, region and state, plus a free-text search on Machine ID and app name, and make the whole table sortable, defaulting to the most alarming rows first.

Highlight trouble so it finds the engineer instead of the other way round. Visually flag any Machine that is stopped or failed, and any Machine that is restarting repeatedly. For the restart-loop flag, prefer recent event data that already comes back with the fleet listing; only if it is not there should the app fetch List Events, and then only for Machines that are already in a non-healthy state, in a throttled background pass whose results are cached. Do not fetch per-Machine events for the entire fleet on load. Put a small summary strip at the top with counts of total Machines, running, stopped, failed and restart-looping, so the state of the world is obvious in one glance.

Clicking a Machine opens a detail panel next to the table without losing my filters. Populate it with Get Machine for the full current config and state, List Events for a reverse-chronological activity timeline, List Processes for what is actually running inside the Machine right now, and List Versions for the config version history. Render the events timeline in plain language with human-readable timestamps rather than raw event payloads, and in the version history show what changed between versions, especially image, resources and environment, so an engineer can spot "this broke right after the last deploy" instantly.

The detail panel has action buttons so on-call can act without opening a terminal: Start Machine, Stop Machine, Restart Machine and Suspend Machine. Only show the actions that make sense for the Machine's current state, show a clear in-progress indicator while the action runs, and refresh that Machine's row and panel afterwards so the new state and the reset time-in-state are visible immediately. If an action fails, surface the actual error message from Fly rather than a generic failure.

Destroy Machine should be available too, but guarded. Keep it visually separate from the safe actions and put it behind an explicit confirmation where the engineer has to acknowledge the specific app name and Machine ID before it proceeds, so a stray click on a crowded board can never delete anything. Once destroyed, remove the row and say plainly what was destroyed.

Add a "Diagnose this Machine" button in the detail panel that kicks off a background agent for that Machine. The agent reads the recent events, the running processes and the config version history, then writes a plain-English diagnosis back into the app saying what likely went wrong and what to do next. It should call out concrete patterns like out-of-memory kills, a crash loop that started right after a specific config version, health checks failing, or a Machine that was stopped deliberately rather than crashing, and it should end with a short recommended next action. Store each diagnosis against the Machine with a timestamp and show it in the panel, keeping previous diagnoses as history so an engineer can see whether this has happened before. While the agent is working, show that it is running so nobody clicks twice.

Under a completed diagnosis, add a follow-up button that posts it to our incident channel using the Slack Send a Message action. Let me pick the channel, and format the message so it stands alone for someone who was not looking at the board: app name, Machine ID, region, current state, the diagnosis, and the recommended next action. Mark on the diagnosis record that it has been posted, with when and to which channel, so we do not double-post the same thing into an incident.

Two things to get right technically. First, the org-wide reads need an organization-scoped Fly access token, not an app-scoped deploy token; if the connected token is app-scoped, the org endpoints will fail with a permission error, so detect that and show a clear message telling me to reconnect with an org-scoped token instead of rendering an empty or half-broken board. Second, Fly rate limits are roughly one request per second per action, so the fleet view must page through the cursor-paginated org-wide results properly, continuing until no cursor is returned, and cache what it fetched rather than hammering per-Machine reads. Reads should be batched and paced, with a manual refresh control and a visible "last updated" timestamp so I always know how fresh the board is.

Design it for a stressed on-call engineer at 3am: dense enough to see the whole fleet at once, legible at a glance, states colour-coded consistently, and no Fly jargon or raw API field names anywhere in the interface.

## How to customize

- Change what counts as urgent, for example treating a Machine that has been stopped for an hour differently from one that stopped a minute ago, or setting how many restarts in a row count as a restart loop.
- Pick which Slack channel diagnoses post to, and adjust the tone and length of what the assistant writes.
- Hide apps you do not want on the board, such as preview or test environments, so on-call only sees what matters at 3am.

## FAQ

### Do I need to know Fly's command line tool to use this?

No, and that is the point. Everything the board does, including starting, stopping, restarting and suspending Machines, happens through buttons. Someone who has never opened a terminal can pick up an on-call shift and still act on what they see.

### Will this work if I only have a deploy key for a single app?

Not for the full fleet view. A single-app deploy key can only ever see that one app, so the board would show a fraction of your Machines. Use an access key scoped to your whole Fly.io organization and the board will pull in every app automatically.

### Can someone delete a Machine by accident?

Deleting is deliberately harder than everything else. It sits behind an explicit confirmation step where you have to acknowledge exactly which Machine is going away, so a stray click on a crowded board cannot destroy anything.

### How current is the information on the board?

The board loads your fleet when you open it and you can refresh it whenever you want. It deliberately reads in batches and reuses what it already fetched rather than checking every Machine constantly, because Fly limits how often it will answer, and a board that hammers the service ends up slower and less reliable than one that paces itself.

### Does the diagnosis get sent to Slack automatically?

No. The assistant writes its diagnosis into the app first so you can read it and judge whether it is right. Posting it to your incident channel is a separate button you press only when you want the rest of the team to see it.

Use this prompt in General Input: https://www.generalinput.com/prompts/run-your-whole-flyio-machine-fleet-from-one-screen