Deploy Pike to Europe — C-like Scripted Web Backends on EU Infrastructure in 2026
Before Node.js. Before Python's WSGI ecosystem. Before PHP became the lingua franca of the web. There was a period in the mid-1990s when the European web was being built by a small number of people who had no industry playbook to follow, who had to invent the server software, the scripting layers, and the deployment models from scratch. One of those groups was at Roxen Internet Software in Linköping, Sweden — and the language they built to power their web server was Pike.
Pike is a general-purpose, object-oriented, dynamically typed language with C-like syntax, static type annotations, native POSIX threads, built-in async I/O, and a garbage collector. It was designed to be fast enough for production web serving, expressive enough for application development, and embeddable enough to serve as the extension language for a commercial web server that needed to run reliably under load. The Roxen web server — written entirely in Pike — served significant portions of the Nordic and European web throughout the late 1990s and 2000s.
Pike was created by Fredrik Hübinette 🇸🇪 (also known as "Mirar") at Linköping University in Sweden. It is maintained today by the Pike Foundation and Roxen Internet Software. It is an EU-origin language with an EU-infrastructure heritage — and it deploys on sota.io.
The Swedish Origin: Linköping and Roxen
Fredrik Hübinette 🇸🇪 — Swedish software engineer, alumnus of Linköping University — created Pike in the mid-1990s, initially as an evolution of LPC (the scripting language used in MUDs, Multi-User Dungeons), which he had worked on extensively. The goal was a language that combined the performance characteristics of C with the flexibility of a scripting language: dynamic typing, automatic memory management, a clean object model, and a runtime that could be embedded in applications.
Linköping University — Linköpings universitet, LiU — is one of Sweden's leading technical universities, known for its contributions to embedded systems, formal verification, and computer science. It produced, among others, the engineers behind significant contributions to the POSIX threading model, and it sits in Sweden's technology corridor between Stockholm and Gothenburg where Ericsson, SAAB Aerospace, and Swedish fintech have deep roots.
The key commercial application of Pike was the Roxen web server, built by Roxen Internet Software (later Roxen AB) based in Linköping. Roxen was not a hobby project. It was, at its peak, one of Europe's leading commercial web servers — deployed across Nordic media companies, Swedish government infrastructure, and international publishing organisations. Major Swedish newspapers, public broadcasters, and EU-adjacent media organisations ran their web presence on Roxen, and Roxen ran on Pike. This gives Pike a claim that few programming languages can match: it powered a substantial fraction of the European web before most of the modern web stack existed.
Martin Stjernholm 🇸🇪 — Swedish software engineer, long-time Pike core developer — contributed extensively to Pike's concurrency model, its garbage collector, and its runtime internals. His work on Pike's thread support — integrating POSIX pthreads with Pike's event loop and making them interact correctly with the garbage collector — established the foundation for Pike's use in multi-threaded production web serving. Sweden's engineering culture, shaped by POSIX standards work, Ericsson's real-time systems expertise, and a tradition of robust, maintainable systems software, is visible in Pike's design.
Pike's Technical Design
Pike is not a toy language. Its design reflects the requirements of production web serving in the 1990s, when server resources were scarce, concurrency was real, and correct behaviour under load was a commercial requirement, not an afterthought.
C-like syntax. Pike code reads like C or Java — curly braces, typed declarations, method calls. This is intentional: the language was designed to be accessible to developers coming from systems programming backgrounds. Pike's type system is dynamic but supports optional static type annotations, enabling early error detection without requiring full static typing.
Native POSIX threads. Pike includes full POSIX thread support, with Pike-level mutexes, condition variables, and atomic operations. Threads in Pike interact correctly with the garbage collector — a non-trivial implementation challenge that the Linköping team solved early. For EU backend services handling concurrent requests, native threads provide predictable performance without the callback pyramid of early Node.js.
Async I/O via Pike.Backend. Pike's Pike.Backend event loop provides asynchronous, non-blocking I/O — sockets, files, timers, and process events — with a callback model. The event loop can be combined with threads for a hybrid concurrency model: a thread pool serves I/O-bound tasks through the event loop while CPU-bound tasks run in dedicated threads. This architecture matches the requirements of EU web services handling both database queries and computational processing.
Built-in PostgreSQL support via Sql.pmod. Pike ships with a standard SQL module (Sql.pmod) that supports PostgreSQL, MySQL, and SQLite via native drivers. The PostgreSQL driver supports connection pooling, parameterised queries (preventing SQL injection), and result streaming. EU backend services typically use PostgreSQL — it is the open-source database of choice for GDPR-regulated workloads that require JSON support, full-text search, and transactional row-level security. Pike's built-in PostgreSQL support means there is no external ORM to audit for CRA compliance.
Module system. Pike uses a file-based module system (pmod files and directories) that allows code to be organised without a package manager. The standard library — Protocols.HTTP, Crypto, MIME, Calendar, ADT, String, Array, Mapping — covers the requirements of web backend development without external dependencies. Like Tcl and Erlang, Pike is designed to be self-sufficient: the standard library is the application toolkit.
Deploy Pike on sota.io
sota.io runs on Hetzner infrastructure in Germany. Data stays in the EU by default. GDPR compliance is structural, not configurable. Pike services deploy as Docker containers.
Prerequisites
- sota.io account (sign up at sota.io)
- Docker installed locally
- Pike 8.0 installed for local development (
pikefrom your distro or pike.lysator.liu.se)
Step 1 — Write a Pike HTTP service
Pike ships with Protocols.HTTP.Server for building HTTP services directly, or you can use Caudium (the Roxen-derived open-source web server written in Pike) for production deployments.
Simple HTTP server with Protocols.HTTP.Server:
#!/usr/bin/env pike
// EU-native Pike HTTP service for sota.io deployment
Protocols.HTTP.Server.Port server;
mapping(string:mixed) handle_request(Protocols.HTTP.Server.Request req) {
string path = req->not_query;
if (path == "/health") {
return ([
"error": 200,
"type": "application/json",
"data": "{\"status\":\"ok\",\"server\":\"sota.io\",\"region\":\"eu-central\"}",
]);
}
if (path == "/api/users") {
// Database query via Sql.pmod
Sql.Sql db = Sql.Sql(getenv("DATABASE_URL"));
array(mapping) rows = db->query(
"SELECT id, name, created_at FROM users ORDER BY created_at DESC LIMIT 10"
);
db->close();
string json = Standards.JSON.encode(rows);
return ([
"error": 200,
"type": "application/json",
"data": json,
]);
}
return ([
"error": 404,
"type": "text/plain",
"data": "Not found",
]);
}
int main() {
int port = (int)(getenv("PORT") || "8080");
server = Protocols.HTTP.Server.Port(handle_request, port);
write("Pike service running on port %d (EU infrastructure)\n", port);
return -1; // Run event loop indefinitely
}
Async HTTP with Pike.Backend event loop:
#!/usr/bin/env pike
// Non-blocking HTTP handler with async database access
Sql.Sql db;
void async_query(string user_id, function(array(mapping)) callback) {
// Pike supports async database operations via threads + callbacks
Thread.thread_create(lambda() {
array(mapping) result = db->query(
"SELECT id, name, email FROM users WHERE id = %s",
user_id
);
call_out(callback, 0, result);
});
}
mapping handle_user_request(Protocols.HTTP.Server.Request req) {
string user_id = req->variables["id"];
if (!user_id) {
return (["error": 400, "type": "application/json",
"data": "{\"error\":\"id parameter required\"}"]);
}
// Parameterised query: prevents SQL injection
array(mapping) rows = db->query(
"SELECT id, name, created_at FROM users WHERE id = %s",
user_id
);
if (!sizeof(rows)) {
return (["error": 404, "type": "application/json",
"data": "{\"error\":\"user not found\"}"]);
}
return ([
"error": 200,
"type": "application/json",
"data": Standards.JSON.encode(rows[0]),
]);
}
int main() {
db = Sql.Sql(getenv("DATABASE_URL"));
Protocols.HTTP.Server.Port(handle_user_request, 8080);
write("Pike async service on EU infrastructure\n");
return -1;
}
GDPR-compliant data erasure handler:
// GDPR Article 17: Right to erasure
// Pike's SQL module makes parameterised deletion straightforward
mapping handle_gdpr_erasure(Protocols.HTTP.Server.Request req) {
string user_id = req->variables["user_id"];
string request_id = Standards.UUID.make_version4()->str();
// Begin erasure transaction
db->query("BEGIN");
// Delete personal data across tables
db->query("DELETE FROM user_profiles WHERE user_id = %s", user_id);
db->query("DELETE FROM user_sessions WHERE user_id = %s", user_id);
db->query("UPDATE users SET email = %s, name = %s WHERE id = %s",
"deleted+" + request_id + "@erasure.local",
"Deleted User",
user_id
);
// Log erasure for GDPR Article 30 record-keeping
db->query(
"INSERT INTO gdpr_audit_log (action, user_id, request_id, performed_at) "
"VALUES ('erasure', %s, %s, NOW())",
user_id, request_id
);
db->query("COMMIT");
return ([
"error": 200,
"type": "application/json",
"data": Standards.JSON.encode(([
"status": "erased",
"request_id": request_id,
"timestamp": Calendar.now()->format_time(),
])),
]);
}
Step 2 — Containerise
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y \
pike8.0 \
pike8.0-dev \
pike8.0-extras \
libpq-dev \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY . .
# Pike's PostgreSQL module is included in pike8.0-extras
# Verify module availability
RUN pike -e "import Sql; write(\"PostgreSQL support: OK\n\");"
EXPOSE 8080
CMD ["pike", "server.pike"]
For production deployments using Caudium (the Roxen-derived web server):
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y \
caudium \
pike8.0 \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
COPY caudium-config/ /etc/caudium/
COPY pike-modules/ /var/lib/caudium/local/
EXPOSE 8080
CMD ["caudium", "--config-dir=/etc/caudium"]
Step 3 — Deploy to sota.io
# Install sota CLI
curl -sSL https://sota.io/install.sh | sh
# Initialise project
sota init
# Deploy — builds Docker image, pushes to EU registry, starts service
sota deploy
# Check status
sota status
Your Pike service is now running on Hetzner infrastructure in Germany. Traffic goes to your-project.sota.io over HTTPS automatically.
Step 4 — Connect PostgreSQL
# Provision managed PostgreSQL
sota postgres create --name pike-db
# Get the connection string
sota postgres env pike-db
In your Pike service, the DATABASE_URL environment variable is injected automatically. Pike's Sql.pmod connects directly:
// Pike's built-in SQL module — no external ORM
Sql.Sql db = Sql.Sql(getenv("DATABASE_URL"));
// Parameterised queries via sprintf-style placeholders
array(mapping) users = db->query(
"SELECT id, name, email, created_at FROM users WHERE active = %d LIMIT %d",
1, 10
);
// Iterate results as Pike mappings
foreach (users, mapping user) {
write("User %s (%s) — joined %s\n",
user->name, user->email, user->created_at);
}
db->close();
The managed PostgreSQL instance runs in the same Hetzner data centre as your Pike service — no cross-region data transfer, no US Cloud Act exposure for EU user data.
Roxen: The EU Web Before AWS
To understand why Pike matters for EU infrastructure, it helps to understand what Roxen was.
In the late 1990s, the commercial web hosting and serving landscape was dominated by Apache (open-source, US-developed) and a small number of commercial servers including Netscape Enterprise Server. Roxen Internet Software, based in Linköping, built an alternative: the Roxen Web Server, written entirely in Pike. Roxen was not a research project. It was a commercial product that competed directly with these established servers and won significant market share in Europe, particularly in the Nordic countries.
Roxen's advantages over Apache in that period were substantial: a tag-based server-side scripting system (RXML) that was more structured than CGI, built-in content management features, Pike-level programmability for custom modules, and a runtime that handled concurrency through Pike's thread model rather than Apache's process fork model. For European media companies — newspapers, public broadcasters, government portals — that needed content management integrated with web serving, Roxen provided a complete solution.
Major Swedish news organisations ran on Roxen. Swedish government web portals ran on Roxen. The Swedish company that became one of Europe's largest CMS vendors — Roxen AB — built its enterprise CMS product on Pike, and that product is still in use at European public institutions today. This is not a language that was used for hobby projects. It was used in production, at scale, for critical EU public information infrastructure.
The successor to Roxen's open-source codebase is Caudium — an actively maintained Pike-based web server that continues the Roxen architectural heritage. For EU teams deploying Pike services, Caudium provides a battle-tested HTTP serving layer with full Pike programmability.
Pike's EU Language Heritage
Pike inherits from a specific lineage of EU computer science:
Linköping University computer science tradition. LiU's computer science department has a strong tradition in type theory, functional programming, and formal methods. The concurrent programming work done at Linköping — including early contributions to POSIX thread semantics and the Ada tasking model — influenced Pike's threading design. Sweden's role in the POSIX standards process, through Ericsson and academic institutions, is visible in Pike's correct implementation of POSIX concurrency primitives.
LPC and the MUD tradition. Pike grew from LPC — the Language of the Persistent Craft — used in Lars Pensjö's LP-MUD system. Pensjö 🇸🇪 (Swedish, Chalmers University of Technology) developed LP-MUD in 1989, and the LPC language it used became the foundation for Fredrik Hübinette's Pike. The MUD lineage gave Pike its object-oriented design and its embeddability: LPC was always designed to run inside a larger system, not as a standalone runtime. This architectural DNA persists in Pike today — it remains an excellent embedding language for applications that need scripting.
Roxen Internet Software's engineering culture. The team at Roxen that built Pike and the Roxen web server applied Swedish engineering rigour — emphasis on correctness, minimal external dependencies, and long-term maintainability — to web server design. Pike's standard library reflects this: rather than deferring to external packages, the standard library provides cryptography (Crypto), encoding (MIME, Charset), protocols (Protocols.HTTP, Protocols.SMTP), data structures (ADT), and calendar handling (Calendar) out of the box.
Comparison: Pike vs Conventional Web Backends
| Feature | Pike on sota.io | Node.js on sota.io | Python/Flask on sota.io |
|---|---|---|---|
| Concurrency model | POSIX threads + event loop | Single-threaded async (libuv) | GIL threads / multiprocessing |
| Type system | Dynamic + optional static annotations | Dynamic (TypeScript optional) | Dynamic (type hints optional) |
| PostgreSQL support | Built-in Sql.pmod | pg / node-postgres (external) | psycopg2 (external) |
| External dependencies | Minimal (stdlib covers most needs) | npm ecosystem | pip ecosystem |
| Web serving | Built-in Protocols.HTTP.Server | express / fastify (external) | Flask/FastAPI (external) |
| GDPR jurisdiction | EU (Hetzner, Germany) | EU (Hetzner, Germany) | EU (Hetzner, Germany) |
| Origin | Sweden 🇸🇪 (EU) | USA 🇺🇸 | USA 🇺🇸 (Guido van Rossum, Dutch-born) |
| EU institutional use | Roxen web server (Nordic media/gov) | General | General/scientific |
GDPR and Pike Backends
GDPR compliance for Pike services on sota.io:
Data residency. All data processed by your Pike service stays in Hetzner's German data centres. No automatic replication to US regions, no US Cloud Act exposure.
Parameterised SQL by default. Pike's Sql.pmod enforces parameterised queries through its sprintf-style placeholder syntax (%s, %d). SQL injection through string concatenation is difficult to do accidentally in Pike — the module API steers developers toward the safe pattern.
Minimal external attack surface. A Pike service with no external package dependencies (using only the standard library and system libraries) has a dramatically smaller supply chain attack surface than a Node.js or Python application. For the EU Cyber Resilience Act's SBOM requirements, a Pike application's dependency graph is short.
Built-in cryptography. Pike's Crypto module provides HMAC, AES, RSA, and DSA implementations. EU services handling personal data under GDPR Article 32 (security of processing) require strong encryption. Pike's built-in crypto module eliminates the need for external cryptography dependencies and the key management complexity they introduce.
Calendar and timezone handling. Pike's Calendar module handles timezone-correct date and time operations — essential for EU services where data subjects in multiple timezones have GDPR rights that must be timestamped correctly. A consent record that says "user withdrew consent at 14:32" must be timestamped in the user's local timezone, not UTC, to be legally meaningful. Pike's Calendar module handles this correctly without external timezone libraries.
Why sota.io for Pike
EU infrastructure by default. Hetzner Germany. No US region fallback. GDPR data residency without configuration.
Managed PostgreSQL. Provisioned in the same data centre as your Pike service. Connection strings injected as environment variables. Backups, failover, and version upgrades managed.
Zero DevOps. Push code, sota deploy, done. No Kubernetes clusters to manage, no ingress controllers, no TLS certificate renewal scripts.
Docker-based deployment. Pike services deploy as Docker containers. The official Debian package (pike8.0) provides a reliable, auditable base image. Pike's minimal runtime footprint — no JVM, no Node runtime, just the Pike interpreter and its standard library — keeps container images small.
German company. No US legal jurisdiction. No Cloud Act exposure. Data processing agreements under GDPR Article 28 with a German data processor.
Pike is an EU-origin language with an EU-infrastructure heritage. Fredrik Hübinette 🇸🇪 created it at Linköping University, Roxen Internet Software 🇸🇪 built the European web on it, and Martin Stjernholm 🇸🇪 and the Pike Foundation maintain it today. Its built-in PostgreSQL support, POSIX threading model, async I/O event loop, and minimal external dependency footprint make it a serious choice for EU regulated backends that need correctness, auditability, and GDPR compliance by design. sota.io provides the EU infrastructure that Pike's Swedish engineering heritage deserves — running in Germany, GDPR-compliant by default, managed so your team focuses on the code.