Skip to main content

Telecom — network performance & capacity

The problem. Subscribers notice a degraded cell long before a threshold report does — dropped calls, stalling video, dead zones at rush hour. The network operations centre needs to spot a degrading or congesting cell and localize the cause, then see far enough ahead to add capacity before the busy hour turns into an outage. The catch: a cell's problem is often not in the cell at all, but in a backhaul link it shares with others.

What we solve here is finding and localizing degradation fast, and planning capacity before congestion bites.

Set up demo data​

New workspace? Run this once (Python) to create two cells' utilisation series (with busy-hour peaks) and the topology where they share a backhaul link — so the localisation in step 2 points at the link. Safe to re-run.

import intellistream_datahub_sdk, numpy as np, pandas as pd

client = intellistream_datahub_sdk.DataHubClient.from_env()

util = 50 + 40 * np.clip(np.sin(np.arange(168) / 24 * 2 * np.pi), 0, 1) # ~90% at busy hour
idx = pd.date_range(end=pd.Timestamp.now(tz="UTC"), periods=168, freq="1h")
for c in ["cell_oslo_4412", "cell_oslo_4418"]:
client.timeseries.create([intellistream_datahub_sdk.TimeSeries(external_id=f"{c}_prb_util", name=f"{c} PRB util", unit="pct", value_type="float")])
client.timeseries.insert_from_lists(timestamps=idx, values=util, ts=f"{c}_prb_util")

client.resources.create(
[intellistream_datahub_sdk.Resource(external_id=x, name=x, labels=[lbl]) for x, lbl in
[("cell_oslo_4412", "Cell"), ("cell_oslo_4418", "Cell"),
("backhaul_link_88", "BackhaulLink"), ("controller_rnc_3", "Controller")]],
[intellistream_datahub_sdk.RelForm.by_external_ids("cell_oslo_4412", "backhaul_link_88", "backhauled_by"),
intellistream_datahub_sdk.RelForm.by_external_ids("cell_oslo_4418", "backhaul_link_88", "backhauled_by"),
intellistream_datahub_sdk.RelForm.by_external_ids("backhaul_link_88", "controller_rnc_3", "connects_to")])

1. Find the busy-hour congestion​

Per-cell throughput, drop rate and active users are series. Aggregating to hourly peaks reveals which cells run hot at the busy hour — the capacity-planning shortlist. See Query & aggregate.

var filter = new RetrieveFilter();
filter.setExternalId("cell_oslo_4412_prb_util");
filter.setStart(ZonedDateTime.now().minusDays(7));
filter.setEnd(ZonedDateTime.now());
filter.setAggregates(List.of("max"));
filter.setGranularity("1h");

var request = new DataRetriever<RetrieveFilter>();
request.setItems(List.of(filter));

client.timeseries().retrieve(request).getItems().get(0).getDatapoints()
.forEach(p -> flagIfSaturated(p.getTimestamp(), p.getValue())); // PRB utilisation %

2. Localize a fault to shared backhaul​

When several cells degrade together, the common cause is usually a backhaul link or controller they share. Model cells → backhaul → controller as a graph and walk from each degraded cell to the element they have in common — the shared-dependency pattern, pointing the field team at the one link to fix instead of a dozen cells to chase.

ResourceNetwork c1 = client.resources().fetchRelated("cell_oslo_4412", 4);
ResourceNetwork c2 = client.resources().fetchRelated("cell_oslo_4418", 4);

Set<String> n1 = c1.nodes().stream().map(Resource::getExternalId).collect(Collectors.toSet());
Set<String> shared = c2.nodes().stream().map(Resource::getExternalId)
.filter(n1::contains).collect(Collectors.toSet());
// shared contains "backhaul_link_88" → fix the link, not the cells

See the result​

Busy-hour utilisation peaks near 90%, and the two degraded cells share one element:

backhaul_link_88 ← fix the link, not the dozen cells behind it

See also​