Skip to content

Execution Backends

Flow-Like supports multiple execution backends, each with different isolation guarantees, performance characteristics, and use cases.

BackendIsolation LevelLatencyBest For
HTTP → Warm PoolProcessLowTrusted workloads, low latency
HTTP → LambdaMicroVM (Firecracker)MediumMulti-tenant SaaS
Lambda SDK InvokeMicroVM (Firecracker)MediumFire-and-forget batch
Lambda SDK StreamMicroVM (Firecracker)MediumStreaming from private Lambdas
Kubernetes JobPodHighUntrusted code, compliance
Docker ComposeContainerLowDevelopment, small deployments

AWS Lambda provides hardware-level isolation via Firecracker microVMs:

  • Each execution runs in its own microVM with hardware-level isolation
  • Memory is wiped between invocations from different tenants
  • No shared filesystem between executions
  • Cold starts create fresh environments
  • Warm starts reuse the same microVM for the same function only (not shared across tenants)

Invocation methods:

MethodDescriptionUse Case
HTTP (Function URL)HTTP POST to Lambda Function URLStreaming responses, simple setup
Lambda SDK InvokeAsync invocation via AWS SDKFire-and-forget batch jobs
Lambda SDK StreamStreaming invocation via AWS SDKStreaming from private Lambdas

Best for: Multi-tenant SaaS, untrusted workloads, pay-per-use pricing.

Kubernetes Warm Pool (HTTP → Deployment)

Section titled “Kubernetes Warm Pool (HTTP → Deployment)”

A pool of long-running executor pods handles requests:

┌─────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │Executor │ │Executor │ │Executor │ ← Warm Pool │
│ │ Pod 1 │ │ Pod 2 │ │ Pod 3 │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
│ └────────────┼────────────┘ │
│ │ │
│ ┌─────┴─────┐ │
│ │ Service │ ← Load balanced │
│ └───────────┘ │
└─────────────────────────────────────────────────────┘

Characteristics:

  • Process-level isolation: Each request runs in the same pod but can use separate processes
  • Shared resources: Pods handle multiple requests over their lifetime
  • Faster response: No cold start - pods are already running
  • Cost efficient: Fewer pod creations, better resource utilization

Security considerations:

Requests from different users may run on the same pod. This is suitable when:

  • Tenants are trusted (same organization)
  • Execution code is sandboxed (e.g., WASM, containers within pods)
  • Performance is prioritized over strict isolation

Best for: Internal/trusted workloads, low-latency requirements, cost optimization.

Kubernetes Isolated Job (Strongest K8s Isolation)

Section titled “Kubernetes Isolated Job (Strongest K8s Isolation)”

Each execution creates a dedicated Kubernetes Job:

┌─────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ Request 1 → ┌─────────┐ │
│ │ Job 1 │ ← Fresh pod │
│ │ Pod │ │
│ └─────────┘ │
│ │
│ Request 2 → ┌─────────┐ │
│ │ Job 2 │ ← Fresh pod │
│ │ Pod │ │
│ └─────────┘ │
│ │
│ Request 3 → ┌─────────┐ │
│ │ Job 3 │ ← Fresh pod │
│ │ Pod │ │
│ └─────────┘ │
└─────────────────────────────────────────────────────┘

Characteristics:

  • Pod-level isolation: Fresh pod for every execution
  • Resource guarantees: Dedicated CPU/memory per job
  • Clean environment: No state leakage between executions
  • Network policies: Can apply per-job network restrictions
  • Kata Containers: Optional hardware-level isolation via RuntimeClass
  • Slower startup: Pod scheduling + image pull overhead (mitigated with pre-pulled images)

Best for: Untrusted code execution, strict compliance requirements, resource-intensive workloads.

For local development and small deployments:

  • Container-level isolation: Each executor is a separate container
  • Shared host resources: Containers share the Docker host
  • Simpler setup: No orchestration complexity

Best for: Development, testing, small-scale deployments.

RequirementRecommended Backend
Multi-tenant SaaSLambda (strongest isolation)
Low latencyHTTP → Warm Pool (K8s/Lambda)
Untrusted codeKubernetes Job or Lambda
Batch processingLambda SDK Invoke (fire-and-forget)
Streaming responseHTTP or Lambda SDK Stream
Cost optimizationHTTP → Warm Pool
Compliance/auditKubernetes Job (per-job logging)
DevelopmentDocker Compose
BackendCold StartWarm Request
Warm Pool (K8s)N/A (always warm)~10-50ms
Lambda~100-500ms~10-50ms
Kubernetes Job~2-10sN/A (always cold)
BackendIdle CostPer-Request Cost
Warm PoolHigh (running pods)Low
LambdaNoneMedium (per-ms billing)
Kubernetes JobLow (no idle pods)High (pod overhead)
Terminal window
# Backend selection for streaming/sync requests (/invoke endpoints)
EXECUTION_BACKEND=http # http, lambda_invoke, lambda_stream, kubernetes_job
# Backend selection for async requests (/invoke/async endpoints)
ASYNC_EXECUTION_BACKEND=redis # http, redis, sqs, kafka
# HTTP backend (Warm Pool, Lambda Function URL, Azure, GCP)
EXECUTOR_URL=https://executor.example.com
# Lambda backends
LAMBDA_EXECUTOR_FUNCTION=arn:aws:lambda:us-east-1:123456789:function:executor
AWS_REGION=us-east-1
# Kubernetes Job backend
K8S_NAMESPACE=flow-like
K8S_EXECUTOR_IMAGE=ghcr.io/tm9657/flow-like-executor:latest

You can override the backend per-request via the API:

POST /apps/{app_id}/events/{event_id}/invoke
{
"payload": { ... },
"mode": "kubernetes_job",
"backend_config": {
"executor_url": "https://custom-executor.example.com"
}
}

Available modes:

  • local - Track only, no execution
  • http - HTTP POST to executor
  • lambda_invoke - AWS Lambda async invoke
  • lambda_stream - AWS Lambda streaming invoke
  • kubernetes_job - Isolated K8s Job

Use Lambda or Kubernetes Isolated Jobs with Kata Containers:

# Kubernetes Job with Kata runtime
spec:
template:
spec:
runtimeClassName: kata-qemu # Hardware isolation

Use Warm Pool for best performance:

# Kubernetes Deployment for warm pool
apiVersion: apps/v1
kind: Deployment
metadata:
name: executor-pool
spec:
replicas: 3
template:
spec:
containers:
- name: executor
resources:
requests:
memory: "512Mi"
cpu: "250m"

Apply network policies for Kubernetes backends:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: executor-isolation
spec:
podSelector:
matchLabels:
app: executor
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
name: flow-like