Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
5027814
Document the remote cache request limits and the 100 MiB artifact cap
tolgaergin Oct 11, 2026
1864bbc
Refresh remote cache documentation dates
tolgaergin Oct 11, 2026
f88519f
Document every remote cache request limit and how LPM CLI waits them out
tolgaergin Oct 11, 2026
2879440
Refresh remote cache documentation dates
tolgaergin Oct 11, 2026
605466d
List the remote cache request limits with the plans
tolgaergin Oct 11, 2026
8f61a6d
Refresh plan documentation dates
tolgaergin Oct 11, 2026
4e615a5
Say which requests and uploads count, and that LPM CLI retries a brie…
tolgaergin Oct 11, 2026
ff249c6
Refresh remote cache documentation dates
tolgaergin Oct 11, 2026
d0dce62
Say which requests and refused uploads count, the 16-upload cap, and …
tolgaergin Oct 11, 2026
f47ac26
Refresh remote cache documentation dates
tolgaergin Oct 11, 2026
59a8996
Document downloads in flight, the transfer floor, and the busy notice
tolgaergin Oct 11, 2026
df24812
Refresh remote cache documentation dates
tolgaergin Oct 11, 2026
1a636b6
Document transfer places, the two-minute cap, short upload leases, an…
tolgaergin Oct 11, 2026
4d284a8
Refresh remote cache documentation dates
tolgaergin Oct 11, 2026
db83f5e
Set the remote cache request limits, and describe out-of-scope reques…
tolgaergin Oct 11, 2026
81fbe32
Refresh remote cache documentation dates
tolgaergin Oct 11, 2026
f31c8fb
Label plan sizes in binary units
tolgaergin Oct 11, 2026
e889f0d
Refresh plan documentation dates
tolgaergin Oct 11, 2026
852ab07
docs(remote-cache): describe the refused-request limit and token gates
tolgaergin Oct 11, 2026
201a7d9
chore: update content dates
tolgaergin Oct 11, 2026
17a7f69
docs(remote-cache): say which accounts a full server keeps places for
tolgaergin Oct 11, 2026
fb921e8
chore: update content dates
tolgaergin Oct 11, 2026
121da76
docs(remote-cache): refused-request limits per token and account, rea…
tolgaergin Oct 11, 2026
4b2418b
chore: update content dates
tolgaergin Oct 11, 2026
bba8d62
docs(remote-cache): login credentials read and write the personal cache
tolgaergin Oct 11, 2026
c671ea1
chore: update content dates
tolgaergin Oct 11, 2026
32f5824
docs(remote-cache): refused requests are answered as themselves; tigh…
tolgaergin Oct 11, 2026
05180c1
chore: update content dates
tolgaergin Oct 11, 2026
273f141
docs(remote-cache): an account's own team stays answered; what counts…
tolgaergin Oct 11, 2026
c1dfc88
chore: update content dates
tolgaergin Oct 11, 2026
eff4f70
docs(remote-cache): downloads from storage, lower daily limits, and s…
tolgaergin Oct 12, 2026
48d2c4b
chore: update content dates
tolgaergin Oct 12, 2026
52a05eb
docs(remote-cache): held uploads, cut-offs, mixed selectors and sessi…
tolgaergin Oct 12, 2026
9771e79
chore: update content dates
tolgaergin Oct 12, 2026
6a116c2
docs(remote-cache): the download host, hash-less artifacts, held uplo…
tolgaergin Oct 12, 2026
ef970da
chore: update content dates
tolgaergin Oct 12, 2026
97b3aac
docs(remote-cache): a lapsed organization's tokens count toward an ad…
tolgaergin Oct 12, 2026
bf0fe00
chore: update content dates
tolgaergin Oct 12, 2026
fe4d875
docs(plans): say storage past the included size is billed per GiB a m…
tolgaergin Oct 12, 2026
e4f357e
chore: update content dates
tolgaergin Oct 12, 2026
cd9ac2c
docs(remote-cache): the address gate is per server, unusable status c…
tolgaergin Oct 12, 2026
08955cf
chore: update content dates
tolgaergin Oct 12, 2026
a96022b
docs(remote-cache): the brief recheck answer, unusable caches, and ro…
tolgaergin Oct 12, 2026
c9fcdf6
chore: update content dates
tolgaergin Oct 12, 2026
7891f9a
docs(remote-cache): the brief 429 while a lapsed bill is checked again
tolgaergin Oct 12, 2026
5ec3ac4
chore: update content dates
tolgaergin Oct 12, 2026
d0cc784
docs(remote-cache): reads and uploads to a cache that can't serve the…
tolgaergin Oct 12, 2026
d9378a3
chore: update content dates
tolgaergin Oct 12, 2026
d4d6384
docs(setup): the per-user token creation limit lpm setup local shares…
tolgaergin Oct 12, 2026
63f5d87
chore: update content dates
tolgaergin Oct 12, 2026
79a1aee
docs: Hobby's storage limit leaves out exempt packages, and Pro's ove…
tolgaergin Oct 13, 2026
da1ed49
chore: update content dates
tolgaergin Oct 13, 2026
9bb47cd
docs: the brief 429 while new tokens are checked, the shared revocati…
tolgaergin Oct 13, 2026
94be5e5
chore: update content dates
tolgaergin Oct 13, 2026
ca1319f
docs: revocations always go through, the remote cache's wider gates a…
tolgaergin Oct 13, 2026
2f1717d
chore: update content dates
tolgaergin Oct 13, 2026
d3dbf4e
docs(cache): split request limits into the download host, revoked tok…
tolgaergin Oct 13, 2026
8d85203
chore: update content dates
tolgaergin Oct 13, 2026
72b921e
docs: rewrite the remote cache limits, token and login passages in pl…
tolgaergin Oct 13, 2026
fd8136f
chore: update content dates
tolgaergin Oct 13, 2026
4a3e859
Merge remote-tracking branch 'origin/main' into docs-389-local
tolgaergin Oct 14, 2026
48e48d4
chore: update content dates
tolgaergin Oct 14, 2026
8d1f400
Merge remote-tracking branch 'origin/main' into docs-389-local
tolgaergin Oct 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions content/docs/infra/login.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ If the browser does not open, copy the displayed URL into a browser. JSON mode s

