Skip to main content

Production Deployment

This guide covers best practices, architecture patterns, and operational considerations for deploying Moq in production.

Architecture Overview

A production Moq deployment typically consists of:
Publishers → Origin Relays → Regional Relays → Edge Relays → Viewers
              (Primary)       (Intermediate)    (CDN/Edge)

Component Roles

  • Origin Relays: Receive content from publishers, authenticate, validate
  • Regional Relays: Aggregate traffic, provide redundancy, span continents
  • Edge Relays: Serve viewers, cache content, distributed globally
  • Root Relay: Coordinates cluster, tracks broadcasts (can be any relay)

Deployment Checklist

1

TLS Certificates

Use valid TLS certificates from Let’s Encrypt or a commercial CA. Self-signed certificates are not suitable for production.
certbot certonly --standalone -d relay.example.com
2

Authentication

Enable JWT authentication and disable public access (or limit to specific paths).
[auth]
key = "/etc/moq/secret.jwk"
# public = ""  # Disable public access
3

Monitoring

Set up logging, metrics, and alerting to track relay health and performance.
4

Redundancy

Deploy at least 2 relays per region for high availability.
5

Load Balancing

Use DNS or anycast to distribute traffic across relays.
6

Firewall

Configure firewalls to allow only necessary traffic.
7

Systemd Service

Run relays as system services with automatic restart.
8

Auto-scaling

Configure auto-scaling based on CPU, bandwidth, or connection count.

Multi-Region Deployment

Three-Tier Architecture

For global deployments:
Layer 1: Origin (1-2 relays)

   └─── Receives content from publishers
   │   Authoritative source
   │   High-reliability hardware

   v
Layer 2: Regional (3-6 relays)

   └─── NA-East, NA-West, EU-West, EU-East, APAC, SA
   │   Aggregate traffic from origins
   │   Provide redundancy

   v
Layer 3: Edge (10-100+ relays)

   └─── Major cities worldwide
       Serve viewers
       Cache content
       Lowest latency to users

Configuration Example

Origin Relay (us-east-1):
origin.toml
[log]
level = "info"

[server]
listen = "[::]:443"

[server.tls]
cert = "/etc/letsencrypt/live/origin.example.com/fullchain.pem"
key = "/etc/letsencrypt/live/origin.example.com/privkey.pem"

[auth]
key = "/etc/moq/secret.jwk"
# No public access on origin

# This is the root relay for the cluster
Regional Relay (eu-west-1):
regional.toml
[log]
level = "info"

[server]
listen = "[::]:443"

[server.tls]
cert = "/etc/letsencrypt/live/eu.example.com/fullchain.pem"
key = "/etc/letsencrypt/live/eu.example.com/privkey.pem"

[auth]
key = "/etc/moq/public.jwk"  # Public key from origin

[cluster]
root = "https://origin.example.com?jwt=CLUSTER_TOKEN"
node = "https://eu.example.com"
Edge Relay (london):
edge.toml
[log]
level = "warn"  # Less verbose on edge

[server]
listen = "[::]:443"

[server.tls]
cert = "/etc/letsencrypt/live/london.example.com/fullchain.pem"
key = "/etc/letsencrypt/live/london.example.com/privkey.pem"

[web.https]
listen = "[::]:443"
cert = "/etc/letsencrypt/live/london.example.com/fullchain.pem"
key = "/etc/letsencrypt/live/london.example.com/privkey.pem"

[auth]
key = "/etc/moq/public.jwk"
public = "demo"  # Allow anonymous viewing on edge

[cluster]
root = "https://origin.example.com?jwt=CLUSTER_TOKEN"
node = "https://london.example.com"

High Availability

Load Balancing

DNS Round-Robin

Simplest approach:
relay.example.com.  A      1.2.3.4
relay.example.com.  A      5.6.7.8
relay.example.com.  AAAA   2001:db8::1
relay.example.com.  AAAA   2001:db8::2
Pros:
  • Simple to implement
  • No additional infrastructure
