> ## Documentation Index
> Fetch the complete documentation index at: https://docs.suga.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Networking

> Public and private networking for your applications

Suga provides two networking modes: **Private Networking** for internal service communication, and **Public Networking** for exposing services to the internet.

## Networking Overview

| Type             | Purpose                          | Configuration | Security          |
| ---------------- | -------------------------------- | ------------- | ----------------- |
| **Private**      | Service-to-service communication | Automatic     | Internal only     |
| **Public HTTPS** | Web traffic with TLS             | Port 443      | Automatic TLS     |
| **Public TCP**   | Non-HTTP protocols               | Custom port   | No TLS by default |

## Private Networking (Service Discovery)

All services in the same environment can communicate privately using automatic service discovery. Private traffic stays inside the environment and is never exposed to the internet.

### How It Works

**Automatic DNS:**

* Every service gets an internal hostname
* Internal DNS resolves service hostnames to addresses within the environment
* No manual configuration required

**Format:**

```
hostname:port
```

**Examples:**

* PostgreSQL: `postgres:5432`
* Redis: `redis:6379`
* API service: `api:3000`
* WebSocket server: `websocket:8080`

### Configuring Hostname and Ports

Each service has a **Private Networking** section in its **Config** tab where you can set:

* **Hostname**: the name other services use to reach this service. It starts as a DNS-safe version of the service's display name (lower case, with spaces and underscores turned into hyphens and other characters dropped), with a `-2` or `-3` suffix if that name is already taken. Override it to use a friendlier name like `postgres` or `api`. Hostnames must be unique within an environment.
* **Ports**: the ports this service listens on internally. Add every port you want reachable from other services in the same environment.

Public networking ports (HTTPS endpoints, TCP proxies, custom domains) are automatically reachable on the private hostname as well, so you don't need to list them twice.

### Connection Strings

Use service names in connection strings:

<CodeGroup>
  ```javascript Node.js theme={null}
  // PostgreSQL
  const connectionString = `postgresql://user:pass@postgres:5432/database`;

  // Redis
  const redisUrl = `redis://:password@redis:6379`;

  // HTTP API
  const apiUrl = `http://api:3000/endpoint`;
  ```

  ```python Python theme={null}
  # PostgreSQL
  DATABASE_URL = "postgresql://user:pass@postgres:5432/database"

  # Redis
  REDIS_URL = "redis://:password@redis:6379"

  # HTTP API
  API_URL = "http://api:3000/endpoint"
  ```

  ```go Go theme={null}
  // PostgreSQL
  connStr := "postgresql://user:pass@postgres:5432/database"

  // Redis
  redisAddr := "redis:6379"

  // HTTP API
  apiURL := "http://api:3000/endpoint"
  ```
</CodeGroup>

<Note>
  Private networking currently only works within the same environment. Services in "production" cannot reach services in "staging".
</Note>

## Public Networking

Public networking exposes services to the internet. Suga offers two modes: **HTTPS** and **TCP Proxy**.

### HTTPS Endpoints

HTTPS endpoints provide secure web access with automatic TLS certificates. All HTTPS traffic goes through Cloudflare's global CDN. See [CDN and Regions](/reference/cdn-and-regions) for the edge architecture and where requests get routed.

**Features:**

* Port 443 (HTTPS)
* Automatic TLS certificates via Cloudflare
* Cloudflare CDN, WAF, and DDoS protection
* Auto-generated domain names
* Traffic spread across replicas

**Auto-Generated Domains:**

Suga generates a domain for each HTTPS endpoint. It combines the service's ID, the environment name, and a label identifying the cluster your organization runs in.

Example:

```
https://k3f9x2mq7p1a-production-a1b2c3d4.us-central1.suga.run
```

The service ID is the short identifier Suga assigns, not the name you gave the service, so renaming a service does not change its generated address. The domain is fixed once the endpoint is created. You can change which port it serves, but not the address itself.

Because the address is assigned rather than chosen, avoid copying it into another service by hand. Reference it instead, so it stays correct if you add a custom domain later:

```bash theme={null}
API_URL=https://{{api.SUGA_PUBLIC_HOSTNAME}}
```

See [Environment Variables](/configure/environment-variables) for how references work, and [Custom Domains](/configure/custom-domains) to serve on your own domain instead.

**Configuration:**

<Steps>
  <Step title="Select Service">
    Click on the service you want to expose.
  </Step>

  <Step title="Open Config Tab">
    In the properties panel, open the **Config** tab.
  </Step>

  <Step title="Add the Generated URL">
    In the **Public Networking** section, click **Add** next to **Generated URL**. Specify the target port your application listens on (e.g., 3000, 8080). Public HTTPS traffic on port 443 routes to this port.
  </Step>

  <Step title="Apply">
    Click **Apply**. Your service will be accessible at the generated URL.
  </Step>
</Steps>

### TCP Proxy

TCP proxy exposes non-HTTP protocols to the internet.

**Use Cases:**

* Direct database access (PostgreSQL, MySQL)
* SSH connections
* Custom protocols (MQTT)
* Game servers

<Note>
  Standard `wss://` WebSockets go through the HTTPS path — see [WebSocket Support](#websocket-support). TCP Proxy is only needed for non-HTTP protocols.
</Note>

**Features:**

* Any TCP port
* Allocated load balancer port
* No automatic TLS (use application-level encryption)

**Configuration:**

<Steps>
  <Step title="Select Service">
    Click on the service to expose.
  </Step>

  <Step title="Open Config Tab">
    In the properties panel, open the **Config** tab.
  </Step>

  <Step title="Add TCP Proxy">
    In the **Public Networking** section, click **+ TCP Proxy**. Enter the port your application listens on (e.g., 5432 for PostgreSQL).
  </Step>

  <Step title="Apply">
    Click **Apply**. Note the allocated hostname and port in the **Public Networking** section.
  </Step>

  <Step title="Connect">
    Use the hostname and allocated port shown in the UI:

    ```
    psql -h proxy.us-central1.suga.run -p 46345 -U user
    ```
  </Step>
</Steps>

<Warning>
  TCP proxy does not provide TLS encryption by default. Use application-level encryption (like PostgreSQL's SSL mode) or consider keeping the service private.
</Warning>

## Connection Timeouts

Suga Cloud applies explicit, predictable timeouts to all public traffic so connection behaviour is consistent across deployments. These limits apply to traffic through public ingress (HTTPS endpoints and TCP Proxy) — private service-to-service connections inside an environment aren't subject to these idle timeouts.

| Timeout                | Applies To                       | Value         | What It Means                                                                                                                                        |
| ---------------------- | -------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Request header timeout | HTTPS endpoints (Free plan only) | 120 seconds   | Clients must finish sending HTTP request headers within 120 seconds of connecting. Protects shared edge infrastructure from slow or stalled clients. |
| Stream idle timeout    | HTTPS endpoints                  | 5 minutes     | An HTTP request, WebSocket, SSE stream, or long-polling response with no traffic in either direction for 5 minutes is closed.                        |
| TCP idle timeout       | HTTPS endpoints, TCP Proxy       | 15 minutes    | A TCP connection with no application data sent in either direction for 15 minutes is closed.                                                         |
| Dead-peer detection    | HTTPS endpoints, TCP Proxy       | \~2.5 minutes | Suga Cloud probes idle connections and closes any whose peer has gone away (network partition, crashed client, etc.) within roughly 2.5 minutes.     |

The stream idle, TCP idle, and dead-peer detection limits apply equally on every plan. The request header timeout applies to Free plan services only. See [Plan Limits](/reference/limits#free-tier-request-headers).

### Keeping Long-Lived Connections Alive

For long-lived connections — WebSockets, Server-Sent Events, persistent database connections via TCP Proxy — make sure the client or server emits traffic more often than the relevant idle timeout:

* **WebSockets:** send a ping frame every 1–2 minutes (well under the 5 minute stream idle timeout). Most WebSocket libraries can do this automatically.
* **Server-Sent Events:** emit a comment line (`: keepalive\n\n`) or heartbeat event every 1–2 minutes.
* **TCP Proxy (e.g. databases):** enable the keepalive your client supports, such as PostgreSQL `keepalives_idle`, or TCP-level `SO_KEEPALIVE` on the socket for clients without a protocol-level option. Otherwise expect to reconnect every 15 minutes.

<Note>
  Dead-peer detection and the TCP idle timeout are independent. Dead-peer detection only closes connections whose *peer* is gone — it does not reset the idle timer for healthy-but-quiet connections.
</Note>

## Load Balancing

For services with multiple replicas, Suga spreads traffic across replicas automatically. This applies to HTTPS endpoints, TCP proxies, and private service-to-service traffic. The distribution strategy is not configurable, and Suga does not guarantee a particular one, so don't rely on requests landing on a specific replica.

<Note>
  Load balancing is automatic. You don't need to configure it manually.
</Note>

## WebSocket Support

WebSockets work automatically with HTTPS endpoints:

**Setup:**

1. Configure your application to listen for WebSocket connections
2. Enable HTTPS on the service
3. Deploy
4. Connect using `wss://` (secure WebSocket)

<Note>
  Idle WebSockets are closed after 5 minutes. Have your client or server send a ping frame every 1–2 minutes to keep the connection open — see [Connection Timeouts](#connection-timeouts).
</Note>

**Example:**

```javascript theme={null}
// Client
const ws = new WebSocket('wss://k3f9x2mq7p1a-production-a1b2c3d4.us-central1.suga.run');

// Server (Node.js with ws library)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 3000 });

wss.on('connection', (ws) => {
  console.log('Client connected');
  ws.send('Welcome!');
});
```

## Server-Sent Events Support

Server-Sent Events (SSE) work automatically with HTTPS endpoints — no special configuration required.

**Setup:**

1. Configure your application to respond with `Content-Type: text/event-stream`
2. Enable HTTPS on the service
3. Deploy
4. Connect using `EventSource` from the client

<Note>
  Idle SSE streams are closed after 5 minutes. Emit a comment line (`: keepalive\n\n`) or heartbeat event every 1–2 minutes to keep the connection open. See [Connection Timeouts](#connection-timeouts).
</Note>

**Example:**

```javascript theme={null}
// Server (Node.js / Express)
app.get('/events', (req, res) => {
  res.set({
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
  });

  const heartbeat = setInterval(() => res.write(': keepalive\n\n'), 90_000);
  req.on('close', () => clearInterval(heartbeat));
});

// Client
const events = new EventSource('https://k3f9x2mq7p1a-production-a1b2c3d4.us-central1.suga.run/events');
events.onmessage = (e) => console.log(e.data);
```

## Network Isolation

Every environment runs inside its own isolated network boundary on Suga Cloud. Services in one environment cannot reach services in another over private networking, and the platform applies a default-deny security posture with explicit allow rules.

### Environment Boundaries

**Between Environments:**

* Services in different environments (production, staging, dev) cannot communicate privately, even within the same project
* Each environment has its own isolated network with its own private DNS
* For cross-environment communication, use public networking

**Between Projects:**

* Services in different projects cannot communicate privately
* Use public networking (HTTPS/TCP) for cross-project communication

<Note>
  Suga Cloud does not provision a dedicated VPC per project, and there is no cross-environment private routing. Environment isolation is enforced by network policy, not by separate networks.
</Note>

### Default-Deny Posture

Every environment starts with a default-deny policy and only the traffic listed below is permitted. Anything not explicitly allowed is dropped.

**Ingress (incoming connections to your services):**

| Source                                                              | Allowed                               |
| ------------------------------------------------------------------- | ------------------------------------- |
| Other services in the same environment                              | Yes                                   |
| Suga Cloud management traffic (TLS, ingress routing, health checks) | Yes                                   |
| Services in other environments or projects                          | No                                    |
| The public internet (direct)                                        | No. Must go through a public endpoint |

**Egress (outbound connections from your services):**

| Destination                                                                                           | Allowed |
| ----------------------------------------------------------------------------------------------------- | ------- |
| DNS resolution                                                                                        | Yes     |
| Other services in the same environment                                                                | Yes     |
| Public internet (any external API or service)                                                         | Yes     |
| Private IP ranges outside the environment (RFC 1918: `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`) | No      |
| Cloud provider metadata endpoints                                                                     | No      |

Blocking RFC 1918 ranges prevents services from reaching internal infrastructure they shouldn't see, including other tenants' private IPs. Blocking metadata endpoints prevents workloads from harvesting cloud credentials or instance identity from the underlying host.

### Public vs Private

* **Private networking** is internal-only and never exposed to the internet. It's the only way services in the same environment talk to each other privately.
* **Public networking** (HTTPS endpoints, TCP proxies, custom domains) requires explicit configuration on each service and routes through Suga's managed ingress with automatic TLS for HTTPS.

## Common Patterns

### Web Application

Frontend talks to backend, backend talks to database:

```mermaid theme={null}
graph LR
    frontend[Frontend<br/>Public] <-->|HTTPS| api[API<br/>Public]
    api <-->|Private| postgres[Postgres<br/>Private]
```

**Configuration:**

* `frontend`: HTTPS enabled (public)
* `api`: HTTPS enabled (public)
* `postgres`: No public networking (private only)
* `api` connects to `postgres` via `postgres:5432`

### Microservices

Multiple services communicate privately, one acts as public gateway:

```mermaid theme={null}
graph TD
    client[Client<br/>Public] <-->|HTTPS| gateway[Gateway<br/>Public]
    gateway <-->|Private| orders[Orders<br/>Private]
    gateway <-->|Private| users[Users<br/>Private]
    gateway <-->|Private| products[Products<br/>Private]
```

**Configuration:**

* `gateway`: HTTPS enabled (public)
* `users`, `orders`, `products`: No public networking (private only)
* Gateway connects to services via private networking

## Common Questions

<AccordionGroup>
  <Accordion title="Can I use a custom port for HTTPS?">
    No, HTTPS always uses port 443. You specify your container port (e.g., 3000), and Suga routes port 443 to your container port automatically.
  </Accordion>

  <Accordion title="Do I need to configure SSL certificates?">
    No, Suga automatically provisions and renews certificates for all HTTPS endpoints. Traffic from the client to Suga's gateway is encrypted, and TLS terminates at the gateway.
  </Accordion>

  <Accordion title="Can I expose a database publicly?">
    Yes, using TCP proxy. However, it's not recommended for security reasons. Keep databases private and access them via your application or a bastion host.
  </Accordion>

  <Accordion title="Can services in different projects communicate?">
    Not via private networking. Use public networking (HTTPS/TCP) or deploy related services in the same project.
  </Accordion>

  <Accordion title="How do I restrict access to public endpoints?">
    Currently, public endpoints are accessible by anyone. Implement authentication in your application. IP allowlisting is planned for a future release.
  </Accordion>
</AccordionGroup>