LPM CLI verifies and saves the returned session. Future protected commands can refresh its access token automatically.

An account keeps up to 20 active `lpm login` sessions, one for each sign-in. If you sign in when the account has 20, LPM.dev ends the session that was used least recently, as `lpm logout --revoke` does.

If the LPM.dev Registry cannot complete the sign-in at once, `lpm login` tries again for up to 30 seconds. If the Registry still cannot complete it, run `lpm login` again.

A valid saved refresh-backed session skips browser authentication. An access token without a refresh credential does not satisfy this check.

To switch accounts, clear the saved session first:
Expand Down
80 changes: 77 additions & 3 deletions content/docs/infra/remote-cache.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export NODE_ENV=production

The token permits cache reads and writes. Supply it through the shell or CI environment, outside committed project configuration.

For the configured Registry origin, LPM CLI can also use `LPM_TOKEN` or credentials from [`lpm login`](/docs/infra/login). Those credentials must permit cache access.
For the configured Registry origin, LPM CLI can also use `LPM_TOKEN`, if that token permits cache access. It can also use your [`lpm login`](/docs/infra/login) credentials. Login credentials read and write your personal cache. The cache of an organization needs one of its tokens.

### 3. Run the task

Expand Down Expand Up @@ -291,7 +291,7 @@ The LPM.dev Registry applies these included storage limits:
| Organization | 25 GiB per seat |
| Enterprise | No fixed quota in the Enterprise plan |

