2026-03-31ยท9 min readยทsota.io team

Deploy Jolie to Europe โ€” Microservice-Native Choreographic Programming Hosting in 2026

Most programming languages were designed for programs. Jolie was designed for services.

The distinction matters. When you write a Node.js microservice, you are taking a general-purpose language and bolting service concepts on top: you import a framework, configure ports, define routes, wire middleware, and eventually โ€” somewhere in the scaffolding โ€” write the business logic. The service is an application; the language is a tool.

In Jolie, there is no distinction. Every Jolie program is a service. Communication ports, protocol negotiation, and interaction patterns are native language constructs โ€” as fundamental as functions or variables in other languages. You do not build a service in Jolie. You write Jolie, and what you have written is a service.

This is not a framework design choice. It is a language design choice, rooted in a decade of academic research at University of Southern Denmark (SDU) in Odense, the IT University of Copenhagen, and the University of Bologna โ€” a Scandinavian-Italian collaboration that produced one of the EU's most distinctive contributions to distributed systems theory.

This guide shows how to deploy Jolie microservice backends to EU infrastructure with sota.io.

The European Roots of Choreographic Programming

Jolie emerged from service-oriented computing research in the mid-2000s, when the EU academic community was grappling with a fundamental problem: how do you formally specify the behaviour of distributed systems where multiple services interact?

The prevailing answer was orchestration: one central coordinator tells all participants what to do. The alternative โ€” the one that Jolie's research group pursued โ€” was choreography: a global specification of who talks to whom, from which every participant's local behaviour can be derived automatically. This idea, called Choreographic Programming, became the theoretical foundation of Jolie.

Fabrizio Montesi ๐Ÿ‡ฎ๐Ÿ‡น (University of Southern Denmark, Odense) โ€” Full professor at SDU's Department of Mathematics and Computer Science, and the primary author and maintainer of Jolie since the language's founding. Montesi arrived in Denmark from Bologna and built Jolie into a complete service-oriented programming language while simultaneously developing choreographic programming as a formal theory. His PhD thesis (IT University of Copenhagen, 2013) โ€” Choreographies, Language, and Verification โ€” established choreographic programming as a rigorous programming language theory. He has since published foundational work on choreographic programming languages, session types, and microservice composition at POPL, LICS, and CONCUR. Montesi holds an ERC Starting Grant (European Research Council) for choreographic programming research โ€” one of the EU's most competitive individual research awards.

Claudio Guidi ๐Ÿ‡ฎ๐Ÿ‡น (IT University of Copenhagen โ†’ independent) โ€” Co-creator of Jolie during his PhD at the IT University of Copenhagen. Guidi designed the original Jolie language semantics and the SOCK (Service-Oriented Computing Kernel) process calculus that gives Jolie its formal foundation. SOCK formalises the primitive operations of service interaction โ€” request-response, one-way notifications, port binding โ€” as a calculus analogous to the ฯ€-calculus for concurrent systems. Guidi's work established the theoretical core that distinguishes Jolie from ad hoc microservice frameworks.

Ivan Lanese ๐Ÿ‡ฎ๐Ÿ‡น (University of Bologna) โ€” Associate professor at Bologna's Department of Computer Science and Engineering, and one of Jolie's earliest contributors. Lanese's research focuses on reversible computation and choreographic programming; his joint work with Montesi on session-based choreographies has been fundamental to the language's semantics. Bologna is one of Europe's oldest universities and a centre of formal methods research โ€” the EU provenance of Jolie's theoretical foundations runs deep.

The EU research lineage. Jolie's development has been supported by Danish Research Council grants, EU Horizon projects on service computing, and Montesi's ERC Starting Grant. The language is not a corporate product or a solo hobbyist project โ€” it is the output of sustained European academic funding, reviewed against the standards of formal programming language theory.

What Makes Jolie Different

Jolie's premise is that microservice concepts should be first-class language constructs, not library choices. Understanding what this means in practice reveals why Jolie occupies a unique position in the European distributed systems landscape.

Ports and protocols as language syntax:

In Jolie, communication endpoints are declared with the inputPort and outputPort keywords โ€” not imported from a library, not configured in YAML, not wired in a framework. They are part of the program's syntax.

