Skip to content

Authority Doc / Public V1 Performance

The Performance Plan sets the expected scale, latency budgets, and payload limits CoachMe designs against for Public V1.

This page is the proposed Public V1 authority for the numbers implementation designs against: expected workspace sizes and client counts, media volume, per-surface API latency budgets, sync payload limits, pagination defaults, provider-quota headroom, and which screens must be designed for scale first. It states assumptions as assumptions and sets design targets, not runtime alert thresholds.

DraftAssumptionsDesign targetsDesign for 2,000Public V1

Decision status: Draft 2026-07-18 — pending review

Nothing on this page is approved yet. The scale figures below are stated assumptions for a UAE-first, single-operator Public V1, chosen so implementation has a concrete number to design against — not measured production data and not commitments. Every budget marked Proposed is a design target for review. When real traffic exists, these are revisited against it. This page sets design targets; the operational alert thresholds that page an engineer are owned by the observability-plan and must not be read off this page.

Note

This page does not own pagination mechanics, provider-quota source values, latency alert thresholds, sync protocol shape, or infrastructure sizing. api-contract-standard owns cursor pagination and envelopes; integration-register owns the authoritative provider quota numbers; observability-plan owns latency objectives and alerts; offline-sync-protocol owns sync payloads and receipts; environment-runbook owns host capacity. This page owns only the expected magnitudes and design budgets those contracts operate at.

Scope

This page owns the scale assumptions and design budgets. Adjacent authorities own the mechanisms those budgets constrain.

This Page Owns

  • Assumed workspace sizes and client-count distribution at Public V1.
  • Assumed media volume per client and per workspace.
  • Per-surface API latency budgets: coach web, coach mobile, client mobile, and sync.
  • Sync payload-size and slice budgets as design targets.
  • Recommended pagination default and maximum page sizes per list class.
  • Provider-quota headroom analysis against assumed volume.
  • The prioritized list of screens that must be designed for scale first.

This Page Does Not Own

  • Cursor pagination mechanics, the collection envelope, and per-endpoint page-size documentation, owned by api-contract-standard.
  • Authoritative provider quota, rate-limit, and pricing numbers, owned by integration-register.
  • Latency objectives, operational alert thresholds, and the p95 alert rules, owned by observability-plan.
  • Sync operation envelopes, receipts, replay, conflict handling, and cache pruning, owned by offline-sync-protocol.
  • Host, VPS, container, and database sizing and capacity posture, owned by environment-runbook.
  • The tenant fence and tenant-leading index shape that make scoped queries scale, owned by multi-tenancy.
  • Rate-limit strategy per endpoint class, owned by security-plan.
  • Load-test and performance-evidence gating, owned by test-and-release-gate.

Scale Assumptions

These are assumptions, not measurements. They give implementation a concrete target and a headroom ceiling. Each is revisited against real traffic.

DimensionTypical (design for)Headroom ceiling (must not break at)Basis
Coaches / workspaces at launchTens to low hundredsLow thousandsUAE-first, single-operator early launch. Growth is expected but not the launch design point.
Active clients per coach workspace20–1502,000A solo coach's real book is small; the heaviest screens must still hold at a power-coach ceiling without a redesign.
Concurrent active client-mobile sessions per workspaceA small fraction of clients at onceDesign list/sync paths so a busy morning across a large book does not fan out unboundedlyClients execute on their own schedule; peaks cluster (mornings, post-Ramadan-iftar windows).
Programs per workspaceTensLow thousands including archivedTemplates plus per-client assignments accumulate.
Messages per active relationshipTens per weekUnbounded history, cursor-pagedHistory grows for the life of the relationship.
Progress/log rows per active clientA few per dayYears of daily history per clientDaily logging is the core loop; timelines must page, never full-scan.

The 20-vs-2,000 rule

The typical coach has ~20–150 clients, but the design point for the heaviest screens is the 2,000-client ceiling. A screen that is comfortable at 20 and quietly O(n) at 2,000 is a launch defect, not a future optimization. The screens that must clear this bar are listed below.

Media Volume Assumptions

Media is the largest byte and processing consumer. These estimates size the media workers and storage; the security treatment of the bytes is owned by media-security, and the authoritative storage cost/quota numbers wait on the object-storage decision in the integration-register.

