Skip to main content
BlindCast adds an encryption layer to your video stack. Monitor these metrics to catch issues before they affect viewers.

Player metrics

The player exposes real-time metrics via getMetrics():
const metrics = player.getMetrics()
MetricTypeWhat it means
timeToFirstFramenumber (ms)Time from load() to first video frame rendered. Includes key fetch + first segment decrypt. Target: under 2s on broadband.
avgDecryptTimenumber (ms)Average time per segment decryption. Should be under 5ms on modern hardware.
avgFragLoadTimenumber (ms)Average time per fragment download. High values indicate CDN or bandwidth issues.
avgKeyFetchTimenumber (ms)Average time per key server request. Target: under 100ms p95.
keyFetchCountnumberTotal key requests made.
qualitySwitchesnumberNumber of ABR quality level changes. Frequent switches indicate unstable bandwidth.
fragmentsLoadednumberTotal segments loaded so far.
stallCountnumberNumber of playback stalls (buffer underruns). Should be 0 under normal conditions.

Reporting metrics

Send metrics to your analytics backend on playback end or periodically:
player.on("ended", () => {
  const metrics = player.getMetrics()
  analytics.track("video_playback_complete", {
    contentId,
    timeToFirstFrame: metrics.timeToFirstFrame,
    avgDecryptTime: metrics.avgDecryptTime,
    avgKeyFetchTime: metrics.avgKeyFetchTime,
    stallCount: metrics.stallCount,
  })
})

What to alert on

ConditionPossible cause
timeToFirstFrame > 5s (p95)Key server latency, slow CDN, or large first segment
stallCount > 0 (frequent)CDN throughput issues or client CPU overloaded from decryption
avgKeyFetchTime > 500ms (p95)Key server overloaded or network issue

Key server metrics

Health check

GET /health returns 200 OK when the server is running. Use this for:
  • Docker health checks: HEALTHCHECK CMD curl -f http://localhost:4100/health
  • Load balancer probes
  • Uptime monitoring (Pingdom, Better Uptime, etc.)

Request logging

The key server logs each request to stdout in JSON format. Pipe to your log aggregator (Datadog, CloudWatch, etc.) and monitor:
MetricHow to measureAlert threshold
Key fetch latencyp50/p95 of GET /keys/:contentId response timep95 > 100ms
Error rate (4xx)Count of 401 + 403 responses / total requests> 5%
Error rate (5xx)Count of 500 responses / total requests> 0.1%
Lease creation rateCount of POST /keys/leases per minuteUnusual spike (>2x baseline)
Lease revocation rateCount of POST /keys/leases/revoke per minuteUnusual spike

Prometheus metrics (optional)

If you run a reverse proxy (nginx, Caddy) in front of the key server, use its built-in Prometheus exporter to track request rates, latency histograms, and error codes.

Database monitoring

Postgres

If using Postgres for lease storage:
MetricWhat to watch
Connection countShould stay well below max_connections
Query latencyLease queries should be under 10ms
Table sizeleases table grows over time — monitor row count
Dead tuplesRun VACUUM if dead tuple ratio is high

SQLite

If using SQLite (single-instance deployments):
MetricWhat to watch
Database file sizeMonitor /data/blindcast.db size
WAL file sizeLarge WAL files indicate slow checkpointing
Disk spaceSQLite needs free disk space for journaling

Infrastructure

ComponentHealth checkWhat to monitor
Key server containerGET /healthCPU, memory, restart count
Postgrespg_isreadyConnections, replication lag, disk
S3 / R2AWS Health Dashboard4xx/5xx error rates on GET requests
CDNProvider dashboardCache hit ratio, bandwidth, error rates

CDN cache hit ratio

Target: >95% cache hit ratio for segment requests. Low hit ratios mean the CDN is fetching from origin on most requests, adding latency and cost.
# CloudFront: check via CloudWatch metric "CacheHitRate"
# Cloudflare: check via Analytics dashboard → Cache tab

Dashboard template

Build a monitoring dashboard with these panels:
  1. Player experience — Time to first frame (p50, p95, p99), stall rate
  2. Key server — Request rate, latency (p50, p95), error rate (4xx, 5xx)
  3. Leases — Active lease count, creation rate, revocation rate
  4. Infrastructure — Container CPU/memory, DB connections, CDN cache hit ratio

Debugging playback issues

When a viewer reports playback problems:
  1. Check key server logs — Was the key request successful? Look for 401 (auth), 403 (lease revoked/expired), 500 (server error).
  2. Check player metrics — If avgKeyFetchTime is high, the issue is key server latency. If stallCount is high, the issue is CDN or bandwidth.
  3. Check CDN logs — Are segments being served? Look for 403 (CORS) or 404 (missing segments).
  4. Check lease state — If using leases, query the database: SELECT * FROM leases WHERE viewer_id = 'user-123' ORDER BY created_at DESC LIMIT 5;