Worker crashed 3 times overnight, bill heading for $38
worker in production crashed 3 times since 02:10 and is restarting. Usage this cycle is $23.40, with an estimated bill of $38.10.
Every morning: Railway deployments that failed or crashed since yesterday, with the error lines, plus usage so far and the estimated bill for the cycle.
What lands on your board
worker in production crashed 3 times since 02:10 and is restarting. Usage this cycle is $23.40, with an estimated bill of $38.10.
Railway restarts a crashed service on its own, which keeps the site up and also hides the crash loop that has been running since 3 a.m. Usage-based billing has the same shape: nothing looks wrong until the invoice, because memory left high on a forgotten service costs a little every hour.
The agent checks each service's deployments for FAILED and CRASHED, reads the build or runtime log around the failure, and adds the workspace's usage so far with the estimated bill from the Railway CLI. One card covers both: what broke overnight and what the month will cost.
Take the project, service and environment IDs from the prompt, or from the dashboard URL (/project/<projectId>/service/<serviceId>?environmentId=<id>). Usually only the production environment matters.
Query https://backboard.railway.com/graphql/v2 with deployments(input: {projectId, environmentId, serviceId}, first: 20) { edges { node { id status createdAt url } } }. Keep deployments created since yesterday with status FAILED or CRASHED, and note each service's newest status.
For FAILED, query buildLogs(deploymentId: $id, limit: 200); for CRASHED, deploymentLogs(deploymentId: $id, limit: 200). Keep the lines with severity error and the few before them.
Run railway usage --json for the current period: current usage, current bill and estimated bill. Add railway usage projects --project <name> to see which service drives CPU, memory and egress.
Services that are down or crash-looping first, with the error line; deployments that failed but were replaced by a good one after; then usage so far, the estimate, and the service with the biggest share.
With BRIEFKIN_TOKEN set, the agent sends the result as one card that updates in place every run. Without it, you get the report in the chat.
Pick your agent, where the data comes from and how to schedule it; the commands below follow.
One command. It puts the SKILL.md in ~/.claude/skills and in ~/.agents/skills, which Codex, Cursor, Gemini CLI, Copilot CLI and OpenCode read too.
shellcurl -fsSL https://briefkin.dev/skills/railway-deploys-and-usage/install | shAsk Claude Code:
promptRun the railway-deploys-and-usage skillOr paste the prompt instead of installing:
promptCheck my Railway services (read only). For each service in the production environment, query the public GraphQL API at https://backboard.railway.com/graphql/v2: deployments(input: {projectId, environmentId, serviceId}, first: 20) with id, status and createdAt. List deployments created since yesterday with status FAILED or CRASHED, and say whether each service's newest deployment is healthy. For failures read buildLogs, for crashes deploymentLogs (limit 200), and give the first error line. Then run railway usage --json and give usage so far this billing period and the estimated bill, and use railway usage projects to name the service with the largest cost. Put services that are broken now first. Do not redeploy or change anything.Every day at 8:00, from cron on any machine where Claude Code is signed in:
crontab0 8 * * * claude -p "Run the railway-deploys-and-usage skill"Add it with crontab -e. A laptop asleep at that time runs it when it wakes if you use launchd or Task Scheduler instead; GitHub Actions works for the API route.
Connect Briefkin once with curl -fsSL https://briefkin.dev/install | sh and every run lands on your board as a report card. How setup works
SKILL.md---
name: railway-deploys-and-usage
description: "Every morning: Railway deployments that failed or crashed since yesterday, with the error lines, plus usage so far and the estimated bill for the cycle. Use when the user asks for this, or when it runs on a schedule."
---
# Railway deploys and usage
Every morning: Railway deployments that failed or crashed since yesterday, with the error lines, plus usage so far and the estimated bill for the cycle.
Railway restarts a crashed service on its own, which keeps the site up and also hides the crash loop that has been running since 3 a.m. Usage-based billing has the same shape: nothing looks wrong until the invoice, because memory left high on a forgotten service costs a little every hour.
The agent checks each service's deployments for `FAILED` and `CRASHED`, reads the build or runtime log around the failure, and adds the workspace's usage so far with the estimated bill from the Railway CLI. One card covers both: what broke overnight and what the month will cost.
## Two ways to get the data
Use the API or MCP route when you have an MCP server, a CLI or an API token for the app. Otherwise, if you can drive a browser the user is signed in to (Claude in Chrome, a Playwright or Chrome DevTools MCP server), use the browser route. Say which one you used.
## Route A: API or MCP server
### What you need
- A Railway account or workspace token in `RAILWAY_TOKEN` (sent as `Authorization: Bearer`), and the Railway CLI logged in for the usage numbers.
- The official Railway MCP server (`https://mcp.railway.com`) works for project lookups; deployment lists and usage come from the API and CLI.
If something is missing, say what and stop; do not invent numbers.
### Steps
1. **Collect the services to watch**: Take the project, service and environment IDs from the prompt, or from the dashboard URL (`/project/<projectId>/service/<serviceId>?environmentId=<id>`). Usually only the production environment matters.
2. **List recent deployments** (Railway): Query `https://backboard.railway.com/graphql/v2` with `deployments(input: {projectId, environmentId, serviceId}, first: 20) { edges { node { id status createdAt url } } }`. Keep deployments created since yesterday with `status` `FAILED` or `CRASHED`, and note each service's newest status.
3. **Read the logs around the failure** (Railway): For `FAILED`, query `buildLogs(deploymentId: $id, limit: 200)`; for `CRASHED`, `deploymentLogs(deploymentId: $id, limit: 200)`. Keep the lines with `severity` error and the few before them.
4. **Read usage and the estimate** (Railway): Run `railway usage --json` for the current period: current usage, current bill and estimated bill. Add `railway usage projects --project <name>` to see which service drives CPU, memory and egress.
5. **Report**: Services that are down or crash-looping first, with the error line; deployments that failed but were replaced by a good one after; then usage so far, the estimate, and the service with the biggest share.
## Route B: the browser
### What you need
- Signed in to Railway as a member of the workspace; the Usage page needs a workspace member, not a project-only invite.
If something is missing, say what and stop; do not invent numbers.
### Steps
Start at https://railway.com/dashboard. The user is signed in already; never type passwords or codes, and ask if a sign-in page appears.
1. **Open the project in the production environment**: From the dashboard pick the workspace and the project. Use the environment switcher at the top of the canvas to select **production**; each service tile shows its newest deployment status and when it last deployed.
2. **Read each service's deployments**: Click a service and open its **Deployments** tab. Note every deployment since yesterday with the status **Failed** or **Crashed**, with its time, and whether the top deployment is **Active**. A service with several crashed entries in a row is crash-looping.
3. **Read the logs behind the failure**: On a failed or crashed deployment choose **View logs**. For a failed build read the **Build Logs** tab; for a crash read the **Deploy Logs** tab, filter with `@level:error` and take the first error line with the few lines before it.
4. **Read usage and the estimate**: Open the workspace's **Usage** page (workspace menu in the top left, then **Usage**). Read **Current usage**, **Estimated bill** and the billing period, then expand the per-project and per-service breakdown to find the largest CPU, memory and egress line.
5. **Report**: Services broken now first with the error line; deployments that failed but were replaced by an active one after; then usage so far, the estimate and the service with the biggest share, with one line on what to fix or scale down first.
Note: The dashboard route works well for a project with a few services; a workspace with many services is faster through the API and CLI. Deploy logs stream in the browser and only keep a recent window, so an error from early in a long-running deployment may need the log filter to surface.
## The report
- **Broken now**: services whose newest deployment failed or crashed, with the error line.
- **Recovered**: failures a later deployment replaced.
- **Usage**: spend so far this cycle and the estimated bill.
- **Biggest cost**: the service and resource behind it.
- One line on what to fix or scale down first.
## Post it to Briefkin
When `BRIEFKIN_TOKEN` is set, or `~/.config/briefkin/env` exists (the installer from https://briefkin.dev/docs writes it), also send the result to the user's Briefkin board as one card. Keep the `item_key` the same on every run so the card updates in place, use a new `event_id` per run, and put today's real numbers in place of the example ones. If the request fails, say so once and carry on.
```bash
[ -n "${BRIEFKIN_TOKEN:-}" ] || . ~/.config/briefkin/env
curl -sS -X POST "${BRIEFKIN_URL:-https://briefkin.dev}/v1/events" \
-H "authorization: Bearer $BRIEFKIN_TOKEN" \
-H "content-type: application/json" \
-d @- <<'JSON'
{
"v": 1,
"event_id": "railway-deploys-and-usage/<date of this run, e.g. 2026-10-16>",
"item_key": "railway-deploys-and-usage",
"project": "acme",
"source": "Railway deploys and usage skill",
"kind": "update",
"title": "Worker crashed 3 times overnight, bill heading for $38",
"summary": "**worker** in production crashed 3 times since 02:10 and is restarting. Usage this cycle is **$23.40**, with an estimated bill of **$38.10**.",
"work_state": "failed",
"widget": [
{
"type": "Table",
"props": {
"columns": [
"Service",
"Status",
"Since",
"Error"
],
"rows": [
[
"worker",
"CRASHED",
"02:10",
"JavaScript heap out of memory"
],
[
"api",
"SUCCESS",
"Oct 15",
"Failed build at 16:20, replaced at 16:41"
],
[
"web",
"SUCCESS",
"Oct 12",
""
]
]
}
},
{
"type": "KeyValue",
"props": {
"items": [
{
"key": "Billing period",
"value": "Oct 1 to Oct 31"
},
{
"key": "Usage so far",
"value": "$23.40"
},
{
"key": "Estimated bill",
"value": "$38.10"
},
{
"key": "Largest share",
"value": "worker memory, $11.80 so far"
}
]
}
},
{
"type": "Callout",
"props": {
"text": "worker runs out of memory while processing the nightly export. Raise its memory limit or stream the export in batches.",
"tone": "warn"
}
}
]
}
JSON
```
Widgets come from the Briefkin catalog (https://briefkin.dev/v1/catalog). Without a token, just give the user the report.
## Run it on a schedule
Suggested: Every day at 8:00 (`0 8 * * *`). From cron, with the agent signed in on that machine:
```bash
0 8 * * * claude -p "Run the railway-deploys-and-usage skill"
# Codex: codex exec, Gemini CLI: gemini -p, Copilot CLI: copilot -p, OpenCode: opencode run
```
Or use the agent's own scheduler (Claude Code routines, Codex automations, Claude or ChatGPT scheduled tasks): https://briefkin.dev/skills/railway-deploys-and-usage#schedule
Source: https://briefkin.dev/skills/railway-deploys-and-usage
A Railway account or workspace token in RAILWAY_TOKEN (sent as Authorization: Bearer), and the Railway CLI logged in for the usage numbers.
The official Railway MCP server (https://mcp.railway.com) works for project lookups; deployment lists and usage come from the API and CLI.
https://mcp.railway.com, signed in with OAuth, where you choose which workspaces and projects the client can reach. It's in Claude's connector directory; in Claude Code run claude mcp add --transport http railway https://mcp.railway.com. If you use the CLI (5.44.0 or later), railway mcp serves the tools from your railway login session: claude mcp add railway -- railway mcp, codex mcp add railway -- railway mcp, or railway mcp install --agent cursor (docs). Besides the read tools it has redeploy, create-deployment and feature-flag tools that change things.railway CLI. railway status and railway logs cover most checks from a linked project folder.Authorization: Bearer, or a project token, which is scoped to one environment, in the Project-Access-Token header. The skill reads RAILWAY_API_TOKEN.Railway has no read-only tokens and the MCP server has no read-only mode, so limit reach instead: authorize only the project in the report, or use a project token for one environment (project tokens work with the API, not with the MCP server).
As of October 2026 the Railway CLI's railway usage command documents the billing period, usage, current bill and estimated bill, with --json for scripts. The GraphQL API has usage data too, but its cost fields are not documented, so the skill uses the command whose numbers match the billing page.
Not at this cadence. Railway allows 100 API requests an hour on the Free plan and more on paid plans. A daily run with a few services makes a few dozen calls; with many services, query only production and keep first small.
No. The skill runs with your own agent and gives you the report in the chat. With a Briefkin token set, each run also posts it to your board as a report card, so you can glance at it instead of asking again.
Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, OpenCode, Windsurf and Amp all read SKILL.md files. The install command puts it in ~/.claude/skills and ~/.agents/skills, where they look. ChatGPT, the Claude app and Grok take the prompt instead. Pick your agent under "Install and run it" and the commands change to match.
Yes. Switch the data source to "Your browser" and the steps change to the Railway pages themselves: the agent opens railway.com/dashboard in a browser you are signed in to and reads the numbers off the page. Claude Code, Codex, Cursor, Claude app and ChatGPT can drive a browser out of the box; Gemini CLI, Copilot CLI and OpenCode need a Playwright or Chrome DevTools MCP server first. It is slower than the API and needs you signed in, so it suits a report you run by hand or from a scheduler on your own computer.
Skills are free to use with any agent. Briefkin is where their results land: one board for every report, number and question your agents send, with a ping when something needs you.
Free during the open beta. No card.