The LPM.dev Registry accepts archives up to 100 MiB (104,857,600 bytes), and refuses an empty upload. With a custom cache endpoint, LPM CLI uploads and restores archives up to 500 MiB (524,288,000 bytes).
The LPM.dev Registry accepts archives up to 100 MiB (104,857,600 bytes), and refuses an empty upload. LPM CLI does not upload a larger archive to it, and builds the task as usual. With a [custom cache endpoint](#custom-cache-endpoints), LPM CLI uploads and restores archives up to 500 MiB (524,288,000 bytes).

Restore also applies these limits to the archive contents:

Expand All @@ -307,6 +307,65 @@ Default retention is 14 days, and a download refreshes the retention period. An

To fit new uploads within the storage limit, the Registry can evict the least recently accessed artifacts. Cache storage is temporary.

### Request limits

The LPM.dev Registry limits the remote cache requests of each Pro account, and of each organization seat, Enterprise included:

| Limit | Per minute | Per day |
| --- | --- | --- |
| Requests of any kind | 3,000 | 100,000 |
| Uploads | 300 | 4,000 |
| Uploaded data | - | 12 GiB |
| Cache hits | 2,000 | 50,000 |
| Downloaded data | - | 40 GiB |
| Of which downloaded through the Registry | - | 5 GiB |

- Each request whose token can use the cache of the account counts against its request limits. This includes lookups that miss, and status checks. A query for several artifacts counts one request for each different artifact. If a query asks for more than the window has left, the Registry refuses it, and it counts as one request.
- Uploads also count against the upload limits, and cache hits count against the cache-hit limits. A cache hit is a download, or an existence check, that finds the artifact. An upload that the Registry refuses before it receives the upload does not count as an upload. An upload of content that the cache already holds does not count either. The Registry knows such content from the checksum that LPM CLI sends. The Registry then makes sure that storage still holds the content, and this counts as a cache hit. If storage lost the content, the Registry stores it again. When the account has no cache hits left, the Registry stores such an upload, and counts it, as any other upload.
- The daily limits of an organization increase with each seat. Its per-minute limits increase with up to ten seats. Its uploads per minute increase with up to five seats, to 1,500 uploads a minute.
- Across the Registry, an account can have 4 uploads in progress for each seat, at least 8 and at most 16. On each Registry server, it can have 8 uploads and downloads together for each seat, at least 32 and at most 64. When a Registry server is half full, it shares its places equally among the accounts that use it. It also keeps a few places for accounts that use few. When every place is taken, the server answers that it is busy until a place becomes free.
- The Registry stops an upload, or a download through the Registry, that takes longer than 10 seconds plus one second for each 128 KiB. It also stops one that takes longer than 2 minutes. LPM CLI gives each remote cache request 30 seconds in any case. After an interrupted download, the task runs as on a miss, and the hit and its bytes still count.
- If an upload stops before it is complete, for example because its connection drops, the upload holds its artifact for 5 minutes or less.
- An account whose plan has no remote cache gets 30 requests a minute and 1,000 a day. The Registry counts these separately from its requests before its plan changed. An organization whose billing lapsed gets HTTP 402 for each request except status checks, which report `paused`. While the Registry finds out again whether the lapse continues, other requests get a short HTTP 429 with `Retry-After: 1`.
- When the Registry refuses a request, its answer gives the reason. For example, an upload with a read-only token, or a request for the cache of another account, gets HTTP 403. A request that is not valid gets HTTP 400. A refused request counts against its own limits, not the request limits above, for any number of seats. For its token, these limits are 30 a minute and 1,000 a day. For the account of the token, they are 120 a minute and 5,000 a day. When one of these limits is spent, the Registry still answers each request as before. A token reaches only the cache of its own account. If `slug` or `teamId` names any other account, the request gets HTTP 403, also if that account does not exist. If only one of `slug` and `teamId` names the account of the token, the request gets HTTP 400.
- If a token can only read the cache, run Turborepo with `--remote-cache-read-only`. Without this flag, Turborepo turns off its remote cache for the run after its first refused upload.
- After its first refused upload, LPM CLI does not upload for the rest of the run. After a refused lookup, LPM CLI does not use the remote cache for the rest of the run. The same occurs when the billing of the organization lapses. If the cache has no room for an upload, LPM CLI skips only that upload. The cache makes room, so a later upload can fit.
- If the small body of a lookup or event report does not arrive in 30 seconds, the request gets HTTP 408.

Each window starts with the first request it counts, not at a set time of day.

A request past a limit gets HTTP 429 with a `Retry-After` header. The header gives the seconds until the limit resets. Until then, LPM CLI skips that kind of request, and builds tasks as it does without a remote cache. A lookup limit also pauses uploads, because a task that skipped its lookup can upload an artifact that the cache already holds. The CLI warns once a run for each kind of limit.

A wait of 5 seconds or less usually means one of two things: the Registry is busy for a short time, or the window of a minute is about to reset. LPM CLI sends such a lookup or upload one more time after the wait. It adds up to half the wait, so that refused requests do not all return at the same time. It does not send the request again if that kind of request was paused in the meantime. If LPM CLI still skips some requests, it shows a note once a run for each kind: `remote cache is busy; skipping some uploads for a moment` (or lookups). It keeps the limit warning for a longer limit.

Turborepo receives a per-minute limit as HTTP 429, and a daily limit as HTTP 403 with the code `remote_caching_over_limit`.

#### Download host

LPM CLI and Turborepo download a cache hit from the download host of the cache, `cache-dl.lpm.dev`. They use a link that the Registry gives in its answer. The link works for one minute.

> **CAUTION:** Allow `cache-dl.lpm.dev` and `lpm.dev` in your CI firewall. If you do not, every cache hit fails to download, and the task runs again.

- The host refuses a request with HTTP 403 if the request has an `Origin`, `Forwarded`, `X-Forwarded-Host`, or similar header. If a TLS-inspecting proxy adds such a header, every cache hit becomes a miss.
- LPM CLI reports a failed download without its link, because the link works as a credential for that minute.
- Turborepo downloads a signed artifact through the Registry instead. Other clients and older LPM CLI releases do this too. These downloads count against the 5 GiB a day of downloads through the Registry.
- Some clients, Turborepo among them, upload an artifact without a content hash. LPM CLI treats such an artifact as a miss, and replaces it with its own.

#### Revoked tokens

- The Registry examines a token at most once a minute on each server. As a result, a revoked token can continue to work for up to a minute.
- When LPM CLI refreshes an `lpm login` session, the previous access token of the session becomes invalid in five minutes or less. Any older token becomes invalid at once, or in that minute on a server that examined it.

#### Tokens that fail

- A token that is not valid gets the same HTTP 401 for one minute.
- Each Registry server counts, on its own, the new tokens from each address that are not valid or whose requests it refuses. A request counts as refused if it is over the request limits of its account. It also counts if the answer says that the billing of the organization lapsed. It counts too if it goes to a cache that cannot serve it, status checks included. A new token counts too if the server tells it to wait while the server examines the limits of its account.
- After 60 such tokens in a minute from one IPv4 address or IPv6 /64, the server answers that address with HTTP 429. This continues for the rest of the minute. The limit is 240 from one IPv6 /48, and 960 from one /32. After 1,200 from all addresses together, the server answers every address with HTTP 429.
- The server still examines one token every 2 seconds from an address that it holds. While it holds every address, it examines one token every 2 seconds in total.
- The server lets through a token whose requests it served in the last day. It also lets through a token that another server served in the last 23 hours, while the Registry can read the pass of that token. The pass ends when the token becomes invalid, or when the server refuses one of its requests as above. A status check counts as served only if the cache of its account serves reads: `enabled` or `over_limit`.
- New tokens that the server still examines also count toward the 60, until the server answers their requests. While 60 are in progress from one address, a further new token gets HTTP 429 with `Retry-After: 1` ("Too many new tokens from this address are being checked"). The server still examines one token every 2 seconds.
- Tokens that LPM.dev creates have a mark that only LPM.dev can make. The server counts them separately from other tokens: 60 a minute from one IPv4 address or IPv6 /48. A flood of made-up tokens can hold up every address, but it does not hold up these tokens. Tokens that LPM.dev created before it started to mark them count with the others.

### Inspect usage

```bash
Expand Down Expand Up @@ -391,9 +450,24 @@ Make sure that the task declares `cache: true` and `outputs`. Inspect warnings f

If read-only mode is enabled, uploads are skipped by design. A local hit also avoids task execution and does not upload an existing local result.

### A request limit is reached

LPM CLI shows the warning `Remote cache limit reached`, with the limit and how long it skips remote requests. Tasks still run, and the CLI uses the remote cache again when the limit resets. See [Request limits](#request-limits).

Concurrent runs, for example parallel CI jobs, share the limits of the account. To use fewer requests, give [read-only access](#read-only-consumers) to jobs that only consume results, so that they do not upload. Also cache only tasks that take longer to run than to download. Each cached task costs a lookup on every run, and an upload on every miss.

The Registry also answers with HTTP 429 and `Retry-After: 1` in these cases:

- The account has as many uploads or downloads in progress as it can have.
- Another upload holds the cache of the account.
- The Registry finds out again whether the limits of the account still apply.
- From one address, as many new tokens are in progress as the server lets through. See [Tokens that fail](#tokens-that-fail).

When a Registry server is busy, it answers with HTTP 429 and `Retry-After: 2`. LPM CLI sends a refused lookup or upload one more time after the wait, plus up to half the wait. If it still skips some requests, it shows `remote cache is busy; skipping some uploads for a moment` (or lookups). An upload of an artifact that another upload still stores gets HTTP 409, and LPM CLI leaves the artifact to that upload.

### The server rejects access

Make sure that the token has `cache:read`, `cache:write`, or `admin` permission. Uploads require `cache:write` or `admin`.
Make sure that the token has `cache:read`, `cache:write`, or `admin` permission. Uploads require `cache:write` or `admin`. Credentials from `lpm login` read and write your personal cache only.

For an organization, use a token scoped to the selected organization. Inspect the account's plan and billing state with [`lpm cache status`](/docs/packages/cache#status).

Expand Down
9 changes: 9 additions & 0 deletions content/docs/infra/setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,15 @@ CAUTION: The `.npmrc` file contains a token. Keep the file outside version contr

Run `lpm setup local` again before the token expires. The command writes a replacement and retires the previous project token.

Token limits:

- An account holds up to 100 active tokens that it created, project tokens included. At this limit, `lpm setup local` fails for a new project, or for a project whose token expired, until you revoke a token in [Registry token settings](https://lpm.dev/dashboard/settings/tokens). At the limit, you can still replace the token of a project if that token is active.
- LPM.dev deletes expired and revoked tokens 30 days later.
- A user creates 10 tokens a minute or fewer, `lpm setup local` included. Token creation on the dashboard shares this limit. Above it, the command fails with HTTP 429, and it works again when the minute ends.
- From one IPv4 address or IPv6 /64, `lpm setup local` creates, replaces, and revokes project tokens 100 times a minute or fewer for each action. Above that, it fails with HTTP 429 before it changes a token.

LPM.dev does not limit how often you revoke tokens in [Registry token settings](https://lpm.dev/dashboard/settings/tokens). As a result, no person who holds a token can stop you from revoking it. A revoked token can continue to work for up to a minute, until the caches of the Registry drop it. For each user, the first 20 revocations a minute, across the dashboard, the API, and `lpm setup local`, also remove the token from the caches at once.

The command uses the current directory. It does not configure every workspace member automatically.

JSON output reports the paths, scope, and expiry. It does not include the token.
Expand Down
2 changes: 1 addition & 1 deletion content/docs/infra/token-rotate.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ After a successful rotation:
- LPM CLI stores the replacement in local secure storage.
- The replacement token does not appear in terminal or JSON output.

The LPM.dev Registry can process five rotation requests per minute for one token record.
The LPM.dev Registry can process five rotation requests per minute for one token record. Across the tokens of one account, personal or organization, it can process 20 per minute.

In rare cases, an edge cache can accept the old value for up to 60 seconds after rotation.

Expand Down
6 changes: 4 additions & 2 deletions content/docs/lpm-dev-and-pro.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@ All LPM.dev Registry packages start private. Pool and Marketplace are explicit p
| --- | --- | --- |
| Price | $0 | $8/mo |
| Private packages | 2 | Unlimited |
| Package storage | 100 MB | 5 GB |
| Package storage | 100 MiB | 5 GiB |
| Package storage beyond that | Publishing stops. The tarballs of packages whose sales pass $50 do not count. | $0.20/GiB a month, rounded up to a whole GiB. Publishing past it waits while billing is not active. |
| Marketplace platform fee | 15% | 10% |
| Firewall for public npm packages | - | Included |
| Local env storage | Included | Included |
| Cloud env sync | - | Included |
| Platform env push and OIDC CI pulls | - | Included |
| Remote task cache | - | 25 GiB |
| Remote cache uploads and cache hits | - | 4,000 and 50,000/day |
| Remote task cache beyond 25 GiB | - | Optional overage: $0.20 per GiB kept 30 days, up to a cap you set |
| Tunnels | - | Included |
| Concurrent tunnels | - | 3 |
Expand All @@ -65,7 +67,7 @@ Pro tunnel overage is enabled by default. Turn it off from the personal tunnel d

If a Pro payment fails, Pro continues to work for nine days while Stripe tries the payment again. During this time, tunnel overage is off, so tunnels stop at the included requests. If the payment does not succeed in the nine days, the account moves to Hobby. The relay then refuses tunnels, and LPM.dev Registry releases your claimed tunnel domains. If you pay the subscription later, Pro returns, but the released domains do not. To pay, update the payment method in [billing settings](https://lpm.dev/dashboard/settings/billing).

Organizations use separate org billing at $8 per seat. Each seat includes unlimited private packages, 5 GB package storage, and 25 GiB remote cache. The organization shares a limit of 3 concurrent tunnels and 3 claimed tunnel domains across all members and base domains. Additional seats do not increase these two limits. Members connect organization tunnels through the claimed domains of the organization, with or without a personal Pro plan.
Organizations use separate org billing at $8 per seat. Each seat includes unlimited private packages, 5 GiB package storage, and 25 GiB remote cache with 4,000 uploads and 50,000 cache hits a day. Package storage past the organization's total is billed at $0.20/GiB a month, rounded up to a whole GiB. See [Remote cache](/docs/infra/remote-cache#request-limits) for every request limit. The organization shares a limit of 3 concurrent tunnels and 3 claimed tunnel domains across all members and base domains. Additional seats do not increase these two limits. Members connect organization tunnels through the claimed domains of the organization, with or without a personal Pro plan.

Each billed Stripe seat adds 100,000 included tunnel requests and 20,000 requests/minute to the organization account. The seat count is fixed when the tunnel usage period opens and applies for the rest of that period. Organization overage uses the same proportional $1/100,000 rate and default-on toggle.

Expand Down
8 changes: 4 additions & 4 deletions lib/generated/content-dates.json
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@
},
"infra/login.mdx": {
"published": "2026-06-16T23:33:51+01:00",
"modified": "2026-09-20T00:17:59+01:00"
"modified": "2026-10-13T21:57:11+01:00"
},
"infra/policy.mdx": {
"published": "2026-06-28T15:54:59+01:00",
Expand Down Expand Up @@ -229,15 +229,15 @@
},
"infra/setup.mdx": {
"published": "2026-06-16T23:33:51+01:00",
"modified": "2026-09-20T00:17:59+01:00"
"modified": "2026-10-13T21:57:11+01:00"
},
"infra/store.mdx": {
"published": "2026-05-01T09:47:04+01:00",
"modified": "2026-09-20T03:12:34+01:00"
},
"infra/token-rotate.mdx": {
"published": "2026-06-16T23:33:51+01:00",
"modified": "2026-09-20T00:18:00+01:00"
"modified": "2026-10-13T21:57:11+01:00"
},
"infra/tunnel.mdx": {
"published": "2026-05-01T09:47:04+01:00",
Expand All @@ -253,7 +253,7 @@
},
"lpm-dev-and-pro.mdx": {
"published": "2026-06-16T23:33:51+01:00",
"modified": "2026-10-13T21:51:29+01:00"
"modified": "2026-10-13T21:57:11+01:00"
},
"migrating.mdx": {
"published": "2026-05-01T09:47:04+01:00",
Expand Down