Skip to content

Private networking

Services in the same environment talk over a private network using stable internal hostnames. Traffic never goes over the public internet.

Every service and database you deploy is reachable by its name on the project’s private network. That hostname resolves to a stable ClusterIP address that is only accessible within the same project’s network. Traffic between services never leaves the cluster.

Private project network Internet HTTPS api :8080 private postgres :5432 cache :6379 Traffic stays on cluster fabric - no public egress between services

Public traffic hits your web service; app-to-database traffic uses internal service hostnames on the private fabric.

Internal hostname
[service-name]

The service name is the name you gave the service when creating it in the dashboard. Spaces are replaced with hyphens and the name is lowercased.

Examples
# Web API service named "api"
http://api:8080
# PostgreSQL database named "postgres"
postgresql://user:pass@postgres:5432/dbname
# Redis cache named "cache"
redis://:password@cache:6379
# Worker service named "background-worker"
http://background-worker:3000

The internal hostname resolves to whatever port(s) your service or database listens on:

  • Web services: the port defined in your service settings (default 8080)
  • PostgreSQL: 5432
  • MySQL: 3306
  • Redis: 6379
  • MongoDB: 27017

Internal requests don’t go through the public load balancer or the Ingress controller, they travel directly between pods over the cluster network. This means:

  • Lower latency (typically under 1ms within a region)
  • No TLS overhead required (traffic is private to the cluster)
  • No egress costs
  • No firewall rules to configure
api/src/jobs.ts
// Call a background worker service over the internal network
const response = await fetch('http://worker:3000/process', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ jobId: '123', payload: data }),
})
const result = await response.json()

Internal network access is not authenticated by default, any service in the same project can reach any other service by its internal hostname. If your services handle sensitive data, implement application-level authentication using a shared secret environment variable or mTLS.

Simple shared secret auth
// In your worker service, verify caller is legitimate
app.use('/internal', (req, res, next) => {
const secret = req.headers['x-internal-secret']
if (secret !== process.env.INTERNAL_API_SECRET) {
return res.status(403).json({ error: 'Forbidden' })
}
next()
})

The private network is scoped to a single project. Services in different projects cannot reach each other via internal hostnames.

If you need cross-project communication, the options are:

  • Public URL: call the service’s public stackblaze.app URL. Traffic goes through the load balancer and Ingress. Secure with API keys.
  • VPC peering (Enterprise): connect two projects over a private network without internet exposure. Contact support to configure.