Skip to main content

Warm Pool Fast Activation

~10x faster MCP server cold starts using warm pool technology. Activate containers in ~1.3s instead of 8-15s.

Overview

The warm pool system pre-provisions container pods that can be rapidly activated with MCP server images. This dramatically reduces cold start latency for on-demand MCP tool execution.
MetricStandard Cold StartWarm Pool Activation
Total Time8-15 seconds~1.3 seconds
Container Creation3-5s0s (pre-created)
Image Pull5-10s~1s (layer extraction)
Process Start1-2s~0.3s

How It Works

Activation Flow

Timing Breakdown

PhaseTimeDescription
Find Warm Pod~100msSelect available pod from pool
Assign Pod~50msMark pod as in-use
Download Image~800msSkopeo pulls image layers
Extract Layers~300msExtract to container rootfs
Start Process~100mschroot + exec ENTRYPOINT
Total~1.3sFull activation time

Architecture

Components

agentarea-mcp-manager/
├── cmd/
│   ├── mcp-manager/         # Main API service
│   └── activation-service/  # Runs inside warm pool pods
├── internal/
│   ├── warmpool/           # Pool management client
│   ├── container/          # Container lifecycle
│   └── backends/           # Kubernetes backend

Warm Pool DaemonSet

Warm pool pods are deployed as a Kubernetes DaemonSet:
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: mcp-warm-pool
  namespace: agentarea
spec:
  selector:
    matchLabels:
      app: mcp-activation
  template:
    spec:
      containers:
      - name: activation-service
        image: agentarea/mcp-runner:latest
        ports:
        - containerPort: 8080
        securityContext:
          privileged: true  # Required for chroot
        volumeMounts:
        - name: container-storage
          mountPath: /var/lib/containers
        - name: image-cache
          mountPath: /var/lib/images
      volumes:
      - name: container-storage
        emptyDir: {}
      - name: image-cache
        persistentVolumeClaim:
          claimName: image-cache-pvc

Activation Service

The activation service runs inside each warm pod:
// cmd/activation-service/main.go
func main() {
    http.HandleFunc("/activate", handleActivation)
    http.HandleFunc("/health", handleHealth)
    http.ListenAndServe(":8080", nil)
}

func handleActivation(w http.ResponseWriter, r *http.Request) {
    var req ActivationRequest
    json.NewDecoder(r.Body).Decode(&req)
    
    // 1. Download image using Skopeo
    err := downloadImage(req.Image, req.InstanceID)
    
    // 2. Extract layers to rootfs
    err = extractLayers(req.InstanceID)
    
    // 3. Parse ENTRYPOINT/CMD from config
    entrypoint, cmd := parseImageConfig(req.InstanceID)
    
    // 4. Apply user overrides
    if req.Entrypoint != nil {
        entrypoint = req.Entrypoint
    }
    if req.Command != nil {
        cmd = req.Command
    }
    
    // 5. Execute via chroot
    cmd := exec.Command(entrypoint[0], append(entrypoint[1:], cmd...)...)
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Chroot: filepath.Join("/var/lib/containers", req.InstanceID),
    }
    cmd.Start()
    
    json.NewEncoder(w).Encode(ActivationResponse{
        Status:  "running",
        PID:     cmd.Process.Pid,
    })
}

Configuration

Feature Flags

Enable warm pool via feature flags:
# Environment variables
MCP_FEATURES_ENABLED=warm_pool,gateway_api,state_reconciler
WARM_POOL_ENABLED=true
WARM_POOL_SIZE=10

Helm Values

# charts/agentarea/values.yaml
mcpManager:
  warmPool:
    enabled: true
    size: 10
    image: agentarea/mcp-runner:latest
    
  features:
    enabled:
      - warm_pool
      - gateway_api
      - state_reconciler

Configuration Options

