These optimizations apply to Docker, Docker Compose, Kubernetes, and any container runtime using cgroups for resource management.
Quick Start
For most production deployments, add these settings to your container:Go Runtime Tuning
GOMAXPROCS (Automatic)
Bifrost automatically detects container CPU limits using automaxprocs. This setsGOMAXPROCS to match your container’s CPU quota from cgroups (v1 and v2).
No configuration needed - this works automatically. You’ll see a log line at startup:
GOGC (Garbage Collection)
GOGC controls garbage collection frequency. The default is 100 (GC triggers when heap grows 100% since last collection).
GOMEMLIMIT (Memory Limit)
GOMEMLIMIT sets a soft memory limit for the Go runtime. When approaching this limit, Go becomes more aggressive about garbage collection.
Best practice: Set to ~90% of your container’s memory limit to leave headroom for non-heap memory (goroutine stacks, CGO, etc.).
When using both
GOGC and GOMEMLIMIT, Go GCs based on whichever trigger fires first. For high-throughput workloads, set GOGC=200 or higher and let GOMEMLIMIT be the primary constraint.System Limits
File Descriptor Limits (ulimits)
Each HTTP connection requires a file descriptor. The default container limit (often 1024) is too low for high-concurrency workloads.Resource Limits
Set CPU and memory limits to match your expected workload:Docker Compose Examples
Development
Production (Single Node)
Production (Multi-Node with PostgreSQL)
If you use PostgreSQL for Bifrost storage, ensure the database is UTF8 encoded. See PostgreSQL UTF8 Requirement.
Kubernetes Configuration
Basic Deployment
File Descriptor Limits in Kubernetes
File descriptor limits in Kubernetes are typically set at the node level. Options include:- Node-level configuration (recommended): Set
fs.file-maxand ulimits in your node configuration - Init container: Use an init container with elevated privileges to set limits
- Security context: Some clusters allow setting capabilities
Check your current limits inside a container with:
cat /proc/sys/fs/file-max and ulimit -nBifrost Application Settings
Align Bifrost’s internal settings with your container resources:Concurrency and Buffer Size
Configure per provider inconfig.json:
concurrency= expected RPS per providerbuffer_size= 1.5 × concurrency
Initial Pool Size
Configure globally inconfig.json:
initial_pool_size = 1.5 × total expected RPS across all providers
Tuning Checklist
1
Set container resource limits
Define CPU and memory limits based on expected workload. Start with 2 CPUs / 2GB for moderate loads.
2
Configure GOMEMLIMIT
Set to 90% of container memory limit (e.g.,
1800MiB for 2GB container).3
Tune GOGC
Start with
GOGC=200 for throughput; reduce to 100 if memory pressure is high.4
Set file descriptor limits
Set
nofile ulimit to at least 2× your expected concurrent connections.5
Align Bifrost settings
Match
concurrency and buffer_size to your container’s CPU count and expected RPS.6
Monitor and adjust
Watch memory usage, GC pause times, and request latencies. Adjust settings based on observed behavior.
Troubleshooting
High Memory Usage
- Reduce
GOGC(e.g., from 200 to 100) - Ensure
GOMEMLIMITis set - Reduce
buffer_sizeandinitial_pool_size
High Latency Spikes
- May indicate GC pauses; try reducing
GOGC - Check if container is hitting CPU limits
- Verify
GOMAXPROCSmatches container CPU quota (check startup logs)
Connection Errors Under Load
- Increase
nofileulimit - Ensure
buffer_sizeis large enough for traffic spikes - Check provider rate limits
Container OOM Killed
- Reduce
GOMEMLIMITto 85% of container memory - Reduce
GOGCto trigger more frequent GC - Reduce
buffer_sizeandinitial_pool_size
Related Documentation
- Performance Tuning - Bifrost-specific performance configuration
- Helm Deployment - Kubernetes deployment with Helm
- Multi-Node Setup - Scaling across multiple instances

