Platform Metrics Transparency

This page shows what telemetry PayCal collects, why we collect it, and when it is deleted.

Our Commitment

Users should be able to see exactly what telemetry a service collects. This page documents each metric used to monitor platform health.

All telemetry on this page is aggregate-only. We do not store personal identifiers in telemetry keys.

Verification Metadata

Route metadata

  • Route: /transparency/metrics/
  • Last verified:
  • Next review due:
  • Verification scope: manual content review against current metric key inventory and retention policy.

Known limitations

  • Metric key inventory is manually kept in sync with code; automated key-diff tooling is planned for quarterly reviews.
  • Retention values reflect current configuration defaults and may not reflect tenant-specific overrides if introduced in future releases.

This metadata is updated as part of the quarterly audit close-out.

Metric Inventory

Metric Category Personal Data? Retention Purpose
Session lifecycle metrics No 30 days raw, 52 weeks rollup, 24 months monthly User experience and capacity planning
Redis health metrics No 24 hours raw, 7 days hourly, 4 weeks daily Infrastructure reliability
Business aggregates No 30 days daily, 52 weeks weekly, 24 months monthly Growth and planning
Frontend telemetry events No 30 days Error detection and feature health
Encryption operation metrics No 30 days raw, 52 weeks rollup, 24 months monthly Cryptographic reliability

Session Lifecycle Metrics No Personal Data

We count login/logout totals and session duration ranges to understand usage patterns. We do not track who logged in.

What: Daily login events, logout events, and session duration distributions.

Why: Detect authentication issues, reduce friction, and improve capacity planning.

How: Daily counters and fixed duration buckets.

Retention: 30 days raw -> 52 weeks rollup -> 24 months monthly -> purge.

Buckets:

  • 0-5min - Quick checks
  • 5-30min - Typical session
  • 30-60min - Extended session
  • 60min+ - Long work session

Example Keys:

telemetry:auth:login:2026-03-09      -> 247
telemetry:auth:logout:2026-03-09     -> 219
telemetry:session:duration:0-5min    -> 45
telemetry:session:duration:5-30min   -> 128
telemetry:session:duration:30-60min  -> 39
telemetry:session:duration:60min+    -> 7

Privacy Guard: Session hash is destroyed immediately after duration calculation. No user UUIDs are stored in telemetry keys.

Volume Cap: Maximum 734 keys/year.

Redis Health Metrics No Personal Data

We monitor Redis as infrastructure health data, not user activity data.

What: Memory usage, key counts by namespace, and connection stats.

Why: Detect memory leaks, prevent evictions, and watch growth.

How: Parse Redis INFO output on a scheduled interval.

Retention: 24 hours raw -> 7 days hourly -> 4 weeks daily -> purge.

Namespaces: Max 10 tracked namespaces (hardcoded whitelist).

  • session:* - Active sessions
  • lock:* - Distributed locks
  • cache:* - Application cache
  • telemetry:* - Metrics storage
  • ratelimit:* - Rate limiting counters
  • nonce:* - CSRF tokens
  • temp:* - Temporary data
  • queue:* - Job queues
  • encryption:* - Wrapped keys
  • feature:* - Feature flags

Example Keys:

telemetry:redis:memory:used_mb:2026-03-09:14  -> 247
telemetry:redis:keys:session:2026-03-09:14    -> 342
telemetry:redis:keys:lock:2026-03-09:14       -> 18

Privacy Guard: Namespace counts are aggregated only. Key content is not inspected.

Volume Cap: 1,680 keys maximum in the active rolling window.

Business Aggregate Metrics No Personal Data

These are top-level platform totals used for planning, not profiling individuals.

What: Total users, active accounts, average work entries.

Why: Capacity planning and growth analysis.

How: Daily aggregation of database counts.

Retention: 30 days daily -> 52 weeks weekly -> 24 months monthly -> purge.

Example Keys:

telemetry:business:users:total:2026-03-09     -> 1247
telemetry:business:users:active:2026-03-09    -> 892
telemetry:business:work:avg_per_user:2026-03  -> 23.4

Privacy Guard: Aggregate-only values. No per-user telemetry records.

Volume Cap: 1,095 keys/year.

Frontend Telemetry Events No Personal Data

Event telemetry helps detect client-side failures and feature reliability issues.

What: Frontend performance events, error counts, and feature usage events.

Why: Identify client issues and monitor product health.

How: POST to /api/telemetry/record for approved event types only.

Retention: 30 days (TTL enforced on increment).

Telemetry submission limits and example event types:

  • 90 events/minute per client (abuse prevention)
  • calendar.load.success
  • calendar.load.failure
  • encryption.dek.unwrap.success
  • encryption.dek.unwrap.failure
  • passkey.login.success
  • passkey.login.failure

Example Keys:

telemetry:event:calendar.load.success:2026-03-09    -> 3421
telemetry:event:passkey.login.failure:2026-03-09    -> 17

Privacy Guard: Event types are allowlisted. No arbitrary strings and no user/session identifiers in telemetry keys.

Volume Cap: 18,250 keys/year maximum.

Encryption Operation Metrics No Personal Data

Cryptographic operations are monitored as platform reliability signals.

What: DEK wrap/unwrap success and failure counters.

Why: Detect cryptographic failures and misconfiguration quickly.

How: Success/failure counters increment for each operation outcome.

Retention: 30 days raw -> 52 weeks rollup -> 24 months monthly -> purge.

Example Keys:

telemetry:encryption:dek:wrap:success:2026-03-09      -> 1203
telemetry:encryption:dek:wrap:failure:2026-03-09      -> 2
telemetry:encryption:dek:unwrap:success:2026-03-09    -> 5847
telemetry:encryption:dek:unwrap:failure:2026-03-09    -> 31

Privacy Guard: Only operation counts are recorded. No key material, ciphertext, or personal identifiers are stored.

Volume Cap: 1,460 keys/year.

Retention and Compaction Pipeline

Raw data: Daily counters expire automatically after 30 days.

Weekly rollups: Scheduled aggregation to 52-week retention.

Monthly rollups: Scheduled aggregation to 24-month retention.

Purge: Metrics older than 24 months are deleted.

Compaction script: /scripts/compact-metrics.php.

Enforcement in Code

Privacy constraints are validated by contract tests in CI.

MetricsPrivacyContractTest::testSessionDurationHasExactlyFourBuckets()
MetricsPrivacyContractTest::testNoUserUUIDsInTelemetryKeys()
MetricsPrivacyContractTest::testRedisNamespacesNeverExceedTen()
MetricsPrivacyContractTest::testAllTelemetryKeysHaveTTL()

Guardrails: Hardcoded namespace/event limits prevent unbounded metric growth.

Additional rate limits:

  • Admin metrics queries: 100 requests/hour
  • Public health checks: 600 requests/hour

Access and Verification

Metrics Dashboard: /admin/metrics (authentication and admin role required).

Public Health Endpoint: /api/v1/health returns aggregate platform status.

Last Updated: March 9, 2026.