Harthelm Docs
Guides

Services that need each other

Start order and readiness with needs.

Last updated 2026-10-19

A web front end calls an API, the API calls a database. With needs, Harthelm knows that, and starts, wakes and keeps them awake together.

Declare the needs

harthelm.yml
services:
  web:
    type: steps
    steps: [{run: npm start}]
    needs: [api]
    ports:
      - port: 3000
        routes: [{path: /}]
  api:
    type: steps
    steps: [{run: ./api}]
    needs: [db]
    ports:
      - port: 8080
        routes: [{path: /api, strip: true}]
    health:
      port: 8080
      path: /health
  db:
    type: managed
    provider: postgres
    secrets:
      password: ${{ secrets.DB_PASSWORD }}

needs lists services of the same file. Sync with the change.

What needs does

Start order. Before its first step, each replica waits up to 5 minutes for the started services it needs: until their health check passes, or, without one, until their first port answers. Then it starts anyway.

Wake. Waking a service wakes everything it needs, at the same time, and transitively: waking web wakes api. The first request waits until the services that are waking are ready.

Sleep. A service does not sleep while a service that needs it is awake: api stays up while web does.

The Run panel shows "needs api" on the row of web.

Managed and forward services

You can name managed and forward services in needs; they have nothing to wake, so naming them only documents the dependency. They cannot declare needs themselves.

When a need fails

A need that is already failing does not hold anything up:

  • Wake. The service wakes anyway, and the workspace list says "needs api, which is failing".
  • Run. A failing need is started again alongside the service, not waited for, and the Run panel says the same.

Requests still reach the service; it answers with its own error until the service it needs runs again. Find the cause in the need's Logs; see Debug a failing service.

How services reach each other

needs does not create addresses. Services call each other the usual ways:

  • Through the dev URL's paths, for example https://${{ workspace.devDomain }}/api in web's env.
  • Directly, as ws-<id>-<name>:<port>, for a service without routes.
  • A managed service through its templates: ${{ services.db.host }}, ${{ services.db.dsn }}.

Errors

CodeCause
unknown-needneeds names a service that is not in the file
needs-cyclethe needs lead back to the service, for example a needs b and b needs a

Both stop the Sync with the line and column; see harthelm.yml errors.

Next steps

On this page