Cons:
  • No health checking
  • Clients may cache DNS
  • Not latency-aware

GeoDNS

Route users to nearest relay:
# Users in North America get:
relay.example.com.  A      us-east.example.com

# Users in Europe get:
relay.example.com.  A      eu-west.example.com

# Users in Asia get:
relay.example.com.  A      ap-south.example.com
Providers: Route53, Cloudflare, NS1, Azure Traffic Manager

Anycast

Multiple relays share the same IP address:
All relays announce: 203.0.113.10
Internet routing delivers to nearest relay
Pros:
  • Automatic failover
  • Lowest latency (network-layer routing)
  • No DNS caching issues
Cons:
  • Requires BGP setup
  • More complex infrastructure
  • Typically needs hosting with anycast support

Health Checking

Monitor relay health:
#!/bin/bash
# health-check.sh

RELAY_URL="http://relay.example.com:4443/"

if curl -sf "$RELAY_URL" > /dev/null; then
  echo "Relay healthy"
  exit 0
else
  echo "Relay unhealthy"
  exit 1
fi
Run from monitoring system (Prometheus, Datadog, etc.)

Redundant Origins

Deploy origins in active-active or active-passive: Active-Passive:
Primary Origin (active)

   v (failure)

Secondary Origin (standby)
Publishers connect to primary, failover to secondary. Active-Active:
Origin A ←───── Publishers (50%)
Origin B ←───── Publishers (50%)
Both origins active, load balanced.

Security

Network Security

Firewall Rules

  • Allow only UDP 443 and TCP 443
  • Restrict management ports to internal IPs
  • Use security groups/firewall rules

DDoS Protection

  • Use DDoS protection service (Cloudflare, AWS Shield)
  • Rate limit connections per IP
  • Monitor for anomalies

Private Networks

  • Use private networking for relay-to-relay communication
  • VPN or VPC peering between regions
  • Keep cluster tokens on private network

Intrusion Detection

  • Monitor logs for suspicious activity
  • Alert on authentication failures
  • Track connection patterns

Application Security

Authentication

Always enable authentication in production:
[auth]
key = "/etc/moq/secret.jwk"
# Never use public = "" in production without careful consideration
See Authentication Guide for setup.

Token Security

  • Short-lived tokens: 1-24 hours maximum
  • Refresh tokens: Issue new tokens before expiration
  • Revocation: Rotate keys to revoke all tokens
  • Minimal permissions: Only grant needed publish/subscribe rights

Secrets Management

Never commit keys to version control:
# Use secrets management
# AWS Secrets Manager
aws secretsmanager get-secret-value --secret-id moq/secret.jwk \
  --query SecretString --output text > /etc/moq/secret.jwk

# HashiCorp Vault
vault kv get -field=jwk secret/moq/key > /etc/moq/secret.jwk

# Kubernetes Secret
kubectl create secret generic moq-key --from-file=secret.jwk

TLS Best Practices

  • Use Let’s Encrypt: Free, automated, trusted
  • Auto-renewal: Set up certbot auto-renewal
  • Strong ciphers: Let QUIC handle cipher selection
  • Certificate monitoring: Alert before expiration

Monitoring & Observability

Metrics to Track

  • CPU usage
  • Memory usage
  • Network bandwidth (in/out)
  • Disk I/O
  • UDP packet loss
  • Connection count

Logging

[log]
level = "info"  # warn for edge, info for regional, debug for origin
Structured logging:
# JSON logs for parsing
RUST_LOG=info moq-relay relay.toml 2>&1 | jq .

# Send to logging service
moq-relay relay.toml 2>&1 | logger -t moq-relay

Alerting

Set up alerts for:
  • Relay down (health check fails)
  • High CPU usage (over 80%)
  • High memory usage (over 90%)
  • Certificate expiring (less than 7 days)
  • Authentication failure spike
  • Abnormal traffic patterns

