eqixiacEquinix Infrastructure as Code

Estate analysis New in 4.0

A read-only review of what an account already runs on Fabric, with priced findings and the evidence behind each.

Purpose#

Estate analysis reads the resources that an account already has (ports, connections, Cloud Routers, networks, service tokens and Network Edge devices) and reports which of them to resize, convert to a term, consolidate, remove or protect. Each finding carries its evidence and a monthly amount. The analysis makes no change to the account.

The package entered the tree in the week of 2026-11-12, and its API may change before 4.0.0 is published.

Run#

Java
import com.eqixiac.equinix.design.estate.EstateAnalyzer;
import com.eqixiac.equinix.design.estate.EstateFinding;
import com.eqixiac.equinix.design.estate.EstateReport;
import com.eqixiac.equinix.design.estate.EstateScope;

EstateReport report = EstateAnalyzer.builder(fabric)
    .networkEdge(networkEdge)                       // optional: include virtual devices
    .scope(EstateScope.projects(projectId))
    .window(Duration.ofDays(30))                    // utilization window
    .progress(System.err::println)
    .analyze();

for (EstateFinding finding : report.findings()) {
    System.out.println(finding.severity() + " " + finding.category() + ": " + finding.title());
    System.out.println("  action: " + finding.action());
    System.out.println("  impact: " + finding.impact() + ", confidence " + finding.confidence());
    finding.evidence().forEach(e -> System.out.println("  evidence: " + e));
    finding.assumptions().forEach(a -> System.out.println("  assumes: " + a));
}

Files.writeString(Path.of("estate-review.md"), report.toMarkdown());
Files.writeString(Path.of("estate-review.json"), report.toJson());

eq.design().analyzeEstate() returns the same builder on a session.

Scope#

EstateScope limits the resources that are read. A run without a scope on a large account sends one or more requests per resource, so most runs name a scope.

FactoryReads
EstateScope.projects(...)Resources in the named projects
EstateScope.accounts(...)Resources of the named billing accounts
EstateScope.resources(...)The named resource UUIDs
EstateScope.entireAccount(max)Everything the credential can see, up to max resources per type

The collector reads a bounded number of pages per resource type. It records each resource that it could not read in report.coverageGaps(), and report.notAnalysed() lists what the rules did not cover. The rules produce findings only from data that was read.

Utilization#

For each connection the analysis reduces the Fabric bandwidth metrics over the window to the median, the 95th percentile and the peak. A connection with fewer samples than the minimum, 24 by default, has unknown utilization and is not reported as idle.

Rules#

CategoryFindingDefault threshold
RIGHT_SIZE_DOWNThe 95th-percentile use is far below the provisioned bandwidthBelow 30%; the target is the smallest tier at or above the 95th percentile times 1.3
RIGHT_SIZE_UPThe 95th-percentile use is close to the provisioned bandwidthAbove 80%
ON_DEMAND_TO_TERMAn on-demand connection or Cloud Router, older than the minimum age, is cheaper on a contract termOlder than 90 days
CONSOLIDATE_BEHIND_ROUTERSeveral port-to-cloud connections in one metro could share a Cloud Router, or a router carries too little to justify itAt least 3 connections
IDLE_OR_UNUSEDA resource is held and not used, for example an active port with no connection
SINGLE_POINT_OF_FAILUREA cloud connection has no secondary in its redundancy group
CAPACITY_RISKA port's allocated bandwidth, or a Cloud Router's connection count, is near its limit
HYGIENEStuck or inconsistent resources, grouped as one finding per issue and resource kind

thresholds(EstateThresholds) changes the thresholds. addRule(EstateRule) adds a rule and rules(List) replaces the set.

Money#

Each finding carries a FinancialImpact priced through a rate card: the current monthly cost, the cost after the action, and the difference. The report totals the savings for each currency separately in addressableMonthlySaving() and lists the items it could not price in unpriced().

Two findings can address the same resource, for example a right-size and a term conversion on one connection. The savings of the two findings then overlap, and the sum over all findings exceeds the amount that can be saved. actions() returns the findings as an ordered list of actions.

Offline use#

Collection and analysis are separate steps, so an inventory can be collected once, stored, and analysed later without access to the API.

Java
import com.eqixiac.equinix.design.estate.EstateInventory;

EstateInventory inventory = EstateAnalyzer.builder(fabric)
    .scope(EstateScope.projects(projectId))
    .collect();

EstateReport offline = EstateAnalyzer.fromSnapshot(inventory).analyze();

The same rules applied to the same stored inventory give the same findings, which makes a review repeatable.

Limits#

  • The analysis takes prices from the rate-card chain. A live Equinix price is the list price for the account's region, and a contract rate is used only when it is supplied through a CustomRateCard.
  • Utilization is taken from the Fabric metrics API for the chosen window, so traffic outside the window, such as a batch job that ran before it, does not appear.
  • A right-size finding on a cloud connection does not check the provider side. An Azure ExpressRoute circuit, for example, cannot be reduced in place.
  • The analysis covers Fabric and, when a Network Edge client is supplied, Network Edge. It does not cover colocation space, power or cross connects.