SourceAssumed volumeNote
Progress photosA few per client per week, a few MB each after normalizationNormalized/stripped by Sharp on ingest; derivatives add a thumbnail per photo.
Voice notesCapped-length notes, occasional per relationshipLength cap is a product decision; FFmpeg validation and rendition per note.
Form/document attachmentsOccasional per onboarding and per reviewDocuments bucket; PDF preview generation per document.
Exercise assetsShared, not per-clientfree-exercise-db thumbnails and YMove references are catalog-scoped, not multiplied per workspace.
Derived objectsOne or more per canonical objectThumbnails/posters roughly double object count; sized into worker throughput, not just storage.

The design consequence: media processing is bursty and per-client, so the media worker throughput target is set against the assumed per-workspace weekly volume at the headroom ceiling, and the coachme.upload.processing.oldest.age gauge owned by observability-plan is the runtime signal that the assumption held.

API Latency Budgets

These are design targets per surface, expressed as p95 for normal interactive JSON. They align with, and must not undercut, the observability-plan launch objective of p95 below 1 second for normal JSON API traffic (excluding health, static, synthetic, byte-transfer, and explicitly long-running routes). Budgets below are the design ceiling each surface aims under.

SurfaceInteraction classProposed p95 budgetNotes
Coach webInteractive read (client list, program library, review screens)≤ 500 ms server timeThe primary creation surface; snappy reads matter most. Excludes report/export generation.
Coach webCommand/mutation (publish, assign, review action)≤ 800 ms server timeWithin the 1 s objective; heavy publish work hands off to workers per event-and-outbox-standard.
Coach mobileReview/inbox/progress reads≤ 600 ms server timeReview and communication surface; no builder parity.
Client mobileToday view, log submit, check-in≤ 600 ms server time onlineMust also degrade to the offline queue, not spin, when the network is poor.
SyncOne sync exchange (push queued ops + pull slice)≤ 1 s server time for a bounded slicePayload-bounded below; large backlogs page across exchanges rather than one large response.
Any surfaceByte transfer, export, reportExcluded from the JSON budgetOwned by upload/download and export paths; measured separately, never counted against the interactive objective.

Note

These are server-processing budgets, not end-to-end device-perceived latency. Client mobile and coach mobile add network and render time on top; the offline-first design in offline-sync-protocol is what protects the client experience when the network, not the server, is the constraint.

Sync Payload Limits

The sync exchange must stay bounded so a large offline backlog or a large first-pull does not produce an unbounded request or response. The protocol mechanics — operation envelopes, receipts, replay, conflict handling — are owned by offline-sync-protocol; this page proposes the size budgets it should enforce.

LimitProposed design targetRationale
Operations pushed per exchangeBounded batch (proposed low hundreds)A device returning from a long offline period drains its outbox across several exchanges, not one oversized request.
Pull slice per exchangeBounded by row count and byte sizeFirst-login or post-reset pull is paged; the slice is scoped to the device's active workspace/relationship per multi-tenancy.
Single operation payloadBounded; media travels by upload-intent, not inlineBytes never ride inside a sync operation; they use the media-security signed-upload path.
Diagnostic summaryBounded counters only, no contentThe client-diagnostic summary is already size-bounded by api-contract-standard and observability-plan.

Pagination Defaults

The api-contract-standard mandates cursor pagination for growing collections and requires each endpoint to document its default and maximum page size. This page proposes the defaults so feature endpoints do not each invent one.

List classProposed defaultProposed maximumPagination
Client list, program library, message threads, progress timeline, task inbox, food/log lists25100Cursor. Sort order stable across pages; tenant-scoped.
Short bounded enum-backed option listsFull listSmall fixed boundOffset allowed only where the collection is fixed and small, per api-contract-standard.

Global counts are not returned where a count could leak hidden resources, per api-contract-standard and roles-and-permissions.

Provider-Quota Headroom

The authoritative quota numbers live in the integration-register. This page checks the assumed Public V1 volume against them and flags where headroom is comfortable versus where it must be watched. It does not restate or override the register's values.

ProviderRegister-stated limitHeadroom against assumed volume
Expo Push600 notifications/sec/project, 100-message batches, 1000-receipt batchesComfortable at assumed launch volume; reminders and messages batch well. Watch at the headroom ceiling with many large workspaces active in one morning window.
GIPHYBeta 100 calls/hour; production approval needed aboveBeta key is insufficient for real messaging use; the register already requires production approval — a launch dependency, not a scale surprise.
YMovePaid-plan limits; internal caps; 48-hour URL expiryCoach-web search and mobile demo playback must respect internal caps; the register owns caps and reconciliation. Program snapshots do not re-hit the provider.
Grafana Cloud / SentryPlan-dependent ingest and retention quotasBounded by the metric-label and retention discipline in observability-plan; scale risk is cardinality, not request volume.

