Escaping the Lambda Trap: Building a Private Serverless Architecture on KVM
Let’s clear the air: "Serverless" is a marketing term, not a technical reality. There are always servers. The only variable is whether you control the kernel or if you're renting execution time by the millisecond at a 400% markup. For many development teams in Oslo and across Europe, the initial allure of AWS Lambda or Azure Functions fades quickly when the first invoice arrives—or worse, when a critical function hits a 3-second cold start during a traffic spike.
As we navigate 2019, the trend is shifting back towards Pragmatic Sovereignty. We want the developer experience of "git push to deploy" without the vendor lock-in and data residency headaches that come with US-based hyperscalers. Especially with the Datatilsynet (Norwegian Data Protection Authority) tightening the screws on GDPR compliance, knowing exactly where your bits live—down to the physical rack in the datacenter—is no longer optional for serious enterprise architectures.
This guide explores how to build a private serverless implementation using OpenFaaS and Docker Swarm on CoolVDS infrastructure. This pattern gives you the scalability of FaaS (Function as a Service) with the raw I/O performance of dedicated NVMe storage.
The Architecture: Why "Roll Your Own" in 2019?
Public cloud FaaS is excellent for glue code. It is terrible for high-throughput, latency-sensitive compute. When you deploy on a managed FaaS platform, you are often sharing a hypervisor with thousands of other noisy tenants. You suffer from "Steal Time" (CPU cycles stolen by the hypervisor for other guests).
In a private setup on a CoolVDS instance, we utilize KVM (Kernel-based Virtual Machine). This provides strict isolation. Unlike OpenVZ or LXC, KVM allows us to run our own kernel and load specific modules required for heavy container orchestration. By placing a serverless framework like OpenFaaS on top of a high-performance VPS, we gain:
- Zero Cold Starts: We can keep containers warm without paying per-second penalties.
- Data Locality: Latency from an Oslo user to a CoolVDS instance in Norway is typically under 5ms. Round-tripping to Frankfurt or Ireland adds unnecessary friction.
- Cost Predictability: A fixed monthly fee for a VDS beats an uncapped variable bill.
Step 1: The Foundation (OS Tuning)
Before installing Docker, we must prep the OS. Default Linux distributions are tuned for general-purpose usage, not for the high packet rates associated with microservices. On a standard CentOS 7 or Ubuntu 18.04 LTS installation, you will hit file descriptor limits immediately under load.
Access your CoolVDS terminal via SSH. We need to tweak sysctl.conf to handle the network churn of ephemeral containers.
# /etc/sysctl.conf
# Increase the maximum number of open files
fs.file-max = 2097152
# Tuning the network stack for high concurrency
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_max_syn_backlog = 5000
# Reduce the time sockets stay in TIME_WAIT
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reuse = 1
# Increase port range for outgoing connections
net.ipv4.ip_local_port_range = 1024 65535
Apply these changes with sysctl -p. If you skip this, your API gateway will choke on 502 Bad Gateway errors the moment you hit 500 requests per second.
Step 2: Orchestration Layer
While Kubernetes is winning the container war, for a lean private serverless setup in 2019, Docker Swarm remains incredibly efficient. It uses less RAM than K8s, leaving more resources for your actual functions. Since CoolVDS offers pure KVM instances, Docker runs natively without virtualization hacks.
Initialize the Swarm on your primary node:
docker swarm init --advertise-addr $(hostname -i)
Pro Tip: When using CoolVDS, ensure your private networking interface is used for the advertise address if you are clustering multiple VDS instances. This keeps cluster traffic off the public internet and unmetered.
Step 3: Deploying OpenFaaS
OpenFaaS (Function as a Service) is the engine. It sits on top of Docker and manages the lifecycle of your functions. We will clone the official repository and deploy the stack.
git clone https://github.com/openfaas/faas
cd faas
./deploy_stack.sh
This script deploys the Gateway, Prometheus (for metrics), and NATS (for async messaging). Once deployed, you need to secure your gateway immediately. By default, it's open.
Step 4: The Performance Pattern - Async Processing
A common mistake is treating serverless functions like synchronous PHP scripts. In a robust architecture, you should offload work. For example, if you are processing image uploads (a common use case for our media clients), you don't want the user waiting for the resize operation.
Here is a Python 3 handler pattern for asynchronous processing using the OpenFaaS watchdog. Note the specific focus on memory efficiency.
import os
from PIL import Image
def handle(req):
"""
Handle a request to the function.
Input: Binary image data
Output: Status message
"""
# Write to /tmp which in Docker is usually an overlayfs or tmpfs
# On CoolVDS NVMe, disk I/O is negligible, so writing to disk is safe.
with open("/tmp/input.jpg", "wb") as f:
f.write(req)
try:
im = Image.open("/tmp/input.jpg")
im.thumbnail((128, 128))
im.save("/tmp/output.jpg", "JPEG")
# In a real scenario, push to S3 compatible storage (like Minio hosted on another VDS)
return "Resize success"
except Exception as e:
return str(e)
The configuration for this function in stack.yml is critical. We must set resource limits to prevent a single function from starving the node.
functions:
resize-image:
lang: python3
handler: ./resize-image
image: my-registry/resize-image:latest
environment:
write_debug: true
# Hard limits are essential for stability
limits:
memory: 128m
cpu: 0.2
requests:
memory: 64m
cpu: 0.1
Storage: The NVMe Difference
This is where infrastructure choice dictates architecture. In a public cloud, disk I/O is often throttled based on volume size. If you provision a small 20GB instance, you get paltry IOPS. This kills serverless performance because containers constantly pull layers and write logs.
CoolVDS instances utilize NVMe storage by default. During our benchmarks locally, we see read speeds exceeding 2000 MB/s on standard instances. This means:
- Docker Image Pulls: Near instant.
- Cold Starts: If a container does die, it respawns in milliseconds because the binary loads from disk immediately.
- Database: If you run a Redis cache sidecar, the persistence latency is non-existent.
Monitoring and Auto-Scaling
You cannot manage what you cannot measure. OpenFaaS comes with Prometheus built-in. We can configure auto-scaling rules based on requests_per_second. However, scaling requires overhead. If your VDS is already at 90% CPU, spawning more containers will only degrade performance.
We recommend a conservative scaling policy for production workloads in alert.rules:
groups:
- name: openfaas
rules:
- alert: APIHighInvocationRate
expr: rate(gateway_function_invocation_total{code="200"}[10s]) > 5
for: 5s
labels:
service: gateway
severity: major
annotations:
description: "High invocation rate on {{ $labels.function_name }}"
The Economic Reality
Let's look at the numbers. A typical medium-load microservices cluster on AWS (EC2 + ALB + NAT Gateway + Data Transfer) can easily run upwards of $300/month before you even account for Lambda execution costs.
| Feature | Public Cloud FaaS | Private FaaS on CoolVDS |
|---|---|---|
| Billing | Per request (Unpredictable) | Flat Monthly (Predictable) |
| Execution Time Limit | Max 15 min (usually less) | Unlimited |
| Data Sovereignty | US Jurisdiction (Cloud Act) | Norway (GDPR Compliant) |
| Storage Speed | Varies/Throttled | Dedicated NVMe |
Conclusion
Building a private serverless platform isn't about reinventing the wheel; it's about owning the car. For developers in the Nordic region, the combination of OpenFaaS and CoolVDS offers a sweet spot: the developer velocity of serverless with the raw power and legal safety of domestic infrastructure.
Don't let latency or legal concerns dictate your architecture. Take control of your stack.
Ready to deploy? Spin up a CoolVDS NVMe instance today and get your private FaaS gateway running in under 10 minutes. Your latency metrics will thank you.