Don't deploy to production without completing this checklist. It covers security, persistence, monitoring, scaling, and performance optimizations for your flashQ deployment.
Security Configuration
1. Enable Authentication
Never run flashQ without authentication in production. Set the AUTH_TOKENS environment variable:
# Single token
AUTH_TOKENS=your-secure-token-here ./flashq-server
# Multiple tokens (comma-separated)
AUTH_TOKENS=token1,token2,admin-token ./flashq-server
Generate secure tokens:
# Generate a 32-character secure token
openssl rand -hex 32
Client configuration:
import { FlashQ } from 'flashq';
const client = new FlashQ({
host: 'your-server.com',
port: 6789,
token: process.env.FLASHQ_TOKEN // Never hardcode tokens!
});
2. Enable TLS/SSL Encryption
Encrypt all traffic between clients and server:
# With certificate files
TLS_CERT=/path/to/cert.pem TLS_KEY=/path/to/key.pem ./flashq-server
# Or use a reverse proxy (recommended)
# nginx, Caddy, or cloud load balancer with TLS termination
Example Caddyfile for automatic HTTPS:
flashq.yourdomain.com {
reverse_proxy localhost:6790 # HTTP API
}
flashq-tcp.yourdomain.com {
reverse_proxy localhost:6789 # TCP with TLS
}
3. Configure Network Security
Restrict access to flashQ ports:
# Firewall rules (example with ufw)
ufw allow from 10.0.0.0/8 to any port 6789 # TCP - internal only
ufw allow from 10.0.0.0/8 to any port 6790 # HTTP - internal only
ufw deny 6789
ufw deny 6790
For Kubernetes, use NetworkPolicies:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: flashq-policy
spec:
podSelector:
matchLabels:
app: flashq
ingress:
- from:
- podSelector:
matchLabels:
access: flashq-allowed
ports:
- port: 6789
- port: 6790
4. Secure Webhook Signatures
If using webhooks, always configure HMAC signatures:
// When setting up webhooks
await client.push('orders', orderData, {
webhook: {
url: 'https://your-api.com/webhook',
secret: process.env.WEBHOOK_SECRET, // HMAC-SHA256 signature
headers: {
'X-Custom-Header': 'value'
}
}
});
// Verify webhook in your handler
import { createHmac } from 'crypto';
function verifyWebhook(payload, signature, secret) {
const expected = createHmac('sha256', secret)
.update(payload)
.digest('hex');
return signature === `sha256=${expected}`;
}
Data Persistence
5. Enable PostgreSQL Storage
In-memory mode loses all data on restart. Always use PostgreSQL in production:
# Required for production
DATABASE_URL=postgres://user:password@localhost:5432/flashq ./flashq-server
PostgreSQL configuration recommendations:
-- Recommended PostgreSQL settings for flashQ
ALTER SYSTEM SET max_connections = 200;
ALTER SYSTEM SET shared_buffers = '256MB';
ALTER SYSTEM SET effective_cache_size = '1GB';
ALTER SYSTEM SET work_mem = '16MB';
6. Configure Database Backups
Set up automated backups for your PostgreSQL database:
#!/bin/bash
# Daily backup script
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR=/var/backups/flashq
pg_dump $DATABASE_URL | gzip > $BACKUP_DIR/flashq_$DATE.sql.gz
# Keep last 7 days
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete
For cloud deployments, use managed backup solutions:
- AWS RDS: Enable automated backups with 7+ day retention
- GCP Cloud SQL: Enable automated backups
- Azure Database: Configure geo-redundant backups
7. Set Retention Policies
Configure how long to keep completed jobs and results:
// Per-job retention
await client.push('analytics', data, {
keepCompletedAge: 86400000, // Keep result for 24 hours
keepCompletedCount: 1000 // Or keep last 1000 results
});
Monitoring & Observability
8. Enable Prometheus Metrics
Enable the HTTP API to expose Prometheus metrics:
# Enable HTTP API (includes /metrics/prometheus)
HTTP=1 HTTP_PORT=6790 ./flashq-server
Prometheus scrape configuration:
# prometheus.yml
scrape_configs:
- job_name: 'flashq'
static_configs:
- targets: ['flashq-server:6790']
metrics_path: /metrics/prometheus
scrape_interval: 15s
Key metrics to monitor:
flashq_jobs_total- Total jobs by queue and statusflashq_jobs_processing- Currently processing jobsflashq_jobs_failed- Failed jobs (DLQ)flashq_queue_latency_seconds- Queue processing latency
9. Set Up Alerting
Configure alerts for critical conditions:
# alerting_rules.yml
groups:
- name: flashq
rules:
- alert: FlashQHighDLQ
expr: flashq_jobs_failed > 100
for: 5m
labels:
severity: warning
annotations:
summary: "High number of failed jobs in DLQ"
- alert: FlashQProcessingStuck
expr: flashq_jobs_processing > 0 and rate(flashq_jobs_completed[5m]) == 0
for: 10m
labels:
severity: critical
annotations:
summary: "Jobs are stuck in processing"
10. Configure Health Checks
Set up health checks for your orchestration platform:
# Kubernetes deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: flashq
spec:
template:
spec:
containers:
- name: flashq
image: flashq/flashq-server:latest
livenessProbe:
httpGet:
path: /health
port: 6790
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 6790
initialDelaySeconds: 5
periodSeconds: 5
Performance Optimization
11. Configure Worker Concurrency
Set appropriate concurrency limits based on your workload:
// For CPU-bound tasks (e.g., image processing)
const worker = new Worker('cpu-tasks', processor, {
concurrency: 4 // Match CPU cores
});
// For I/O-bound tasks (e.g., API calls)
const worker = new Worker('api-calls', processor, {
concurrency: 20 // Higher for I/O
});
// For rate-limited APIs (e.g., OpenAI)
await client.setRateLimit('openai', { max: 50, window: 60000 });
12. Enable Binary Protocol
Use MessagePack binary protocol for 40% smaller payloads:
const client = new FlashQ({
host: 'flashq-server',
port: 6789,
useBinary: true // Enable MessagePack
});
Benefits:
- 40% smaller message sizes
- 3-5x faster serialization
- Recommended for high-throughput scenarios
13. Optimize Job Payloads
Keep job payloads small and reference external data:
// BAD: Large payload
await client.push('process', {
document: largeBase64Document, // 5MB in job
});
// GOOD: Reference external storage
await client.push('process', {
documentUrl: 's3://bucket/doc.pdf', // URL reference
});
Resilience & High Availability
14. Configure Retry Policies
Set appropriate retry and backoff settings:
await client.push('critical-task', data, {
max_attempts: 5, // Retry up to 5 times
backoff: 1000, // Start with 1s backoff
timeout: 30000, // 30s processing timeout
stall_timeout: 60000 // 60s stall detection
});
// Exponential backoff: 1s, 2s, 4s, 8s, 16s
15. Enable Clustering (High Availability)
For high availability, deploy multiple flashQ nodes:
# Node 1 (will become leader)
CLUSTER_MODE=1 NODE_ID=node-1 DATABASE_URL=postgres://... ./flashq-server
# Node 2 (follower, automatic failover)
CLUSTER_MODE=1 NODE_ID=node-2 DATABASE_URL=postgres://... ./flashq-server
# Node 3 (follower)
CLUSTER_MODE=1 NODE_ID=node-3 DATABASE_URL=postgres://... ./flashq-server
Load balancer configuration:
# nginx.conf
upstream flashq {
server node1:6789;
server node2:6793;
server node3:6795;
}
server {
listen 6789;
proxy_pass flashq;
}
Quick Reference: Environment Variables
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string |
AUTH_TOKENS |
Yes | Comma-separated auth tokens |
HTTP |
Recommended | Enable HTTP API (1 to enable) |
HTTP_PORT |
Optional | HTTP port (default: 6790) |
PORT |
Optional | TCP port (default: 6789) |
CLUSTER_MODE |
Optional | Enable clustering (1 to enable) |
NODE_ID |
For clustering | Unique node identifier |
Final Production Command
# Complete production startup
DATABASE_URL=postgres://user:pass@db:5432/flashq \
AUTH_TOKENS=your-secure-token \
HTTP=1 \
HTTP_PORT=6790 \
CLUSTER_MODE=1 \
NODE_ID=node-1 \
./flashq-server --release