Skip to content

Sync limits from GitHub

Say you want your limits in your GitHub repository, next to the code that checks them. A change to a limit then goes through a pull request like any other change, and a GitHub Actions workflow syncs it to Limitry when it reaches main.

Put a limitry.json at the root of your repository, listing your limits by name. limitry.json has every field each limit takes.

{
"limits": [
{
"name": "AI budget",
"subjectKind": "user",
"action": "ai-call",
"amount": 200,
"unit": "cents",
"window": "month",
"failMode": "closed"
},
{
"name": "API burst",
"subjectKind": "apikey",
"action": "api-request",
"amount": 60,
"window": "minute",
"rolling": true
},
{
"name": "Exports at once",
"subjectKind": "workspace",
"action": "export",
"amount": 3,
"window": "concurrent"
}
]
}

Install the CLI and give it a test key with Limits set to View and change (under Custom; limits:read and limits:write). Then ask what a sync would change:

Terminal window
npm install -g @limitry/cli
export LIMITRY_TOKEN="lim_test_…"
limitry sync --dry-run
Would create: AI budget
Would create: API burst
Would create: Exports at once
Dry run: nothing was changed.

limitry sync reads ./limitry.json; pass another path to read another file. Without --dry-run it makes the changes:

Terminal window
limitry sync
Created: AI budget
Created: API burst
Created: Exports at once

Run it again and nothing changes:

No changes: 3 limits already match.

A key acts in its own environment, so a test key syncs your test limits and a live key your live ones. Limitry checks the whole file before it changes anything. If one entry is wrong, such as a name used twice, nothing changes and the error says which entry to fix. Add --json for the API’s answer as JSON.

In your repository’s settings, under Secrets and variables → Actions, add a secret named LIMITRY_API_KEY: a live key with Limits set to View and change. This workflow shows the plan on pull requests that change limitry.json, and syncs when the change reaches main:

.github/workflows/limitry.yml
name: Limitry limits
on:
pull_request:
paths: [limitry.json]
push:
branches: [main]
paths: [limitry.json]
concurrency: limitry-limits
jobs:
limits:
runs-on: ubuntu-latest
env:
LIMITRY_TOKEN: ${{ secrets.LIMITRY_API_KEY }}
steps:
- uses: actions/checkout@v7
# GitHub's runners come with Node.js and npm.
- run: npm install -g @limitry/cli
- name: Plan
if: github.event_name == 'pull_request'
run: |
{
echo "### Limitry: what merging this changes"
echo '```'
limitry sync --dry-run
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
- name: Sync
if: github.event_name == 'push'
run: limitry sync

The plan appears on the run’s summary page, so reviewers see which limits a pull request changes, field by field. If the file has a mistake, the step fails and the pull request shows a failed check.

To keep test in step too, add a second secret with a test key and run the same steps with it, for example on pushes to a staging branch.

Once a sync runs on every merge, the file decides: a limit changed in the app is set back to what the file says on the next sync. To archive the limits the file doesn’t name, and to sync from your own code instead, see limitry.json.