Skip to content

Service Topology Diagram

Visualize your entire infrastructure at a glance with BRIDGEPORT’s interactive topology diagram — see which services talk to which databases, how traffic flows between components, and where everything runs.

The BRIDGEPORT dashboard showing the interactive service topology diagram, with servers, services, connections, and external entities

The topology diagram lives on your Dashboard page and renders an interactive, draggable graph of every service and database in the selected environment. Connections between nodes represent the data flows you define — a web app connecting to PostgreSQL on port 5432, an API server talking to Redis over TCP, a worker polling a message queue.

What the topology diagram shows:

  • Services grouped visually by the server they run on
  • Databases (both server-hosted and standalone)
  • User-defined connections with port, protocol, and direction metadata
  • Real-time status via color-coded nodes

What it does not show:

  • Automatic network-level discovery (connections are user-defined)
  • Cross-environment relationships (each environment has its own diagram)

You need at least one environment with services or databases already created. If you are starting from scratch, see Services and Databases first.

  1. Navigate to the Dashboard (click the BRIDGEPORT logo or go to /).
  2. Select your environment from the sidebar dropdown.
  3. Your services and databases appear as nodes, grouped by server.
  4. Click Add Connection to draw a line between two nodes.
  5. Drag nodes to arrange the layout — positions save automatically.

That is it. You now have a living architecture diagram that stays in sync with your infrastructure.


flowchart LR
    A[Services & Databases<br/>in environment] --> B[Topology Diagram<br/>renders nodes]
    B --> C[User creates<br/>connections]
    C --> D[ServiceConnection<br/>records saved]
    B --> E[User drags<br/>nodes]
    E --> F[DiagramLayout<br/>positions saved]
    F --> B
    D --> B

The diagram is composed of two data sources:

  1. Nodes come automatically from your existing services (grouped by server) and databases in the selected environment. You do not need to create nodes manually — they appear as soon as you add a service or database.

  2. Connections are user-defined ServiceConnection records that you create to represent the relationships between nodes. Each connection stores source, target, port, protocol, direction, and an optional label.

  3. Layout is stored as a DiagramLayout record per environment. When you drag nodes, the positions (x, y coordinates keyed by node ID) are persisted to the database so every team member sees the same arrangement.


You have two ways to create connections:

Drag-to-connect (fast path): Hover any service or database node; the colored dots on each side are connection handles. Drag from a handle and release on another node. The connection is saved with the default direction (forward) and no port/protocol metadata. To delete, click the X that appears on the manual (green) edge, or use the Connections list dropdown.

Add Connection modal (full control): Click the + button in the topology toolbar to open a form where you can pick source/target from dropdowns and fill in port, protocol, label, and direction. The connection appears immediately on the diagram.

PropertyTypeRequiredDescription
environmentIdstringYesThe environment this connection belongs to
sourceType"service", "database", or "external"YesWhat kind of node the connection starts from
sourceIdstringYesThe ID of the source service, database, or external entity
sourceHandlestringNoWhich handle on the source the user dragged from ("left", "right", "top", "bottom"). Used to preserve the exact anchor across reloads.
targetType"service", "database", or "external"YesWhat kind of node the connection goes to
targetIdstringYesThe ID of the target service, database, or external entity
targetHandlestringNoWhich handle on the target the user dropped onto
portintegerNoPort number (e.g., 5432, 6379, 443)
protocolstringNoProtocol label (e.g., tcp, http, grpc, amqp)
labelstringNoHuman-readable description shown on the edge
direction"forward" or "none"No (default: "none")Whether the edge has an arrow
Terminal window
curl -X POST https://your-bridgeport/api/connections \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"environmentId": "env_abc123",
"sourceType": "service",
"sourceId": "svc_web",
"targetType": "database",
"targetId": "db_postgres",
"port": 5432,
"protocol": "tcp",
"label": "Primary DB",
"direction": "forward"
}'

Expected response (201):

{
"id": "conn_xyz789",
"environmentId": "env_abc123",
"sourceType": "service",
"sourceId": "svc_web",
"targetType": "database",
"targetId": "db_postgres",
"port": 5432,
"protocol": "tcp",
"label": "Primary DB",
"direction": "forward",
"createdAt": "2026-02-25T10:00:00.000Z"
}
  • forward: Renders an arrow from source to target. Use this when data flows in a clear direction — a web app querying a database, or an API pushing to a message queue.
  • none: Renders an undirected line. Use this for bidirectional communication or when direction does not matter — two services that call each other, or a shared cache.

Not every node on your diagram is a server-hosted service. Inbound traffic often originates from systems you don’t run yourself — Cloudflare, a CDN, an external browser/client, or another company’s API. External entities model these on the canvas without pretending they’re services.

