Serverless on Iron: Building High-Performance FaaS Architectures in a Post-Schrems II World
Let’s cut through the marketing noise immediately. "Serverless" is a lie. It has always been a lie. There are servers. There are always servers. The only difference is whether you control the kernel or if you are begging Amazon for 100ms of compute time on a shared node that’s currently being strangled by a noisy neighbor.
I have spent the last decade debugging distributed systems across the Nordics, and if there is one thing 2021 has taught us, it is that blindly trusting the hyperscalers with your data sovereignty is a dangerous game. Between the fallout of Schrems II and the sheer unpredictability of public cloud billing, the "pay-per-invocation" model often transforms from a dream into a financial nightmare at scale.
So, why are we talking about Serverless patterns on a VPS provider blog? Because the most robust, compliant, and cost-effective Serverless architecture right now isn't Lambda or Azure Functions. It is Self-Hosted FaaS (Function as a Service) running on dedicated kernel-based virtual machines.
We are going to look at how to architect this using the tools available today—Kubernetes (K3s), OpenFaaS, and high-performance NVMe storage—to keep your latency low and your data safely inside Norway.
The Latency Lie and the Norwegian Context
If your users are in Oslo, Bergen, or Trondheim, routing traffic to Frankfurt or Ireland for a "stateless function" is architectural malpractice. Light speed is finite. Physics does not care about your cloud provider's SLA.
When you deploy a function on a standard public cloud, you are often hitting a cold start penalty of 500ms to 2 seconds. Add network latency from Norway to Central Europe (approx. 25-35ms round trip), and your "instant" API is sluggish.
The alternative? Running your own FaaS platform on CoolVDS instances located directly in Norway. We strip away the virtualization overhead using KVM, and with local peering via NIX (Norwegian Internet Exchange), your latency drops to single-digit milliseconds.
Pattern 1: The "Iron-FaaS" Stack (K3s + OpenFaaS)
For production workloads in late 2021, you don't need the bloat of full K8s. We use K3s—a lightweight Kubernetes distribution—sitting on top of a Linux VPS. This gives us the orchestration we need without eating 4GB of RAM just for the control plane.
The Infrastructure Base
Start with a clean Debian 11 (Bullseye) or Ubuntu 20.04 LTS instance. Do not skimp on I/O. FaaS workloads are bursty; they hammer disk I/O when pulling container images for cold starts. This is why we standardize on NVMe at CoolVDS. Spinning rust is dead.
First, verify your kernel supports the necessary overlay drivers:
grep CONFIG_OVERLAY_FS /boot/config-$(uname -r)
If that returns y or m, you are good. Now, let's get K3s running. We disable Traefik by default because we want to handle ingress explicitly later.
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--no-deploy traefik" sh -
Deploying the Function Gateway
We will use OpenFaaS. It is battle-tested, works with any container, and doesn't lock you into a vendor's proprietary runtime. Install `arkade` to manage the apps:
curl -sLS https://get.arkade.dev | sudo sh
Now, deploy OpenFaaS to your local cluster:
arkade install openfaas
Pro Tip: By default, OpenFaaS might expose the gateway on a NodePort. In a production environment on CoolVDS, you should front this with Nginx or HAProxy bound to your public IP to handle SSL termination and rate limiting before traffic hits the cluster.
Pattern 2: The Async Worker Queue
One of the biggest mistakes developers make is treating FaaS as a synchronous HTTP request/response engine. It works, but it's fragile. The real power is in Async Patterns.
In this architecture, your VPS receives the request, acknowledges it instantly (HTTP 202), and pushes the payload into NATS (bundled with OpenFaaS). A worker function picks it up when resources allow. This prevents your server from melting under load spikes—something shared hosting can't handle.
Here is how you define a function stack that handles heavy image processing asynchronously. Note the `com.openfaas.scale.zero` label—this allows the pod to scale down to nothing when idle, saving your VPS resources for other tasks.
version: 1.0
provider:
name: openfaas
gateway: http://127.0.0.1:8080
functions:
image-resizer:
lang: python3-http
handler: ./image-resizer
image: registry.coolvds-client.no/image-resizer:latest
labels:
com.openfaas.scale.zero: true
com.openfaas.scale.zero.duration: 5m
annotations:
topic: "image-upload"
environment:
write_debug: true
read_timeout: 10s
write_timeout: 10s
To deploy this, you simply run:
faas-cli up -f stack.yml
Pattern 3: The Data Sovereignty Sidecar
Schrems II killed the Privacy Shield. If you are processing personal data of Norwegian citizens, sending that data to a US-owned cloud function (even one in a strictly EU region) is a compliance grey area that makes lawyers sweat.
By hosting the FaaS platform on a CoolVDS instance, you own the data path. But you still need persistent storage. We recommend mapping a host path directly to your function for high-speed database access, bypassing network storage latency entirely.
Here is a Python handler for a function that reads directly from a secure, local NVMe mount point, ensuring data never leaves the encrypted disk:
import os
def handle(req):
# Strict path checking to prevent directory traversal attacks
base_path = "/mnt/secure_storage/users/"
user_id = req.strip()
if ".." in user_id or "/" in user_id:
return "Invalid ID", 400
file_path = os.path.join(base_path, user_id, "profile.json")
if not os.path.exists(file_path):
return "User not found", 404
with open(file_path, 'r') as f:
data = f.read()
return data, 200
You would mount the volume in your Kubernetes deployment like this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-profile-reader
namespace: openfaas-fn
spec:
template:
spec:
containers:
- name: user-profile-reader
image: user-profile-reader:latest
volumeMounts:
- mountPath: /mnt/secure_storage
name: nvme-data
readOnly: true
volumes:
- name: nvme-data
hostPath:
path: /data/compliance_safe
type: Directory
Tuning for Performance: The CoolVDS Difference
Standard VPS providers often oversell CPU cycles. In a FaaS environment, "CPU Steal" is the enemy of latency. If your neighbor spins up a crypto miner, your function's cold start time triples.
We monitor this aggressively. On your instance, you can check your steal time using `vmstat`:
vmstat 1 5
Look at the st column. On CoolVDS, this should be consistently 0. If you see numbers climbing here on your current provider, you are paying for performance you aren't getting.
Furthermore, tuning the kernel for high-throughput network connections is mandatory for an API gateway. Add these to your /etc/sysctl.conf to handle the bursty nature of serverless traffic:
# Increase the range of ephemeral ports
net.ipv4.ip_local_port_range = 1024 65535
# Reuse connections in TIME_WAIT state
net.ipv4.tcp_tw_reuse = 1
# Increase max open files for Nginx gateway
fs.file-max = 2097152
Conclusion
Serverless is not about abandoning servers; it is about abstracting them intelligently. By deploying OpenFaaS on CoolVDS, you gain the developer experience of Lambda—git push deployments, auto-scaling, and event-driven triggers—without the latency penalties, vendor lock-in, or GDPR headaches of the public cloud.
You keep the data in Norway. You keep the latency low. You keep the costs predictable.
Ready to build your own Iron-FaaS platform? Don't let slow I/O kill your cold starts. Deploy a high-frequency NVMe instance on CoolVDS today and see what real raw performance feels like.