Skip to content

docs: add outpost documentation - #15867

Open
maximevast wants to merge 1 commit into
mainfrom
maxime/plr-349/docs
Open

maximevast wants to merge 1 commit into
mainfrom
maxime/plr-349/docs

Conversation

@maximevast

@maximevast maximevast commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Related Issue: #

What

Why

How

Checklist

  • This PR addresses a single concern (one bug fix, one feature, one refactor)
  • The diff is reasonably sized and easy to review
  • New functionality is covered by tests
  • Linting and type checking pass (uv run task lint && uv run task lint_types)
  • No unrelated changes or drive-by fixes are included

View guided diff Turn on auto-fix

@mintlify

mintlify Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
Polar 🟢 Ready View Preview Oct 23, 2026, 3:08 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

@vercel

vercel Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
orbit Ready Ready Preview Oct 23, 2026 3:08pm UTC
polar-test Ready Ready Preview Oct 23, 2026 3:08pm UTC

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cubic analysis

3 issues found across 2 files

Confidence score: 3/5

  • docs/features/outpost.mdx describes versioned keys and automatic migration, but the SDK uses unversioned keys and never expires the state hash. Document the actual key layout and lifetime.
  • docs/features/outpost.mdx overpromises flush() delivery: retries can end with events reported to onDropped while the flush completes. Describe it as draining events until delivered or reported dropped.
  • docs/features/outpost.mdx understates storage use because the pending hash grows with unconfirmed events. Qualify the estimate or tie it to pending event volume and confirmation lag.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="docs/features/outpost.mdx">

<violation number="1" location="docs/features/outpost.mdx:126">
P2: `flush()` does not guarantee delivery: after retries, the SDK can report a batch to `onDropped` and complete the flush. Say it drains pending events until delivered or reported dropped instead of promising they reach Polar.</violation>

<violation number="2" location="docs/features/outpost.mdx:148">
P2: The SDK uses unversioned `outpost:state`/`outpost:pending` keys and never expires the state hash, so this table and the automatic version-migration claim are inaccurate. Document the actual key layout and lifetime, or implement the stated versioning and state TTL first.</violation>

<violation number="3" location="docs/features/outpost.mdx:152">
P2: The few-kilobyte estimate ignores the pending hash, which stores an entry per unconfirmed event and grows with event volume. Qualify the estimate or size it by pending event rate and confirmation lag.</violation>
</file>

Linked issue analysis

Linked issue: PLR-349: Document Outpost for merchants and for the team

Status Acceptance criteria Notes
✅ Explain Outpost guarantees, reconciliation, and failure behavior The guide describes local reads, Polar snapshot replacement, and what happens when Redis or Polar is unreachable.
✅ Document Redis setup, token scope, and telemetry controls The guide covers Redis configuration, environment isolation, the events:write scope, telemetry, and how to disable it.
✅ Show balance reads, actor warm-up, and serverless flushing The guide shows actor and meter calls, explains warming customers, and points to flushing in serverless runtimes.
✅ Document Redis keys, TTLs, and approximate customer memory The footprint table lists keys and lifetimes, and the text estimates a few kilobytes per customer.
❌ Link the guide from both SDK pages The diff adds the Mintlify page to navigation but does not update either SDK README.
❌ Add the internal Outpost design document The diff contains only the merchant-facing guide and no document in the engineering design-documents handbook.
❌ Describe Redis hash layout and Lua script guarantees The merchant guide lists Redis keys, but the diff does not document the internal hash layout or Lua scripts.
❌ Document WebSocket messages and snapshot and seal behavior The guide mentions snapshots and a WebSocket connection, but not message types or the internal snapshot and seal cycle.
❌ Explain the internal pending model and failure modes The guide covers merchant-visible failures, but the requested internal pending model and design-level failure modes are absent.
❌ Include sequence diagrams for writes, reads, snapshots, and confirmations The diff includes one high-level sequence diagram, not the four requested design-document diagrams.

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread docs/features/outpost.mdx

| Key | Content | Lifetime |
| ------------------------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------ |
| `outpost:v1:state:<customer>:<reducer>` | One hash per customer and meter: Polar's totals, local 5-minute buckets, credits | 24 hours after the last read, write or snapshot |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The SDK uses unversioned outpost:state/outpost:pending keys and never expires the state hash, so this table and the automatic version-migration claim are inaccurate. Document the actual key layout and lifetime, or implement the stated versioning and state TTL first.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At docs/features/outpost.mdx, line 148:

<comment>The SDK uses unversioned `outpost:state`/`outpost:pending` keys and never expires the state hash, so this table and the automatic version-migration claim are inaccurate. Document the actual key layout and lifetime, or implement the stated versioning and state TTL first.</comment>

<file context>
@@ -0,0 +1,154 @@
+
+| Key                                                     | Content                                                                        | Lifetime                                   |
+| ------------------------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------ |
+| `outpost:v1:state:<customer>:<reducer>`                 | One hash per customer and meter: Polar's totals, local 5-minute buckets, credits | 24 hours after the last read, write or snapshot |
+| `outpost:v1:pending:<customer>:<reducer>:<bucket>`      | The events of a bucket Polar has not confirmed yet                              | 65 minutes after the last write            |
+| `outpost:v1:<db>:updates`                               | Pub/sub channel that carries each write to the other instances                  | No storage                                 |
</file context>

Comment thread docs/features/outpost.mdx

A read returns the customer's `consumed_units`, `credited_units` and `balance` for one meter, computed as Polar does: credits minus consumption.

In a serverless runtime, flush `Metering` before each request ends, as the [SDK guide](/integrate/sdk/typescript) explains, so your events reach Polar before the runtime freezes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: flush() does not guarantee delivery: after retries, the SDK can report a batch to onDropped and complete the flush. Say it drains pending events until delivered or reported dropped instead of promising they reach Polar.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At docs/features/outpost.mdx, line 126:

<comment>`flush()` does not guarantee delivery: after retries, the SDK can report a batch to `onDropped` and complete the flush. Say it drains pending events until delivered or reported dropped instead of promising they reach Polar.</comment>

<file context>
@@ -0,0 +1,154 @@
+
+A read returns the customer's `consumed_units`, `credited_units` and `balance` for one meter, computed as Polar does: credits minus consumption.
+
+In a serverless runtime, flush `Metering` before each request ends, as the [SDK guide](/integrate/sdk/typescript) explains, so your events reach Polar before the runtime freezes.
+
+## When something is down
</file context>
Suggested change
In a serverless runtime, flush `Metering` before each request ends, as the [SDK guide](/integrate/sdk/typescript) explains, so your events reach Polar before the runtime freezes.
In a serverless runtime, flush `Metering` before each request ends, as the [SDK guide](/integrate/sdk/typescript) explains, so pending events are delivered or reported to `onDropped` before the runtime freezes.

Comment thread docs/features/outpost.mdx
| `outpost:v1:pending:<customer>:<reducer>:<bucket>` | The events of a bucket Polar has not confirmed yet | 65 minutes after the last write |
| `outpost:v1:<db>:updates` | Pub/sub channel that carries each write to the other instances | No storage |

A customer who stops sending events disappears from Redis after a day. A hash holds a few hundred bytes per bucket, and Polar's snapshots fold buckets into one total every five minutes, so a customer costs a few kilobytes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The few-kilobyte estimate ignores the pending hash, which stores an entry per unconfirmed event and grows with event volume. Qualify the estimate or size it by pending event rate and confirmation lag.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At docs/features/outpost.mdx, line 152:

<comment>The few-kilobyte estimate ignores the pending hash, which stores an entry per unconfirmed event and grows with event volume. Qualify the estimate or size it by pending event rate and confirmation lag.</comment>

<file context>
@@ -0,0 +1,154 @@
+| `outpost:v1:pending:<customer>:<reducer>:<bucket>`      | The events of a bucket Polar has not confirmed yet                              | 65 minutes after the last write            |
+| `outpost:v1:<db>:updates`                               | Pub/sub channel that carries each write to the other instances                  | No storage                                 |
+
+A customer who stops sending events disappears from Redis after a day. A hash holds a few hundred bytes per bucket, and Polar's snapshots fold buckets into one total every five minutes, so a customer costs a few kilobytes.
+
+The `v1` in each key names the layout. A future layout takes a new version and starts from Polar's snapshot; it never reads the previous keys, which expire on their own.
</file context>
Suggested change
A customer who stops sending events disappears from Redis after a day. A hash holds a few hundred bytes per bucket, and Polar's snapshots fold buckets into one total every five minutes, so a customer costs a few kilobytes.
A customer's Redis footprint also depends on its pending event volume; size capacity using the event rate and confirmation lag.

This branch was successfully deployed

3 active deployments
staging - docs — 79694677 Deployed Oct 23, 2026 by mintlify[bot]
Preview – polar-test — 79694677 Deployed Oct 23, 2026 by vercel[bot]
Preview – orbit — 79694677 Deployed Oct 23, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant