---
url: https://docs.hostly.ninja/use-cases.md
---
# Use Cases and Examples

Most applications are more than a single website. A web app usually needs a database, maybe a cache or a queue, and often a worker that processes jobs in the background. In Hostly, each of these parts is its own [service](../concepts/service.md) in the same workspace.

This section shows which service configuration fits which part of an application, and walks through complete examples.

## Three kinds of services

Each service is defined by two decisions: does it get a **public domain**, and does it have a **port**?

| Kind | Public domain | Port | Reachable from |
|---|---|---|---|
| Public service | Hostly subdomain or custom domain | yes | the internet and other services of the workspace |
| Internal service | none ("Only reachable internally") | yes | other services of the workspace only |
| Service without port | none | none | nobody, it only connects outward |

## Typical use cases

### Websites, web apps, and APIs

Everything users or external clients open through a URL. Use a **public service** with SSL enabled.

Examples: a frontend, a REST or GraphQL API, a dashboard, a webhook receiver.

### Databases

Databases must never be reachable from the internet. Deploy them as an **internal service** with the database port and a volume for the data.

Examples: PostgreSQL (`5432`), MySQL or MariaDB (`3306`), MongoDB (`27017`).

::: warning Volumes are required for persistent data
Without a volume, all data written by the database is lost on every restart or redeployment. Volumes are only available on the paid tier. Do not enable high availability for a database: all three instances would share the same volume.
:::

### Caches and queues

Fast in-memory stores and message brokers that only your own services talk to. Use an **internal service** with the broker port.

Examples: Redis or Valkey (`6379`), RabbitMQ (`5672`), NATS (`4222`).

### Background workers

Processes that pick up jobs from a queue or database, send e-mails, generate reports, or sync data. Nobody connects to them, so they need **no port** and no public domain.

Examples: a queue consumer, a scheduler, a bot that connects to an external chat API.

### Internal APIs and microservices

Backends that only your public services call, e.g. an authentication service, a rendering service, or an AI model behind your own API. Use an **internal service** so the backend is not exposed directly.

## How services reach each other

Every service has a [service name](../concepts/service.md#service-name) that is unique within its workspace. Other services of the same workspace reach it at:

```text
<service-name>:<port>
```

For example, a database named `db` listening on `5432` is reachable at `db:5432`. Use this address in connection strings of other services:

```dotenv
DATABASE_URL=postgres://app:${DB_PASSWORD}@db:5432/app
```

* The address is shown on the service details page as **Internally reachable at**. The service list shows it for internal services.
* Any TCP protocol works internally, not just HTTP.
* Public services are reachable internally as well, at their service name and container port.
* Services of other workspaces cannot reach your services internally. Running several services in one workspace requires the paid tier, the free tier allows one service per workspace.
* Internal traffic is not encrypted by Hostly. It stays within your workspace's network.

## Examples

* [Web app with PostgreSQL](./web-app-with-postgres.md): a public web app and an internal database.
* [Background worker with a queue](./background-worker.md): a public app, an internal Redis queue, and a worker without port.
