Docker Performance Tuning
This guide covers performance tuning for DeepIntShield when running in Docker containers. Proper tuning ensures DeepIntShield can fully utilize container resources and achieve optimal throughput.
Quick Start
Section titled “Quick Start”For most production deployments, add these settings to your container:
services: deepintshield: image: maximhq/deepintshield:latest environment: - GOGC=200 - GOMEMLIMIT=3600MiB # 90% of 4GB memory limit ulimits: nofile: soft: 65536 hard: 65536 deploy: resources: limits: cpus: '4' memory: 4GGo Runtime Tuning
Section titled “Go Runtime Tuning”GOMAXPROCS (Automatic)
Section titled “GOMAXPROCS (Automatic)”DeepIntShield automatically detects container CPU limits using automaxprocs. This sets GOMAXPROCS 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:
maxprocs: Updating GOMAXPROCS=4: determined from CPU quotaGOGC (Garbage Collection)
Section titled “GOGC (Garbage Collection)”GOGC controls garbage collection frequency. The default is 100 (GC triggers when heap grows 100% since last collection).
| Scenario | Recommended GOGC | Trade-off |
|---|---|---|
| Memory constrained | 50-100 | More frequent GC, lower memory |
| High throughput, memory available | 200-400 | Less GC overhead, higher memory |
| Latency sensitive | 50-100 | More predictable latency |
environment: - GOGC=200GOMEMLIMIT (Memory Limit)
Section titled “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.).
| Container Memory | Recommended GOMEMLIMIT |
|---|---|
| 512 MB | 450MiB |
| 1 GB | 900MiB |
| 2 GB | 1800MiB |
| 4 GB | 3600MiB |
| 8 GB | 7200MiB |
environment: - GOMEMLIMIT=3600MiBSystem Limits
Section titled “System Limits”File Descriptor Limits (ulimits)
Section titled “File Descriptor Limits (ulimits)”Each HTTP connection requires a file descriptor. The default container limit (often 1024) is too low for high-concurrency workloads.
ulimits: nofile: soft: 65536 hard: 65536| Expected Concurrent Connections | Recommended nofile |
|---|---|
| < 1000 | 4096 |
| 1000-5000 | 16384 |
| 5000-10000 | 32768 |
| > 10000 | 65536+ |
Resource Limits
Section titled “Resource Limits”Set CPU and memory limits to match your expected workload:
deploy: resources: limits: cpus: '4' memory: 4G reservations: cpus: '2' memory: 2GSizing guidance:
| Expected RPS | Recommended CPUs | Recommended Memory |
|---|---|---|
| 100-500 | 1-2 | 512MB-1GB |
| 500-2000 | 2-4 | 1-2GB |
| 2000-5000 | 4-8 | 2-4GB |
| 5000+ | 8+ | 4GB+ |
Docker Compose Examples
Section titled “Docker Compose Examples”Development
Section titled “Development”services: deepintshield: image: maximhq/deepintshield:latest ports: - "8080:8080" volumes: - ./data:/app/data environment: - LOG_LEVEL=debugProduction (Single Node)
Section titled “Production (Single Node)”services: deepintshield: image: maximhq/deepintshield:latest ports: - "8080:8080" volumes: - deepintshield-data:/app/data environment: - LOG_LEVEL=info - LOG_STYLE=json - GOGC=200 - GOMEMLIMIT=3600MiB ulimits: nofile: soft: 65536 hard: 65536 deploy: resources: limits: cpus: '4' memory: 4G reservations: cpus: '2' memory: 2G healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "-O", "/dev/null", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 restart: unless-stopped
volumes: deepintshield-data:Production (Multi-Node with PostgreSQL)
Section titled “Production (Multi-Node with PostgreSQL)”services: deepintshield-1: image: maximhq/deepintshield:latest ports: - "8081:8080" environment: - LOG_LEVEL=info - GOGC=200 - GOMEMLIMIT=1800MiB - DEEPINTSHIELD_DB_TYPE=postgres - DEEPINTSHIELD_DB_DSN=postgres://user:pass@postgres:5432/deepintshield?sslmode=disable ulimits: nofile: soft: 65536 hard: 65536 deploy: resources: limits: cpus: '2' memory: 2G depends_on: - postgres
deepintshield-2: image: maximhq/deepintshield:latest ports: - "8082:8080" environment: - LOG_LEVEL=info - GOGC=200 - GOMEMLIMIT=1800MiB - DEEPINTSHIELD_DB_TYPE=postgres - DEEPINTSHIELD_DB_DSN=postgres://user:pass@postgres:5432/deepintshield?sslmode=disable ulimits: nofile: soft: 65536 hard: 65536 deploy: resources: limits: cpus: '2' memory: 2G depends_on: - postgres
postgres: image: postgres:16-alpine environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=pass - POSTGRES_DB=deepintshield volumes: - postgres-data:/var/lib/postgresql/data
volumes: postgres-data:Kubernetes Configuration
Section titled “Kubernetes Configuration”Basic Deployment
Section titled “Basic Deployment”apiVersion: apps/v1kind: Deploymentmetadata: name: deepintshieldspec: replicas: 3 selector: matchLabels: app: deepintshield template: metadata: labels: app: deepintshield spec: containers: - name: deepintshield image: maximhq/deepintshield:latest ports: - containerPort: 8080 env: - name: GOGC value: "200" - name: GOMEMLIMIT value: "3600MiB" resources: limits: cpu: "4" memory: "4Gi" requests: cpu: "2" memory: "2Gi" livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 5 periodSeconds: 10 readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 5 periodSeconds: 5File Descriptor Limits in Kubernetes
Section titled “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
securityContext: capabilities: add: ["SYS_RESOURCE"]DeepIntShield Application Settings
Section titled “DeepIntShield Application Settings”Align DeepIntShield’s internal settings with your container resources:
Concurrency and Buffer Size
Section titled “Concurrency and Buffer Size”Configure per provider in config.json:
{ "providers": { "openai": { "concurrency_and_buffer_size": { "concurrency": 1000, "buffer_size": 1500 } } }}Formula:
concurrency= expected RPS per providerbuffer_size= 1.5 × concurrency
Initial Pool Size
Section titled “Initial Pool Size”Configure globally in config.json:
{ "client": { "initial_pool_size": 3000 }}Formula: initial_pool_size = 1.5 × total expected RPS across all providers
Tuning Checklist
Section titled “Tuning Checklist”Set container resource limits
Section titled “Set container resource limits”Define CPU and memory limits based on expected workload. Start with 2 CPUs / 2GB for moderate loads.
Configure GOMEMLIMIT
Section titled “Configure GOMEMLIMIT”Set to 90% of container memory limit (e.g., 1800MiB for 2GB container).
Tune GOGC
Section titled “Tune GOGC”Start with GOGC=200 for throughput; reduce to 100 if memory pressure is high.
Set file descriptor limits
Section titled “Set file descriptor limits”Set nofile ulimit to at least 2× your expected concurrent connections.
Align DeepIntShield settings
Section titled “Align DeepIntShield settings”Match concurrency and buffer_size to your container’s CPU count and expected RPS.
Monitor and adjust
Section titled “Monitor and adjust”Watch memory usage, GC pause times, and request latencies. Adjust settings based on observed behavior.
Troubleshooting
Section titled “Troubleshooting”High Memory Usage
Section titled “High Memory Usage”- Reduce
GOGC(e.g., from 200 to 100) - Ensure
GOMEMLIMITis set - Reduce
buffer_sizeandinitial_pool_size
High Latency Spikes
Section titled “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
Section titled “Connection Errors Under Load”- Increase
nofileulimit - Ensure
buffer_sizeis large enough for traffic spikes - Check provider rate limits
Container OOM Killed
Section titled “Container OOM Killed”- Reduce
GOMEMLIMITto 85% of container memory - Reduce
GOGCto trigger more frequent GC - Reduce
buffer_sizeandinitial_pool_size
Related Documentation
Section titled “Related Documentation”- Performance Tuning - DeepIntShield-specific performance configuration
- Helm Deployment - Kubernetes deployment with Helm
- Multi-Node Setup - Scaling across multiple instances