// A Jolie service exposes an HTTP port โ€” no framework required
inputPort MyService {
  location: "socket://localhost:8080"
  protocol: http {
    format = "json"
  }
  interfaces: MyInterface
}

The protocol is part of the port declaration. The same service can expose multiple ports with different protocols simultaneously:

// Expose HTTP for web clients and a binary protocol for internal microservices
inputPort WebPort {
  location: "socket://localhost:8080"
  protocol: http { format = "json" }
  interfaces: MyInterface
}

inputPort InternalPort {
  location: "socket://localhost:9090"
  protocol: sodep   // Jolie's native binary protocol
  interfaces: MyInterface
}

This is not configuration. This is code. The protocol is type-checked against the interface at compile time.

Interface definitions โ€” the contract:

Jolie interfaces define operations with their request and response types. The same interface can be implemented by different services and consumed by different clients, independently of protocol:

type OrderRequest: void {
  .orderId: string
  .userId: string
  .items[1,*]: void {
    .productId: string
    .quantity: int
  }
}

type OrderResponse: void {
  .success: bool
  .message?: string
  .totalEur?: double
}

interface OrderInterface {
  RequestResponse:
    placeOrder(OrderRequest)(OrderResponse),
    getOrder(string)(OrderResponse)
  OneWay:
    cancelOrder(string)
}

Types in Jolie are structural โ€” the type tree reflects the message structure, and nesting is explicit. The ? suffix marks optional fields; [1,*] marks arrays with at least one element.

Behaviour โ€” the service logic:

service OrderService {
  inputPort OrderPort {
    location: "socket://localhost:8080"
    protocol: http { format = "json" }
    interfaces: OrderInterface
  }

  // Connect to downstream inventory microservice
  outputPort InventoryService {
    location: "socket://inventory:9090"
    protocol: sodep
    interfaces: InventoryInterface
  }

  main {
    // Request-response handler โ€” the pattern is the syntax
    [placeOrder(request)(response) {
      // Check inventory โ€” calling another Jolie microservice
      checkStock@InventoryService({
        .productIds = request.items[*].productId
      })(stockResponse)

      if (stockResponse.available) {
        response.success = true
        response.totalEur = computeTotal(request.items)
        response.message = "Order placed"
      } else {
        response.success = false
        response.message = "Item out of stock"
      }
    }]

    [getOrder(orderId)(response) {
      // Retrieve from storage
      response.success = true
    }]

    [cancelOrder(orderId) {
      // One-way โ€” no response
      println@Console("Cancelled: " + orderId)()
    }]
  }
}

The [operation(request)(response) { ... }] syntax is not function definition โ€” it is behaviour declaration. Jolie's execution model is session-based: each incoming request opens a session, the behaviour block executes, and the response is sent. Concurrency between sessions is handled automatically by the Jolie runtime.

Aggregation and embedding โ€” microservice composition:

Jolie's killer feature for microservice architectures is aggregation: one Jolie service can re-expose the interfaces of another service, acting as a gateway or proxy without code:

// API gateway that aggregates three backend services
inputPort APIGateway {
  location: "socket://0.0.0.0:80"
  protocol: http { format = "json" }
  aggregates: OrderService, UserService, InventoryService
}

This single declaration creates an HTTP gateway that routes requests to the appropriate backend service based on interface matching. No routing code. No middleware. The composition is structural.

Building a Complete Microservice

A complete Jolie microservice for deployment on sota.io:

Project structure:

my-jolie-service/
โ”œโ”€โ”€ service.ol          # Main Jolie service
โ”œโ”€โ”€ types.iol           # Shared type definitions
โ”œโ”€โ”€ Dockerfile
โ””โ”€โ”€ .gitignore

types.iol:

type HealthRequest: void
type HealthResponse: void {
  .status: string
  .lang: string
  .version: string
}

type MessageRequest: void {
  .text: string
}

type MessageResponse: void {
  .reply: string
  .processedAt: string
}

interface AppInterface {
  RequestResponse:
    health(HealthRequest)(HealthResponse),
    process(MessageRequest)(MessageResponse)
}

service.ol:

include "types.iol"
include "time.iol"
include "string_utils.iol"

