# Transfer Quotas

**Last Updated:** April 28, 2026

## Overview

Stratofusion enforces quotas at two layers so usage can be blocked before expensive operations start and surfaced back to users with actionable feedback.

- Google Drive: 750 GB daily upload limit is enforced.
- OneDrive, Dropbox, Box, and pCloud: tracked for visibility and troubleshooting only.
- Subscription tiers enforce shared daily and monthly data transfer allowances, daily search limits, max file size, and files-per-batch limits.
- User-facing billing now treats uploads, downloads, copy, move, backup, and sync as one shared data transfer bucket.
- Cross-provider transfers consume the shared user-facing data transfer bucket once, while provider diagnostics still track source-download and destination-upload sides separately.
- Quota failures are surfaced in-context through transfer dialogs, upload toasts, download errors, and structured logs.

## Dual-Layer Quota System

Stratofusion now enforces limits at two layers:

### 1. Subscription Limits (User-Facing)

- Scope: shared daily and monthly data transfer allowance plus daily search allowance based on subscription tier.
- Reset: daily windows at `00:00 UTC`, monthly windows on the first day of each month at `00:00 UTC`.
- Visibility: `Settings -> Billing`.
- Enforcement: blocks uploads, transfers, downloads, and search requests when the active allowance is exhausted, and blocks oversized files or batches that exceed the active plan cap.

Current tiers:

- Free: `1 GB/day`, `10 GB/month`.
- Pro: `50 GB/day`, `200 GB/month`.
- Unlimited: `500 GB/day`, `15 TB/month`.

Current daily search tiers:

- Free: `10/day`.
- Pro: `200/day`.
- Unlimited: no daily cap.

Current per-operation plan tiers:

- Free: `100 MB` max file size, `100` files per batch.
- Pro: `2 GB` max file size, `1,000` files per batch.
- Unlimited: `10 GB` max file size, `10,000` files per batch.

Billing copy presents Free as `2 storage services (more coming)`, Pro as `5 storage services (more coming)`, and Unlimited as `All storage services (more coming)`, but provider APIs can still impose stricter request, file-size, or batch-size limits for specific operations.

### 2. Provider Limits (Background)

- Scope: provider/account transfer caps tracked per `(provider, account, user)`.
- Reset: provider-specific daily windows.
- Visibility: surfaced through transfer error messages and runtime quota logs.
- Enforcement: Google Drive upload quota is enforced; other providers remain tracked for visibility and diagnostics.

### Enforcement Order

1. Subscription daily/monthly quota is checked first.
2. Provider daily quota is checked second.
3. If a provider check fails, the subscription reservation is rolled back so blocked transfers do not consume plan quota.

## What Counts

### Data Transfer

- Local file uploads from the web UI.
- Browser download manifests with known file sizes, including Google proxy/Fly-backed downloads.
- Cross-provider copies and moves when the transfer size can be estimated.
- Folder copy operations when folder size can be estimated.
- Backup launches through the copy and folder-copy services.
- Sync launches when a transfer-size estimate is available.

### Search / Operations

- Search requests count against the daily search quota.
- AI search remains tier-gated separately from the daily count.

## Cross-Provider Example

Copying `Google Drive -> OneDrive` for `100 GB` counts as:

- Subscription data transfer: `100 GB`.
- Google Drive download: `100 GB`.
- OneDrive upload: `100 GB`.

If the Google Drive source cannot serve the transfer because of a provider-side limit in the future, or the destination Google Drive account has no upload quota remaining, Stratofusion blocks the operation before launch.

## Reset Windows

- Google Drive: app-local reset at midnight `America/Los_Angeles`.
- OneDrive, Dropbox, Box, pCloud: app-local reset at UTC midnight.

Google's official wording is still based on waiting 24 hours after the cap is hit. Stratofusion uses a predictable daily window in the dashboard for operational clarity.

## API

- `GET /api/transfer-quotas`.
  - Returns account-scoped upload and download snapshots for the authenticated user.
- `GET /api/subscription/usage`.
  - Returns the authenticated user's daily/monthly data transfer usage and daily search usage for billing-oriented views. Daily transfer usage overlays currently active Fly.io rclone progress so long-running jobs remain visible after the UTC daily reset.
- `GET /api/quotas/status`.
  - Returns the authenticated user's current plan tier plus data transfer, search, and AI-search quota status. The daily transfer window uses the same active-transfer overlay as subscription usage.
- `GET /api/transfer-quotas`.
  - Returns account-scoped provider quota snapshots derived from Postgres history.
- `trackProviderUploadQuota(...)`.
  - Validates and records incoming provider upload bytes.
- `trackProviderDownloadQuota(...)`.
  - Records outgoing provider download bytes.
- `trackProviderCrossTransferQuota(...)`.
  - Atomically checks source-download and destination-upload windows together in Postgres history.
- `consumeQuota(...)`.
  - Reserves daily/monthly data transfer usage or daily search usage.

## In-Context Feedback

- `Settings -> Billing` shows a `Plan Usage` card with daily/monthly data transfer usage, daily search usage, and live connected-service counts against the tier limits.
- The main header can show a warning badge once data transfer or daily search usage reaches `80%`.
- Upload failures, copy/move launch failures, search failures, and download manifest failures preserve quota messages from the API layer.
- File-size and files-per-batch plan failures are surfaced through the same in-context upgrade flows as quota failures.
- Subscription-limit errors surface daily or monthly transfer-limit copy. Upgradeable plans show an `Upgrade Plan` call to action that links to `/user/billing`; Unlimited users instead see `Schedule retry` and `Contact support` actions because there is no higher self-serve tier. Retry actions are disabled while the retry request and jobs refresh are pending so rapid double-clicks cannot enqueue duplicate retry jobs.
- Scheduled sync jobs that hit a transfer quota during launch or reconciliation are automatically paused until the parsed reset time. Two-way syncs are also marked for `--resync` on retry because the prior bisync attempt may have stopped before it could persist a clean baseline.
- Structured runtime logs emit `[QUOTA-CHECK]`, `[QUOTA-EXCEEDED]`, and `[PROVIDER-QUOTA-EXCEEDED]` entries for support and debugging.

## Error Handling

Quota failures are returned as `CloudStorageErrorCode.QUOTA_EXCEEDED`.

Example:

```text
Daily upload quota exceeded for google. Remaining: 0 bytes. Resets at: 2026-01-15T08:00:00.000Z
```

```text
Monthly transfer limit exceeded for free plan. Used: 10 GB / 10 GB. Resets at: 2026-02-01T00:00:00.000Z.
```

```text
Monthly data transfer quota exceeded. Used: 10 GB / 10 GB. Resets at: 2026-02-01T00:00:00.000Z.
```

- Quota state is persisted in PostgreSQL and shared across application instances. Local development uses local PostgreSQL; production uses Compose PostgreSQL.
- Daily data transfer counters and daily search counters reset lazily when the stored UTC date no longer matches today.
- Daily transfer displays are read models: after a UTC reset, they include bytes from still-running backup/sync rclone operations using active operation snapshots, with operation-event history used as the baseline when available.
- Monthly quota resets happen by reading or creating the current UTC month record.
- Daily search resets happen lazily when the stored `searchDate` no longer matches the current UTC date.
- Folder, backup, and sync quota enforcement depends on size estimation. If total bytes cannot be resolved, usage is not blocked pre-flight.
- Box and pCloud are tracked, but not every route in the current proof of concept exposes enough byte metadata to record every operation yet.

## Related Docs

- [Provider API Limits](PROVIDER_API_LIMITS.md).
- [Quota Enforcement](QUOTA_ENFORCEMENT.md).
