SapixDBSapixDB/Docs
Home
Community · Operations

Capacity Forecasting

One endpoint tells you how long every agent has before hitting the 1 billion record threshold — based on current write velocity, not guesswork.

Safe
≥ 180 days to threshold
Warning
< 180 days to threshold
Urgent
< 90 days to threshold

API

Get forecast

No query parameters. Returns a fresh forecast for every registered agent.

GET /v1/capacity/forecast
GET /v1/capacity/forecast
Authorization: Bearer <key>
response
{
  "threshold": 1000000000,
  "forecasts": [
    {
      "agent_id": "events",
      "record_count": 990000000,
      "daily_rate": 800000.0,
      "days_to_threshold": 12.5,
      "urgent": true,
      "warning": true
    },
    {
      "agent_id": "orders",
      "record_count": 4200000,
      "daily_rate": 47000.5,
      "days_to_threshold": 21168.9,
      "urgent": false,
      "warning": false
    },
    {
      "agent_id": "audit_log",
      "record_count": 102000,
      "daily_rate": 0.0,
      "days_to_threshold": null,
      "urgent": false,
      "warning": false
    }
  ],
  "generated_at_ms": 1754478000000
}

Response fields

FieldTypeDescription
thresholdnumberHard record cap — always 1,000,000,000
forecastsarrayOne entry per registered agent, sorted soonest-first
generated_at_msnumberUnix millisecond timestamp of when the forecast was computed
agent_idstringAgent namespace
record_countnumberCurrent total records in the agent's strand
daily_ratenumberEstimated records written per day (last-100-records window)
days_to_thresholdnumber | nullProjected days until threshold; null if daily_rate is 0
urgentbooleantrue when days_to_threshold < 90
warningbooleantrue when days_to_threshold < 180

How it works

For each registered agent, SapixDB samples the last 100 records by timestamp and measures the elapsed time between the oldest and newest of those records. It then extrapolates a daily write rate and projects how long until record_count reaches 1 billion.

// sample window
daily_rate = (sample_size − 1) / elapsed_days
days_to_threshold = (1_000_000_000 − record_count) / daily_rate

The window is intentionally short (last 100 records) so the rate reflects current write velocity. An agent that was heavily written in the past but is now idle will show a low rate and a large days_to_threshold.

Sort orderAgents with the smallest days_to_threshold appear first. Agents with null (zero write rate) sort last, then by descending record_count.

Monitoring recommendations

Poll daily from your observability stack
Call GET /v1/capacity/forecast once per day from a cron job or monitoring agent. Alert immediately on any urgent: true entry.
Act before urgent — plan at warning
A warning (< 180 days) gives you time to archive old data, increase instance size, or add a retention policy. Urgent (< 90 days) requires immediate action.
SapixDB does not auto-purge
There is no automatic data eviction at the threshold. Plan capacity proactively using the Policy Engine's retention rules.
Check for unregistered agents
Agents that exist on disk but were not loaded at startup will not appear in the forecast. Run POST /v1/admin/repair-registry after deploys to ensure full coverage.

Example: polling alert script

TypeScript
async function checkCapacity(sapixUrl: string, apiKey: string) {
  const res = await fetch(`${sapixUrl}/v1/capacity/forecast`, {
    headers: { Authorization: `Bearer ${apiKey}` },
  });

  if (!res.ok) throw new Error(`capacity forecast failed: ${res.status}`);

  const { forecasts } = await res.json() as {
    threshold: number;
    forecasts: Array<{
      agent_id: string;
      record_count: number;
      daily_rate: number;
      days_to_threshold: number | null;
      urgent: boolean;
      warning: boolean;
    }>;
  };

  for (const f of forecasts) {
    if (f.urgent) {
      await sendAlert("URGENT", `${f.agent_id} fills in ${f.days_to_threshold?.toFixed(0)} days (${f.record_count.toLocaleString()} records)`);
    } else if (f.warning) {
      await sendAlert("WARNING", `${f.agent_id} fills in ${f.days_to_threshold?.toFixed(0)} days`);
    }
  }
}

Limitations

LimitationDetail
Sample size is fixed at 100Bursty write patterns may cause the rate to be unrepresentative if recent activity is atypical.
Linear extrapolation onlySeasonal or accelerating growth is not modeled. Use this as a lower-bound estimate, not a precise projection.
No cachingEach call recomputes all forecasts. For large installations with many agents, call infrequently (once per hour or less).
Requires agent in registryAgents on disk but not in the registry are excluded. Run repair-registry after migrating or adding instances.
← Policy EngineUser Manual →