service MyApp {
  inputPort AppPort {
    location: "socket://0.0.0.0:8080"
    protocol: http {
      format = "json"
      .osc.health.method = "get"
      .osc.process.method = "post"
    }
    interfaces: AppInterface
  }

  main {
    [health(request)(response) {
      response.status = "ok"
      response.lang = "jolie"
      response.version = "1.10"
    }]

    [process(request)(response) {
      // String operations using Jolie standard library
      toUpperCase@StringUtils(request.text)(upper)
      getCurrentTimeMillis@Time(void)(ts)
      response.reply = "Processed: " + upper
      response.processedAt = string(ts)
    }]
  }
}

Dockerfile:

FROM openjdk:21-slim AS base

# Install Jolie from official distribution
RUN apt-get update && apt-get install -y wget unzip && \
    wget -q https://github.com/jolie/jolie/releases/download/v1.10.4/jolie-1.10.4.zip && \
    unzip -q jolie-1.10.4.zip -d /opt && \
    rm jolie-1.10.4.zip && \
    apt-get clean

ENV JOLIE_HOME=/opt/jolie-1.10.4
ENV PATH=$JOLIE_HOME/bin:$PATH

WORKDIR /app
COPY . .

EXPOSE 8080
CMD ["jolie", "service.ol"]

Deploy on sota.io:

# Install sota CLI
curl -fsSL https://sota.io/install.sh | sh

# Deploy from Dockerfile
sota deploy --port 8080

# Add custom domain
sota domains add jolie.yourdomain.eu

# Set environment variables
sota env set DATABASE_URL=postgresql://...

Your Jolie microservice is live on EU infrastructure in Frankfurt โ€” GDPR-compliant, isolated, with managed PostgreSQL available on demand.

Orchestrating Multiple Jolie Services

One of Jolie's strongest deployment patterns is the orchestrator: a Jolie service that calls other Jolie services in sequence or parallel.

include "types.iol"

service OrderOrchestrator {
  inputPort OrchestratorPort {
    location: "socket://0.0.0.0:8080"
    protocol: http { format = "json" }
    interfaces: OrderOrchestratorInterface
  }

  // Downstream Jolie microservices
  outputPort UserService {
    location: "socket://user-service:9001"
    protocol: sodep
    interfaces: UserInterface
  }

  outputPort InventoryService {
    location: "socket://inventory-service:9002"
    protocol: sodep
    interfaces: InventoryInterface
  }

  outputPort PaymentService {
    location: "socket://payment-service:9003"
    protocol: sodep
    interfaces: PaymentInterface
  }

  main {
    [checkout(request)(response) {
      // Parallel calls to user and inventory services
      // Jolie handles concurrency between sessions automatically
      getUser@UserService({ .userId = request.userId })(user)
      checkStock@InventoryService({ .items = request.items })(stock)

      if (stock.available && user.creditLimit >= request.totalEur) {
        // Sequential payment
        charge@PaymentService({
          .userId = request.userId
          .amountEur = request.totalEur
        })(payment)
        response.success = payment.charged
        response.orderId = payment.transactionId
      } else {
        response.success = false
        response.reason = "Insufficient stock or credit"
      }
    }]
  }
}

Parallel execution of independent service calls (getUser and checkStock) is handled by Jolie's session concurrency model โ€” no async/await, no Promise.all, no goroutines. The language runtime manages it.

Why EU Teams Use Jolie

Microservices without framework tax. Every microservice framework โ€” Express, FastAPI, Spring Boot โ€” adds a learning curve, version management burden, and a layer of abstraction between your business logic and the network. Jolie eliminates the layer. The service definition is the program. For EU teams building distributed systems where protocol correctness matters, removing the framework-business-logic gap reduces integration bugs.

Choreographic programming for distributed system correctness. Montesi's choreographic programming theory, supported by his ERC grant, gives Jolie a formal foundation for specifying how distributed services interact. Choreographies guarantee communication safety โ€” if a choreography compiles, every service knows exactly which messages to send and receive, and deadlocks due to mismatched interactions are ruled out at the design level. For EU financial services, healthcare systems, and public sector platforms where distributed correctness is a compliance requirement, this is a meaningful property.