┌──────────────┐ ┌──────────────────────────────┐
│ Cloudflare │ ---> │ web-server-01 │
│ (external) │ │ ┌────────────┐ │
└──────────────┘ │ │ nginx │ │
│ └────────────┘ │
└──────────────────────────────┘
  • Click the globe icon in the topology toolbar to drop a new external entity onto the canvas. You’ll be prompted for a label (e.g. "Cloudflare") and a kind (e.g. cloudflare, cdn, web, client).
  • The kind drives the visual accent (Cloudflare/CDN → orange, Web/Client → cyan, anything else → slate).
  • Drag from any of the four handles to a service or database to represent inbound traffic. The connection is stored exactly like any other ServiceConnection, but with sourceType: "external".
  • Resize an external entity with the dashed corner handles when it’s selected.
  • Delete via the trash icon on the node (operator role required). Connections referencing the deleted entity are cleaned up automatically.

External entities live per-environment and persist their position and size across reloads.

MethodEndpointAuthDescription
GET/api/environments/:envId/external-entitiesAny roleList external entities for an environment
POST/api/environments/:envId/external-entitiesOperator+Create an external entity
PATCH/api/external-entities/:idOperator+Update label, kind, position, size
DELETE/api/external-entities/:idOperator+Delete the entity (cleans up referring connections)

When several servers belong together logically — an HA pair, a swarm or Kubernetes node set, or a regional grouping — you can wrap them in a cluster container. Clusters group servers visually and let you move or collapse them as a unit.

  • Click the stack icon in the topology toolbar to create a new cluster. You’ll be prompted for a name (e.g. "Production HA").
  • Open a server’s detail view and set its clusterId to the cluster’s ID (via PATCH /api/servers/:id). The diagram parents the server’s group inside the cluster on the next render.
  • Collapse a cluster from its header to fold all child servers into a single aggregate node. Edges from any child server reroute to the cluster while collapsed — a per-server collapse state inside a collapsed cluster is ignored (the cluster always wins).
  • Delete a cluster via its header trash icon. Member servers are not deleted — their clusterId is set to NULL so they re-emerge as standalone server groups.
MethodEndpointAuthDescription
GET/api/environments/:envId/server-clustersAny roleList clusters for an environment
POST/api/environments/:envId/server-clustersOperator+Create a cluster
PATCH/api/server-clusters/:idOperator+Update name, color, collapsed flag, position, size
DELETE/api/server-clusters/:idOperator+Delete the cluster (sets child Server.clusterId = NULL)
PATCH/api/servers/:idOperator+Set/clear clusterId on a server (pass null to disassociate)

Densely-populated server groups can become unreadable in a fixed-width box. To fix that, select a server box (click its border) — four resize handles appear on the corners. Drag them to enlarge the container so child services stay legible.

The new size persists in the diagram layout for everyone on the team, alongside the existing position data. Server boxes can’t be shrunk below the bounding box of their currently-laid-out children to avoid clipping. The same NodeResizer behavior is available on external entities and cluster containers.


When you drag a connection between two nodes, BRIDGEPORT now remembers the exact handle (anchor) you dragged from and dropped onto — not just “this node to that node”. This matters when:

  • You routed a connection from the bottom of a node to the top of another (vertical flow).
  • You want auto-inferred and manual edges to share consistent routing across reloads.

Each node exposes four handles — left, right, top, bottom — with stable IDs that are stored on the ServiceConnection row as sourceHandle and targetHandle. The Add Connection modal sets these to null (no specific anchor) so React Flow picks the shortest path; drag-to-connect captures the user’s exact anchor choice.


The top-right of the diagram canvas has a toolbar with several controls:

  • Add Connection (+) — opens the Create Connection modal. Same as the Dashboard-level button.
  • Add external entity (globe icon) — drops a new external, non-server entity on the canvas. See External Entities.
  • New cluster (stack icon) — creates a logical grouping of servers. See Server Clustering.
  • Connections list (chain-link icon) — opens a dropdown listing every manual connection in the environment with its source → target names. Hover a row to reveal a quick delete icon; the connection is removed without leaving the dashboard.
  • Layout controls — fit-to-view, reset layout, and export as Mermaid (see Exporting as Mermaid).

The connections dropdown is the fastest way to audit and prune stale links when a diagram has grown dense.

The topology diagram renders three types of nodes:

Node TypeVisualSource
ServiceNodeRounded rectangle with service name, status indicator, and exposed portEvery Service in the environment
DatabaseNodeCylinder shape with database name and portEvery Database in the environment
ServerGroupNodeContainer box that groups its child services (and databases hosted on it) — resizable when selectedEvery Server in the environment
ExternalEntityNodePill-shaped node with a globe icon, color-coded by kindEvery ExternalEntity in the environment
ServerClusterNodeDashed container that groups multiple server boxes; collapsibleEvery ServerCluster in the environment

Each node displays a color-coded status indicator:

  • Green: Running / Healthy
  • Yellow: Warning / Starting
  • Red: Stopped / Unhealthy / Error
  • Gray: Unknown / Not checked

Services are automatically grouped inside their parent server’s visual boundary. This gives you an immediate sense of which services are co-located.

┌─────────────────────────────────┐
│ web-server-01 │
│ ┌───────────┐ ┌───────────┐ │
│ │ nginx │ │ web-app │ │
│ │ :80 │ │ :3000 │ │
│ └───────────┘ └───────────┘ │
└─────────────────────────────────┘
│ │
▼ ▼
╔═══════╗ ┌───────────┐
║ Redis ║ │ api-01 │
║ :6379 ║ │ ┌─────┐ │
╚═══════╝ │ │ api │ │
│ └─────┘ │
└───────────┘

