# How Edge Routing and Load Balancing Work in Openship: OpenResty Proxy Architecture Explained

> Learn how Openship uses OpenResty edge routing and load balancing with NGINX upstream blocks to manage traffic and enforce policies effectively.

- Repository: [oblien/openship](https://github.com/oblien/openship)
- Tags: internals
- Published: 2026-07-21

---

**Openship routes traffic through a managed OpenResty edge proxy that atomically swaps routing rules stored in a Postgres-lite database, using NGINX upstream blocks to load-balance requests across multiple backend instances while enforcing rate-limits and access policies at the edge.**

Edge routing and load balancing in Openship are handled by a sophisticated proxy layer built on OpenResty. The `oblien/openship` repository implements this architecture using a combination of Lua-based routing logic, atomic configuration updates, and NGINX's native upstream mechanisms to ensure high availability and zero-downtime deployments.

## The OpenResty Edge Proxy Foundation

Openship deploys a customized **OpenResty** instance—an NGINX build extended with Lua scripting capabilities—to serve as the edge proxy. When requests arrive at free domains like `myapp.opsh.io`, the proxy executes Lua-based routing logic to determine traffic destination.

The edge proxy maintains an **edge routing table** that maps hostnames to upstream configurations. According to the source code in [`packages/adapters/src/runtime/oblien-routing.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/runtime/oblien-routing.ts), the system performs a `routes.set` operation to look up hostnames and atomically swap the entire rule set for that specific host. This atomic operation ensures that routing changes take effect instantaneously without serving stale configuration to incoming requests.

## Routing Metadata and Policy Storage

### Database Schema for Route Rules

All routing metadata persists in Openship's **Postgres-lite (PGLite)** database. The schema definitions in [`packages/db/src/schema/route-rule.ts`](https://github.com/oblien/openship/blob/main/packages/db/src/schema/route-rule.ts) define the structure for storing:

- Target hostnames and their associated upstream services
- Per-route policies including rate-limits, IP bans, and allow/deny lists
- Service discovery information for self-hosted containers, Vercel builds, or Cloud Run services

When a project is created or updated, Openship writes this metadata to the database before pushing changes to the edge proxy. The separation of policy storage from the proxy runtime allows the system to enforce security rules—such as blocking malicious IPs or throttling requests—directly at the edge before traffic reaches backend services.

## Atomic Route Updates with `routes.set`

The core runtime implementation in [`packages/adapters/src/runtime/oblien-routing.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/runtime/oblien-routing.ts) handles the critical task of updating live routing tables. Rather than incrementally modifying routes, the system uses an atomic `routes.set` operation that replaces the entire rule set for a given hostname in a single transaction.

This approach guarantees **zero-downtime deployments**. When a project is redeployed or a new version is released, the new routing configuration completely replaces the old one without intermediate states where partial rules might cause request failures. End-users experience seamless transitions between application versions because the edge proxy never serves a partially updated configuration.

## Upstream Load Balancing Mechanisms

Openship leverages NGINX's built-in upstream mechanisms to distribute traffic across multiple backend instances. For each project, the system creates an **upstream pool** containing reachable instances—whether self-hosted containers, serverless deployments, or external services.

The edge proxy distributes incoming requests using a **round-robin** strategy by default, though it supports any algorithm available in standard NGINX upstream configurations. This transparent load balancing occurs automatically once the routing table defines multiple upstream URLs for a single hostname, providing horizontal scalability without additional configuration layers.

## Edge Preflight and Port Management

Before applying routing tables, Openship must ensure exclusive control over standard HTTP ports. The **edge-preflight** module in [`packages/adapters/src/system/edge-preflight.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/system/edge-preflight.ts) performs critical system validation:

1. Probes ports 80 and 443 to detect existing listeners
2. Identifies conflicting processes that might own the edge ports
3. Executes "edge takeover" procedures to stop foreign owners when necessary
4. Verifies OpenResty instance readiness before accepting traffic

This preflight check prevents port conflicts and ensures that only the managed OpenResty instance handles incoming requests. The module confirms proxy ownership before the routing tables are applied, eliminating race conditions during system startup or recovery.

## Implementing Edge Routing in Practice

### Programmatic Route Configuration

You can define edge routes programmatically using the runtime adapter:

```typescript
import { setRoute } from '@openship/adapters/runtime';

// Define a route rule for myapp.opsh.io with load balancing
await setRoute('myapp.opsh.io', {
  upstreams: [
    { url: 'http://10.0.0.5:3000' },   // primary instance
    { url: 'http://10.0.0.6:3000' },   // secondary instance (load-balanced)
  ],
  policy: {
    rateLimit: { period: '1m', limit: 1000 },
    allow: ['192.168.0.0/16'],
  },
});

```

### CLI Deployment with Edge Sync

Trigger a full edge-routing synchronization after deployment using the CLI:

```bash
openship cli deploy --project myapp --sync-edge

```

The CLI internally invokes the same `setRoute` API and waits for the edge-preflight module to confirm the OpenResty proxy is active and ready to receive traffic.

## Summary

- **OpenResty edge proxy** handles all incoming traffic through Lua-based routing logic executing on a customized NGINX instance.
- **Postgres-lite (PGLite)** stores routing metadata and per-route policies including rate-limits, bans, and access control lists in [`packages/db/src/schema/route-rule.ts`](https://github.com/oblien/openship/blob/main/packages/db/src/schema/route-rule.ts).
- **Atomic updates** via `routes.set` in [`packages/adapters/src/runtime/oblien-routing.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/runtime/oblien-routing.ts) ensure zero-downtime deployments by swapping entire rule sets instantaneously.
- **NGINX upstream blocks** provide transparent load balancing across multiple backend instances using round-robin or other supported algorithms.
- **Edge-preflight** procedures in [`packages/adapters/src/system/edge-preflight.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/system/edge-preflight.ts) verify port ownership and resolve conflicts before activating routing tables.

## Frequently Asked Questions

### What database does Openship use for edge routing metadata?

Openship uses **Postgres-lite (PGLite)**, an embedded PostgreSQL implementation, to store routing configurations. The schema defined in [`packages/db/src/schema/route-rule.ts`](https://github.com/oblien/openship/blob/main/packages/db/src/schema/route-rule.ts) maintains records mapping hostnames to upstream services and enforcement policies like rate-limits and IP restrictions.

### How does Openship achieve zero-downtime deployments?

Openship implements **atomic route swapping** through the `routes.set` operation in [`packages/adapters/src/runtime/oblien-routing.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/runtime/oblien-routing.ts). Rather than incrementally updating routes, the system replaces the entire rule set for a hostname in a single operation, ensuring clients never receive partially updated configurations during deployments.

### What load balancing algorithms does Openship support?

Openship supports any algorithm available in standard **NGINX upstream** configurations. By default, the system uses **round-robin** distribution across the upstream pool members defined for each project, though administrators can configure alternative NGINX balancing methods depending on their specific requirements.

### How does Openship handle port conflicts on standard HTTP ports?

The **edge-preflight** module in [`packages/adapters/src/system/edge-preflight.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/system/edge-preflight.ts) actively probes ports 80 and 443 before startup. If another process owns these ports, the module executes an "edge takeover" procedure to stop conflicting services and verify OpenResty ownership, ensuring exclusive control over the edge proxy ports before routing tables are applied.