Protocol flexibility for heterogeneous EU environments. EU enterprise landscapes often combine modern REST APIs with legacy SOAP services, internal binary protocols, and vendor-specific interfaces. Jolie speaks all of them from the same codebase. A single Jolie service can consume a SOAP endpoint from a German SAP installation, re-expose it via JSON/HTTP to a React frontend, and forward events to an internal Jolie binary-protocol service โ€” without protocol conversion middleware.

Academic adoption in EU CS programmes. Jolie is used for teaching distributed systems and service-oriented programming at the University of Southern Denmark, the IT University of Copenhagen, and several Italian universities. EU researchers building distributed systems tools and runtime environments have used Jolie as a reference implementation. For teams hiring from Danish and Italian CS programmes, Jolie familiarity is a realistic expectation.

ERC-funded active development. Montesi's ERC Starting Grant funds ongoing Jolie development and choreographic programming research. The language is actively maintained, the team is reachable (GitHub, Jolie community forums), and the research pipeline feeds directly into language improvements. For EU organisations evaluating language maturity, an ERC-funded professor at a major Danish university is a credible maintenance guarantee.

Formal service composition without code generation. Jolie's aggregates and courier constructs allow structural service composition โ€” routing, filtering, and re-exposing service interfaces โ€” without generating stub code or running separate API gateway processes. For EU API gateway deployments where traffic volume or compliance requirements make third-party API management products expensive, a Jolie-based gateway is a native alternative.

Practical Considerations

JVM runtime. Jolie runs on the JVM (Java 11+). Startup time is JVM startup time โ€” fast enough for container workloads, but not sub-millisecond. For applications where cold-start latency matters (serverless, short-lived jobs), plan for the JVM warm-up period.

Ecosystem scope. Jolie's standard library covers HTTP, SOAP, binary protocols, file I/O, JSON/XML processing, and common utilities. For specialised domain libraries (ML frameworks, database-specific clients), you will call Java or JavaScript libraries via Jolie's embedding mechanism (JavaService or embedding Jolie in). The ecosystem is narrower than Python or Node.js โ€” evaluate your library requirements before committing.

Community size. Jolie is a university-research-origin language with a small but engaged community. The GitHub repository is active, the mailing list responsive, and Montesi's group publishes regular updates. For production deployments, factor in that community support will be primarily academic rather than StackOverflow-scale.

When Jolie is the right choice:

Deploy on EU Infrastructure

sota.io runs on servers in Germany (Frankfurt) and other EU data centres. All data stays within EU jurisdiction, GDPR compliance is structural, and every deployment is isolated by default.

Get started:

# Install sota CLI
curl -fsSL https://sota.io/install.sh | sh

# Log in
sota login

# Deploy from Dockerfile
sota deploy --port 8080

# Custom domain
sota domains add jolie.yourdomain.eu

Microservice-native. Choreography-correct. Hosted in Europe.

European Connections Summary

WhoInstitutionContribution
Fabrizio Montesi ๐Ÿ‡ฎ๐Ÿ‡นUniversity of Southern Denmark (SDU), OdenseJolie language creator, choreographic programming theory, ERC Starting Grant
Claudio Guidi ๐Ÿ‡ฎ๐Ÿ‡นIT University of CopenhagenJolie co-creator, SOCK process calculus
Ivan Lanese ๐Ÿ‡ฎ๐Ÿ‡นUniversity of BolognaJolie contributor, choreographic programming semantics
IT University of Copenhagen ๐Ÿ‡ฉ๐Ÿ‡ฐCopenhagenJolie birthplace (Guidi's PhD, early development)
University of Southern Denmark ๐Ÿ‡ฉ๐Ÿ‡ฐOdenseJolie's current research home, active development
University of Bologna ๐Ÿ‡ฎ๐Ÿ‡นBolognaFormal methods research, choreography theory
European Research CouncilEUERC Starting Grant for choreographic programming (Montesi)

Jolie is the output of Scandinavian-Italian academic collaboration โ€” Danish institutional support, Italian formal methods expertise, and EU research funding โ€” producing a language that treats microservice architecture not as a deployment pattern but as a programming model.


sota.io is EU-native infrastructure for backend services. Deploy your Jolie microservice application to German servers in minutes โ€” GDPR-compliant, managed PostgreSQL, custom domains included.