Design-For-Scale-First Screens

These are the screens where the 20-vs-2,000 gap changes the design, not just the data. Each must be built against the headroom ceiling from day one.

ScreenWhy it breaks at scaleRequired design posture
Program builderLarge catalogs, many exercises per program, many assignments; a coach with a big book reuses and clones heavily.Cursor-paged catalog and assignment lists; no full-library load; program snapshots avoid re-fetching provider data.
Today view (client mobile)Must resolve today's tasks instantly, offline-first, under poor network.Bounded, pre-materialized daily slice; offline queue for logs; never a synchronous fan-out across full history.
Progress timelineYears of daily rows per client; a naive load is unbounded.Cursor pagination over tenant-leading indexes; windowed/aggregated views; never a full-history scan on open.
Coach task inboxThe canonical 20-vs-2,000 screen: fine at 20 clients, O(n) at 2,000.Cursor pagination, server-side triage/filtering, bounded default page; no per-client fan-out to build the list.

Note

The tenant-leading composite indexes required by multi-tenancy — for example (workspace_id, created_at) — are what let these screens page efficiently. A non-leading tenant column makes every one of these queries scan across tenants and degrade exactly as client count grows. Index shape is owned there; this page names the screens that depend on it.

Required Evidence

Scale behavior is proven against the headroom ceiling, not the typical case.

  • The four design-for-scale screens return within their surface latency budget with a seeded workspace at the 2,000-client ceiling.
  • Every growing list endpoint is cursor-paged, stable across pages, and does not return a leaking global count.
  • A device returning from a long offline period drains its outbox across bounded exchanges without an oversized request or response.
  • A first-login pull is slice-bounded and tenant-scoped.
  • Media processing keeps coachme.upload.processing.oldest.age within target at assumed per-workspace burst volume.
  • Normal interactive JSON stays within the per-surface p95 budget and under the observability-plan 1 s objective.
  • Provider calls stay within integration-register caps at assumed volume, with degradation behavior proven at the ceiling.

Proposed Locks And Open Questions

Because this is a draft, nothing here is locked. On approval, the first group is intended to become design rules; the second stays open.

Proposed To Lock On Approval

  • Design the heaviest screens for the 2,000-client ceiling, not the typical 20–150.
  • Per-surface latency budgets as design targets under the observability 1 s objective.
  • Bounded sync payloads and paged pulls, with media always by upload-intent.
  • Cursor pagination defaults (25 default / 100 max) for growing lists.
  • The four design-for-scale-first screens as launch design requirements.

Deliberately Open

  • The assumption figures themselves, which are revisited against real production traffic — that is the whole point of stating them as assumptions.
  • Exact sync batch and slice numbers within the bounded-batch intent, set with offline-sync-protocol.
  • Storage cost and quota headroom, which wait on the object-storage service selection in the integration-register.
  • Load-test evidence shape and gating, owned by test-and-release-gate.

These pages own adjacent rules this page depends on but does not redefine.

API Contract Standard

Owns cursor pagination, collection envelopes, and per-endpoint page-size documentation.

Observability Plan

Owns the p95 latency objective, operational alert thresholds, and the processing-age and queue-age gauges that measure whether these assumptions held.

Offline Sync Protocol

Owns sync operation envelopes, receipts, replay, conflict handling, and the payload budgets this page targets.

Integration Register

Owns the authoritative provider quota, rate-limit, pricing, and object-storage numbers this page analyzes headroom against.

Multi-tenancy

Owns the tenant fence and tenant-leading index shape that make the scale-sensitive screens page efficiently.

Environment Runbook

Owns host, database, and container sizing and the capacity posture these assumptions must fit.

Media Security

Owns the byte-path security treatment of the media whose volume this page estimates.

Security Plan

Owns the per-endpoint rate-limit strategy that bounds request volume alongside these design budgets.

Test And Release Gate

Owns performance and load-test evidence and its gating.

Development Readiness Review

Tracks this page as one of the three architecture docs required before implementation commits to schemas and APIs.

CoachMe internal planning documentation.