Performance Optimization

Operating System

# Increase file descriptors
echo "* soft nofile 1048576" >> /etc/security/limits.conf
echo "* hard nofile 1048576" >> /etc/security/limits.conf

# Optimize network stack
sysctl -w net.core.rmem_max=134217728
sysctl -w net.core.wmem_max=134217728
sysctl -w net.ipv4.udp_mem='4096 873800 16777216'

# Increase UDP buffer
sysctl -w net.core.netdev_max_backlog=5000

Hardware Recommendations

Origin Relays

  • CPU: 8-16 cores
  • RAM: 16-32 GB
  • Network: 10 Gbps
  • Storage: Fast SSD for caching

Regional Relays

  • CPU: 16-32 cores
  • RAM: 32-64 GB
  • Network: 10-40 Gbps
  • Storage: NVMe SSD

Edge Relays

  • CPU: 4-8 cores
  • RAM: 8-16 GB
  • Network: 1-10 Gbps
  • Storage: SSD for caching

Cloud Provider Recommendations

Origin: c7g.2xlarge (8 vCPU, 16 GB RAM)Regional: c7g.4xlarge (16 vCPU, 32 GB RAM)Edge: c7g.xlarge (4 vCPU, 8 GB RAM)Use Elastic IP or ALB with UDP support.

Scaling

Horizontal Scaling

Add more relays as traffic grows:
Phase 1: Single relay
  → 1,000 concurrent viewers

Phase 2: Regional cluster
  → 10,000 concurrent viewers

Phase 3: Multi-region cluster
  → 100,000+ concurrent viewers

Phase 4: Multi-tier with edge
  → 1,000,000+ concurrent viewers

Auto-scaling

With Kubernetes or cloud auto-scaling:
# Kubernetes HPA example
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: moq-relay
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: moq-relay
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

Backup & Disaster Recovery

Configuration Backup

# Backup relay config and keys
tar czf moq-backup-$(date +%Y%m%d).tar.gz \
  /etc/moq/*.toml \
  /etc/moq/*.jwk

# Store securely
aws s3 cp moq-backup-*.tar.gz s3://backups/moq/

Recovery Plan

1

Prepare backup relay

Keep standby relay with same config, different IP
2

Document DNS changes

Document how to update DNS records
3

Test failover

Regularly test switching to backup
4

Runbook

Maintain runbook for common failures

Cost Optimization

Bandwidth Costs

Moq’s biggest cost is typically bandwidth:
  • Clustering reduces costs: Route traffic optimally
  • Caching: Edge relays cache content
  • Deduplication: One source, many viewers
  • Quality adaptation: Lower quality = less bandwidth

Cloud Cost Tips

  • Use spot/preemptible instances for non-critical edge relays
  • Reserved instances for origin/regional relays
  • Multi-cloud to leverage free egress tiers
  • Monitor bandwidth with usage alerts

Troubleshooting

  • Check logs: journalctl -u moq-relay -n 100
  • Look for OOM kills: dmesg | grep -i oom
  • Check disk space: df -h
  • Verify config file is valid
  • Check geographic distance to relay
  • Verify network path: mtr relay.example.com
  • Check relay CPU usage
  • Verify QUIC is not being blocked
  • Test with different DNS resolver
  • Check network connectivity between relays
  • Verify cluster token is valid and not expired
  • Check for firewall rules blocking relay-to-relay traffic
  • Ensure root relay is accessible from all leaves
  • Verify certificate is not expired: openssl x509 -in cert.pem -noout -dates
  • Check certificate matches hostname
  • Ensure full chain is provided
  • Check Let’s Encrypt rate limits

Next Steps

Relay Setup

Detailed relay configuration

Authentication

Setup JWT authentication

Publishing

Connect publishers to production relay

Monitoring

Advanced monitoring and debugging