Databases that have a serverId appear inside that server’s group. Standalone databases (no server association) appear as independent nodes outside any group.

Every node on the diagram is draggable. When you release a node, BRIDGEPORT saves the new position to the database:

PUT /api/diagram-layout
{
"environmentId": "env_abc123",
"positions": {
"service:svc_web": { "x": 150, "y": 200 },
"service:svc_api": { "x": 400, "y": 200 },
"database:db_pg": { "x": 275, "y": 450 }
}
}

These positions are per-environment and shared across all users. If a teammate arranges the diagram, everyone sees the same layout on their next page load.

Click on any node to see a popover with quick details:

  • Service nodes: Container status, health status, image tag, server name, link to service detail page
  • Database nodes: Database type, connection info, monitoring status, link to database detail page

You can export the current topology as a Mermaid diagram for use in external documentation, wikis, or READMEs.

Terminal window
curl "https://your-bridgeport/api/diagram-export?environmentId=env_abc123&format=mermaid" \
-H "Authorization: Bearer $TOKEN"

Example response:

{
"mermaid": "graph TD\n subgraph web_server_01[\"web-server-01\"]\n svc_web[\"web-app (3000)\"]\n svc_nginx[\"nginx (80)\"]\n end\n subgraph api_server_01[\"api-server-01\"]\n svc_api[\"api (8080)\"]\n end\n db_postgres[(\"PostgreSQL (5432)\")]\n svc_web -->|Primary DB| db_postgres\n svc_api -->|Primary DB| db_postgres\n svc_nginx --> svc_web"
}

Paste the mermaid value into any Mermaid-compatible renderer (GitHub markdown, Notion, Confluence) and it renders automatically.


When a new engineer joins, point them at the Dashboard topology. In seconds they can see which services exist, where they run, and how they connect — without reading a 50-page architecture doc.

During an outage, the topology diagram shows unhealthy nodes in red. Follow the connections to trace upstream and downstream dependencies. “The API is red, and it connects to PostgreSQL which is also red — the database is the root cause.”

Export the topology as Mermaid and embed it in your project’s README or wiki. Since connections are maintained in BRIDGEPORT, the exported diagram stays up to date with a single API call.

Before migrating a database to a new server, check the topology to see which services connect to it. You will know exactly what needs updating.


MethodEndpointAuthDescription
GET/api/connections?environmentId=XAny roleList all connections in an environment
POST/api/connectionsOperator+Create a connection (sourceType/targetType may be service, database, or external)
DELETE/api/connections/:idOperator+Delete a connection
GET/api/diagram-layout?environmentId=XAny roleGet saved node positions (x, y, optional width, height)
PUT/api/diagram-layoutOperator+Save/update node positions (incl. resized width/height)
GET/api/diagram-export?environmentId=X&format=mermaidAny roleExport topology as Mermaid (services, databases, external entities)
GET/api/environments/:envId/external-entitiesAny roleList external entities
POST/api/environments/:envId/external-entitiesOperator+Create an external entity
PATCH/api/external-entities/:idOperator+Update an external entity
DELETE/api/external-entities/:idOperator+Delete an external entity (cleans up referring connections)
GET/api/environments/:envId/server-clustersAny roleList server clusters
POST/api/environments/:envId/server-clustersOperator+Create a server cluster
PATCH/api/server-clusters/:idOperator+Update a cluster (name, color, collapsed, position, size)
DELETE/api/server-clusters/:idOperator+Delete a cluster (members keep existing; clusterId set to NULL)
PATCH/api/servers/:idOperator+Includes clusterId (string or null) to attach/detach a server from a cluster

  • Make sure you have selected the correct environment in the sidebar dropdown.
  • Services only appear if they belong to a server in the current environment.
  • Databases only appear if they are associated with the current environment.

”A connection with this source, target, and port already exists” (409)

Section titled “”A connection with this source, target, and port already exists” (409)”

Connections are unique per environment + source + target + port combination. If you need multiple connections between the same two nodes, use different port numbers.

”Cannot create a connection from a node to itself” (400)

Section titled “”Cannot create a connection from a node to itself” (400)”

Self-connections are not allowed. If you need to represent a service connecting to itself (e.g., a recursive worker), consider using the label field on the service itself instead.

  • Check that you have the operator or admin role. Viewers can view the diagram but cannot modify layout positions.
  • Check the browser console for API errors. A 404 on the PUT endpoint usually means the environment ID is stale.
  • Ensure your Mermaid renderer supports subgraph syntax (most do since Mermaid 8.x).
  • Special characters in service/database names are escaped automatically, but extremely long names may cause layout issues in the rendered output.

  • Services — Managing the services that appear as nodes
  • Databases — Managing the databases that appear as nodes
  • Servers — Understanding server grouping
  • Deployment Plans — Orchestrating deployments across connected services
  • Monitoring Overview — Real-time health data shown on topology nodes