VariableDefaultDescription
WARM_POOL_ENABLEDfalseEnable warm pool
WARM_POOL_SIZE10Number of pre-provisioned pods
WARM_POOL_NAMESPACEagentareaKubernetes namespace
IMAGE_CACHE_SIZE10GiPersistent cache for images

Image Handling

Skopeo Integration

Images are downloaded using Skopeo for efficient layer handling:
func downloadImage(imageRef, instanceID string) error {
    destDir := filepath.Join("/var/lib/images", instanceID)
    
    cmd := exec.Command("skopeo", 
        "copy",
        "--dest-tls-verify=false",
        "docker://"+imageRef,
        "dir://"+destDir,
    )
    
    return cmd.Run()
}

Layer Extraction

func extractLayers(instanceID string) error {
    imageDir := filepath.Join("/var/lib/images", instanceID)
    rootfsDir := filepath.Join("/var/lib/containers", instanceID)
    
    // Read manifest
    manifest, _ := os.ReadFile(filepath.Join(imageDir, "manifest.json"))
    
    // Extract each layer
    for _, layer := range manifest.Layers {
        layerPath := filepath.Join(imageDir, layer)
        cmd := exec.Command("tar", "-xf", layerPath, "-C", rootfsDir)
        cmd.Run()
    }
    
    return nil
}

ENTRYPOINT/CMD Parsing

func parseImageConfig(instanceID string) ([]string, []string) {
    configPath := filepath.Join("/var/lib/images", instanceID, "config.json")
    
    var config ImageConfig
    data, _ := os.ReadFile(configPath)
    json.Unmarshal(data, &config)
    
    return config.Config.Entrypoint, config.Config.Cmd
}

Pool Management

Pod Selection

// internal/warmpool/client.go
func (c *Client) FindAvailablePod() (*Pod, error) {
    pods, err := c.listPods()
    if err != nil {
        return nil, err
    }
    
    for _, pod := range pods {
        if pod.Status == "available" {
            return &pod, nil
        }
    }
    
    return nil, ErrNoAvailablePods
}

func (c *Client) AssignPod(podID, instanceID string) error {
    return c.k8sClient.PatchPod(podID, map[string]interface{}{
        "metadata.labels": map[string]string{
            "instance-id": instanceID,
            "status":      "in-use",
        },
    })
}

State Reconciliation

The state reconciler ensures pool health:
// Runs in background
func (r *StateReconciler) Reconcile() {
    ticker := time.NewTicker(30 * time.Second)
    for range ticker.C {
        // Check pool size
        currentSize := r.countAvailablePods()
        if currentSize < r.targetSize {
            r.scaleUp(r.targetSize - currentSize)
        }
        
        // Clean up stale pods
        r.cleanupStalePods()
    }
}

Security Considerations

Warm pool pods run with privileged: true for chroot capability.

Security Measures

MeasureDescription
No Docker SocketUses Skopeo + direct execution, no Docker daemon
Namespace IsolationPods in dedicated Kubernetes namespace
RBACLimited permissions for activation service
Image VerificationOptional image signature verification
Network PoliciesRestrict pod network access

Best Practices

  1. Limit pool access - Only MCP Manager can activate pods
  2. Image allowlist - Restrict which images can be activated
  3. Resource limits - Set CPU/memory limits on activation pods
  4. Audit logging - Log all activation requests
  5. Regular rotation - Periodically recycle warm pods

Monitoring

Metrics

# Prometheus metrics
mcp_warmpool_available_pods{namespace="agentarea"} 8
mcp_warmpool_activation_duration_seconds{quantile="0.99"} 1.3
mcp_warmpool_activation_errors_total 3
mcp_warmpool_image_pull_duration_seconds{quantile="0.99"} 0.8

Health Checks

# Check warm pool status
kubectl get pods -n agentarea -l app=mcp-activation

# Check activation service health
kubectl exec -n agentarea mcp-warm-pool-xxx -- curl localhost:8080/health

Troubleshooting

Common Issues


Next Steps