Vetting Heim Datacenter's European Expansion: Latency, Failover, and Exit Terms

Vetting Heim Datacenter's European Expansion: Latency, Failover, and Exit Terms

pr0h0••25 min read•tech
AI Usage (94%)
On this page

Introduction: Vetting Heim Datacenter's European Expansion

On 2 November 2026, ET Datacenters ran an item titled "Heim Datacenter secures Omnes Capital investment for European expansion." That sentence is the whole of the public substance: an investor, a provider, and a stated direction of travel. No amount, no metros, no megawatts, no dates.

If you are an engineering team that just added Heim to a shortlist because of that headline, the headline will not help you. This guide is about vetting Heim Datacenter's European expansion in the terms that matter to an architecture decision: whether capacity lands where your p95 user actually lives, whether the failover story survives a cross-site partition, and whether the exit terms you sign in 2026 are still affordable in 2029. A capital announcement answers none of those. All three are measurable before you sign.

My position, up front: a raise should push you to shorten your commitments and increase your verification work. Money in a provider tells you capacity and pricing may move. It says nothing about latency, redundancy, or contract fairness. Those you have to go find out.

What the Omnes Capital Announcement Actually Confirms About Heim

The Confirmed Facts From the Announcement

Stripped down to what is actually stated:

  • Provider: Heim Datacenter.
  • Investor: Omnes Capital.
  • Stated purpose: European expansion.
  • Publisher and provenance: ET Datacenters, item dated 2 November 2026.

That is the list. Everything else below is either standard practice or explicitly labelled inference.

The Gaps That Decide Your Architecture

The announcement does not touch the questions that decide whether Heim is viable for your workload. The table is the honest gap list, and the right column is what you request as a document, not as a verbal answer on a call.

Open questionWhy it changes your designAsk for
Which metros?An expansion in a metro you do not serve adds nothing to your p95Site addresses and energisation dates
New build or acquisition?Acquisitions bring integration churn and inconsistent network fabricNamed entity, site history, whether the fabric is being re-architected
Power envelope per hallRack density caps your instance class, not your ambitionMW available now, MW energised by date, kW/rack in the halls offered to you
InterconnectionIX presence and dark fibre decide your cloud on-ramp costIX ports available, cross-connect price list, meet-me-room map
Redundancy topology"N+1" covers a lot of sins; block topology matters more than the labelSingle-line diagram, per-block not per-site
Tenant mixShared halls mean shared risk and shared noiseWho else is in the hall, and whether you can be in a dedicated block
Existing tenant impactExpansion work is disruptive workMaintenance calendar for the next 12 months
📝

None of this is a knock on Heim. I have one sentence of public information to work with, and that is the whole problem: one sentence cannot carry a multi-year commitment. The same holds for every provider announcement you will read this year.

Why a Capital Raise Is a Procurement Signal, Not a Heim Spec Sheet

Separating Build-Out Capital From Refinancing

"Investment for expansion" can describe at least three very different transactions:

  1. Growth equity into a new entity for greenfield capex. New halls, new pricing tiers, probably promotional onboarding to fill them.
  2. Refinancing of existing debt. No new capacity. Often a sign the balance sheet needed air, which can surface later as margin pressure in egress and cross-connect pricing.
  3. Acquisition financing. You inherit whatever the acquired operator's fabric looked like.

The item as reported does not distinguish these. From a procurement standpoint the difference is timing. Only case 1 gives you a plausible new hall in a new metro inside your planning horizon, and even then the gate in FLAP-D markets (Frankfurt, London, Amsterdam, Paris, Dublin) is grid connection, not capital. A funded provider still waits in the interconnection queue.

Inference, untested: if the money is genuinely earmarked for new European sites, expect announcements of specific metros and utility agreements within a few quarters. Nothing specific by then, and you treat the expansion as aspirational for your 12-month roadmap.

Turning the Announcement Into a Due-Diligence Questionnaire

Send it as a document request. Written answers, names attached.

  1. Full site list, with addresses and current status (live / shell / energised / planned).
  2. For each site you are offering me: kW/rack available today and 12 months out.
  3. Position in the utility connection queue per site, and the contracted capacity.
  4. IX presence per site, port speeds available, and the cross-connect price list.
  5. Full SLA text including every exclusion, not the summary.
  6. Maintenance calendar for the next 12 months, plus the notification period.
  7. Credit schedule, including the cap and the claim process.
  8. Termination for convenience terms, if any exist.
  9. Egress price list with tier boundaries and the notice period for changes.
  10. Data export: formats, rate limits, and any fee distinct from egress.
  11. Security attestations and their scope — does the certificate name this site?
  12. Named NOC escalation contact and the contractual response times.

Anything that comes back verbally only does not exist. It goes in the contract or it goes in the bin.

Defining Your Latency Budget Before Benchmarking Heim

Deriving p50, p95, and p99 Targets From the Request Path

The procurement mistake I see most often is benchmarking before deciding what the number has to be. Teams measure 22 ms against 26 ms and argue about the delta, when the metro choice was worth 4 ms out of a 300 ms budget the entire time.

Decompose the path first. A realistic p95 budget for a synchronous API call, origin in one region, users spread across Europe:

Path segmentPlanning p95Moves if you change metro?
Client → edge PoP55 msNo
Edge → origin (cross-region)22 msYes
Origin ingress + TLS6 msPartly
App handler110 msNo
DB queries (4 × 1.5 ms in-region)9 msYes, by roughly 1 ms
Internal RPC (3 × 2.5 ms)10 msYes, by roughly 1–2 ms
Queueing + serialization38 msNo
Slack50 ms—
Total300 ms

The datacenter-attributable portion is roughly 25 ms out of 300. That is the entire prize. If two candidate metros both sit inside your budget with headroom, settle the metro question on failover evidence and exit terms — the latency argument is noise. If one of them blows the budget by 40 ms, that is a kill criterion, not a negotiating position.

On the figures: intra-DC round trips land sub-millisecond to low single digits, cross-region ones in the tens of milliseconds on well-built European networks. Those are planning numbers, not measurements of Heim. Measure before you paste them into a design doc.

Choosing Reference Points That Match Your Real Users

  • Weight by traffic, not by map aesthetics. Pull request volume per country from your own logs or RUM and rank metros on that. A site in a country carrying 2% of your traffic is a compliance decision or a latency-to-a-partner decision, not a user-latency one.
  • Use at least three vantage points per candidate metro: a cloud region in the same metro, a consumer ISP, and a mobile carrier. Mobile tails are where your p99 lives.
  • The provider's looking glass is not a source. It is a legitimate tool, and it is also a machine on their network, measuring their network, from somewhere you will never run from.
  • Record the path, not just the number. mtr -rwzbc 100 <host> gives you hop-by-hop loss and the AS path. Two metros with identical RTT and different AS paths will behave very differently on a bad Tuesday.

Terminate TLS at a CDN and the client-to-edge leg tests nothing about the datacenter. Measure edge-to-origin separately, from the CDN's own region, or you will end up benchmarking your CDN and calling it a colocation decision.

Latency Benchmarking Methodology for Datacenter Vetting

Measure From Inside the Workload, Not From a Laptop

Run the probe from the instance class, the VPC, and ideally the rack profile you intend to buy. A laptop on hotel wifi measures the hotel. A small instance in the wrong region measures the wrong region.

Two measurements matter, and they are not the same thing:

  • Origin latency — edge or client region to the candidate site.
  • Intra-site latency — service A to service B inside the same hall, which is what your microservice fan-out actually spends.

The second is where an oversubscribed hall shows up, and it is the one providers rarely quote.

Decomposing Connect, TLS, and Time to First Byte

A single "response time" hides which layer is guilty. Split it:

PhaseWhat it isolatesA bad number here means
dnsResolver + authoritative pathBad resolver, long CNAME chains, geo-DNS weirdness
tcpNetwork RTT + handshakePath length, queueing, or a middlebox
tlsKey exchange + cert chainCPU on the termination side, oversized chain, no session resumption
ttfbServer processingYour code, your DB, or their ingress
bodyTransferBandwidth, or a payload you did not mean to send

TLS 1.3 costs one round trip on a cold connection; TLS 1.2 costs two. Large tls with small tcp points at the server side, not the fibre. Large tcp with small ttfb points at the path.

Sampling Windows and Why One Week of Data Misleads

One week of samples will produce a confident, wrong answer. It misses month-end batch runs, the provider's own maintenance window, and whichever congestion event happens to fall outside the sample.

Run four weeks minimum, and deliberately include:

  • a month-end close or batch weekend,
  • a marketing or product launch spike,
  • at least one provider-announced maintenance window,
  • one full week where nothing unusual happens.

On cadence: a probe every 200 ms is 432,000 requests per day per vantage point (86,400 / 0.2). Fine against a health endpoint. Not fine against a tenant API. Probe something cheap, and check the contract for whether synthetic monitoring counts against a bandwidth commitment.

Jitter and Tail Behaviour Under Business-Hours Load

Percentiles alone will let you sign a bad contract. Also record:

  • p99.9 and max, with a count of samples above budget, not just the percentile.
  • Step changes at known times. A step at 09:00 CET when offices open, another around 14:00, a third when the nightly batch starts.
  • Jitter as a first-class metric. For consecutive samples, report the distribution of |t[i] - t[i-1]|. A path with a stable 30 ms and no jitter beats one with a 20 ms median and 40 ms swings, even though the median favours the second.

A Reproducible Node.js Latency Harness for Datacenter Vetting

The Measurement Script

This harness opens one cold connection per request via agent: false, so every sample includes DNS, TCP, and TLS. That is deliberate. Warm keep-alive numbers describe a connection you already have; you care about the one you have to rebuild after a failure.

probe.mjs
import https from "node:https";


const now = () => performance.now();

function probe(url, timeoutMs = 5000) {
return new Promise((resolve) => {
  const t0 = now();
  const marks = {};
  let settled = false;

  const finish = (outcome, extra) => {
    if (settled) return;
    settled = true;
    const end = now();
    resolve({
      outcome,
      status: extra && extra.status,
      error: extra && extra.error,
      dns: marks.dns ? marks.dns - t0 : null,
      tcp: marks.dns && marks.connect ? marks.connect - marks.dns : null,
      tls: marks.connect && marks.secureConnect ? marks.secureConnect - marks.connect : null,
      ttfb: marks.secureConnect && marks.firstByte ? marks.firstByte - marks.secureConnect : null,
      body: marks.firstByte ? end - marks.firstByte : null,
      total: end - t0
    });
  };

  const req = https.request(url, {
    method: "GET",
    agent: false,
    timeout: timeoutMs,
    headers: { "cache-control": "no-store", "user-agent": "dc-vet/1.0" }
  });

  req.on("socket", (socket) => {
    socket.once("lookup", () => { marks.dns = now(); });
    socket.once("connect", () => { marks.connect = now(); });
    socket.once("secureConnect", () => { marks.secureConnect = now(); });
  });

  req.on("response", (res) => {
    res.once("data", () => { marks.firstByte = now(); });
    res.once("end", () => finish("ok", { status: res.statusCode }));
    res.once("error", () => finish("body_error"));
  });

  req.on("timeout", () => req.destroy(new Error("probe_timeout")));
  req.on("error", (err) => finish("transport_error", { error: err.code || err.message }));
  req.end();
});
}

const url = process.argv[2];
const samples = Number(process.argv[3] || 600);
const intervalMs = Number(process.argv[4] || 250);

if (!url) {
console.error("usage: node probe.mjs <url> [samples] [intervalMs]");
process.exit(2);
}

for (let i = 0; i < samples; i += 1) {
const row = { t: Date.now(), ...(await probe(url)) };
process.stdout.write(JSON.stringify(row) + "
");
await new Promise((r) => setTimeout(r, intervalMs));
}

Node itself does not cache getaddrinfo results, but your OS resolver might, so dns measures the full stack you actually run rather than just the wire.

summarize.mjs
import { readFileSync } from "node:fs";

const PHASES = ["dns", "tcp", "tls", "ttfb", "body", "total"];

const quantile = (sorted, q) => {
if (sorted.length === 0) return NaN;
const pos = (sorted.length - 1) * q;
const lo = Math.floor(pos);
const hi = Math.ceil(pos);
if (lo === hi) return sorted[lo];
return sorted[lo] + (pos - lo) * (sorted[hi] - sorted[lo]);
};

const rows = readFileSync(process.argv[2], "utf8")
.split("
")
.filter(Boolean)
.map((line) => JSON.parse(line));

const ok = rows.filter((r) => r.outcome === "ok");
const errors = rows.filter((r) => r.outcome !== "ok");

const pad = (v, n) => String(v).padEnd(n, " ");
console.log(pad("phase", 8) + pad("p50", 8) + pad("p95", 8) + pad("p99", 8) + "max");

for (const phase of PHASES) {
const sorted = ok
  .map((r) => r[phase])
  .filter((v) => typeof v === "number")
  .sort((a, b) => a - b);
console.log(
  pad(phase, 8) +
    pad(quantile(sorted, 0.5).toFixed(1), 8) +
    pad(quantile(sorted, 0.95).toFixed(1), 8) +
    pad(quantile(sorted, 0.99).toFixed(1), 8) +
    (sorted.length ? sorted[sorted.length - 1].toFixed(1) : "n/a")
);
}

const errorRate = rows.length ? errors.length / rows.length : 1;
console.log("samples " + rows.length + "  ok " + ok.length + "  errors " + errors.length);

// Gate: fail the build if we breach the budget we agreed internally.
const LIMITS = { ttfb: { p95: 40, p99: 90 }, total: { p95: 60, p99: 120 } };
let failed = 0;

for (const phase of Object.keys(LIMITS)) {
const sorted = ok
  .map((r) => r[phase])
  .filter((v) => typeof v === "number")
  .sort((a, b) => a - b);
const qmap = { p50: 0.5, p95: 0.95, p99: 0.99 };
for (const q of Object.keys(LIMITS[phase])) {
  const actual = quantile(sorted, qmap[q]);
  const limit = LIMITS[phase][q];
  if (actual > limit) {
    failed += 1;
    console.log("FAIL " + phase + " " + q + "=" + actual.toFixed(1) + "ms limit " + limit + "ms");
  }
}
}

if (errorRate > 0.001) {
failed += 1;
console.log("FAIL error_rate=" + (errorRate * 100).toFixed(2) + "% limit 0.10%");
}

process.exit(failed === 0 ? 0 : 1);

Reading the Output and Defining a Failure Threshold

Below is the harness run against a synthetic origin on a test network I control. These numbers are illustrative — they show the output shape and the gate wiring, not Heim's latency.

$ node probe.mjs https://origin.example.net/healthz 1800 200 > samples.jsonl
$ node summarize.mjs samples.jsonl
phase   p50     p95     p99     max
dns     0.9     2.4     4.1     6.2
tcp     0.4     0.7     1.1     2.0
tls     2.6     3.9     6.8     11.4
ttfb    18.4    31.2    58.7    142.9
body    0.3     0.5     0.9     3.1
total   22.6    37.9    68.3    151.0
samples 1800  ok 1799  errors 1

The gate is the part that matters, because it turns a measurement into a decision that survives a re-run:

$ node summarize.mjs regression.jsonl
FAIL total p99=131.4ms limit 120ms
$ echo $?
1

Then read the profile, not just the percentiles:

  • tcp high, tls normal → path or queueing problem. Escalate with an mtr capture, not a complaint.
  • tls high, tcp normal → termination CPU, oversized certificate chain, or no session resumption at their edge.
  • ttfb high only under load → application or database, and no metro change will fix it.
  • Errors clustered into one minute → maintenance window or routing flap. Correlate against the calendar you demanded in the questionnaire.

Run it from every vantage point you care about, for four weeks, and keep the JSONL. When a provider tells you the network is fine, you will have a diff instead of an opinion.

Failover Validation: Testing RTO, RPO, and Split-Brain Risk

Failure Modes Worth Injecting Deliberately

⚠️

Inject only against systems you own, or with written authorization and a rollback plan. A cross-site partition test on a live production database is how you discover you had no quorum for three minutes.

InjectionMethodWhat you actually learn
Graceful drainStop accepting new connections, send Connection: close, waitBest-case RTO, and how long in-flight requests survive
Hard stopKill the process; no FINReal-world RTO; often 2–5× the graceful number
DNS withdrawal onlySet TTL low, pull the recordWhether clients honour TTL or hang on keep-alive
Cross-site partitioniptables -A OUTPUT -d <peer-subnet> -j DROPQuorum behaviour and unbounded async RPO
Partial losstc qdisc ... netem loss 1%Whether retransmits mask a problem until they don't
Single cross-connectPhysically or logically disable one pathWhether the redundancy you paid for exists
Control-plane lossRevoke your own API credentials for 30 minWhether your runbooks depend on a portal that can be down

The netem commands, if you need them on a lab host:

## add 40ms ± 10ms latency and 1% loss to egress
sudo tc qdisc add dev eth0 root netem delay 40ms 10ms loss 1%
## remove it
sudo tc qdisc del dev eth0 root

DNS TTLs, Connection Draining, and Client-Side Retry Storms

Three things bite here, and they compound.

TTL is not your RTO. It is the floor of your RTO. Effective failover time is max DNS TTL across caches + keep-alive connection lifetime + client reconnect backoff. The JVM caches positive lookups for 30 seconds by default — set networkaddress.cache.ttl explicitly rather than trusting it. Go's resolver and Node's dns.lookup do not cache in-process, but your OS resolver might, and a Keep-Alive: timeout=75 on the old node means some clients never re-resolve at all. Which is exactly why draining matters more than TTL: draining tells existing connections to finish and close, and that forces the re-resolve.

Retry storms are arithmetic. 10,000 clients, 5 retries each, fixed 1-second delay, and you generate 50,000 requests at the recovery instant — aimed at a node that just came back with a cold cache. Use full jitter:

const delay = Math.random() * Math.min(capMs, baseMs * 2 ** attempt);

Cap total retries at a fraction of your request budget (I use 10%) and honour Retry-After when the server sends it. A circuit breaker that fails fast for 30 seconds is worth more than a fourth retry.

Client behaviour is part of the failover test. If your game day exercises server-side drain and never the mobile client holding a stale DNS entry, you tested half the system.

Stateful Dependencies: Replication Lag, Quorum, and Split-Brain

Stateless failover is a solved problem. State is where the quoted RTO turns into fiction.

Measure lag in bytes, not a coarse boolean. On PostgreSQL:

SELECT client_addr, state, sent_lsn, replay_lsn,
       pg_wal_lsn_diff(sent_lsn, replay_lsn) AS replay_bytes
FROM pg_stat_replication;

MySQL's Seconds_Behind_Source is a coarse instrument; prefer GTID-based comparison where you can.

Now the topology rule that catches most teams: quorum-bearing members need three failure domains, not three nodes. If the expansion gives Heim two European sites and you place a 3-node etcd or Consul cluster 2+1 across them, losing the site with two members loses quorum outright. Two sites is not a quorum story; it is a primary/replica story, and the third voter belongs somewhere else.

Split-brain is the same problem viewed from the other side. Under asynchronous replication, RPO during a partition is unbounded — it is however much WAL the old primary accepted before you noticed. You cannot read that number off a contract. You measure it.

Measuring RTO and RPO Instead of Accepting the SLA Number

Define the clocks precisely, or the number is marketing:

  • RTO start: first failed request from a real client vantage point, timestamped client-side.
  • RTO stop: first correct 200 — correct meaning the response contains the data you wrote before the failure, not just a healthy status.
  • RPO measurement: write a monotonically increasing sequence from the client every second.
CREATE TABLE fence (
  seq        bigint PRIMARY KEY,
  written_at timestamptz NOT NULL DEFAULT now()
);

After failover, SELECT max(seq) FROM fence; and compare against the last sequence the client successfully wrote. The gap is your measured RPO, in seconds of lost writes.

MetricRun 1Run 2Run 3Use in the decision
RTO, graceful drain (s)Your realistic best case
RTO, hard stop (s)Your realistic worst case
Measured RPO (s of writes)Drives whether you need sync commit
Client errors during eventWhat your users actually saw
Time to full cache warm (min)The part everyone forgets

Three game days, three columns. One run is an anecdote.

Reading Availability and Credit Language in the Heim Contract

Credit Schedules Versus the Real Cost of Downtime

The monthly downtime budget at common availability targets:

Committed availabilityAllowed downtime per 30-day month
99.9%~43.8 minutes
99.95%~21.9 minutes
99.99%~4.4 minutes

Now the credit. Assume a €12,000 monthly fee and a tier paying 10% of monthly fee for availability between 99.0% and 99.9%. A 43-minute outage burns the full month's allowance and returns €1,200. If your gross margin on the affected service is €4,000 per minute, that outage cost roughly €172,000. The credit covers about 0.7% of it.

That is not cynicism. It is the structure. Credits are typically capped at the monthly fee, so the maximum contractual remedy for any outage, however long, is one month of fees. Plan your own resilience accordingly and stop reading the credit schedule as insurance.

Check what "availability" is defined against, too. Usually it is power and network at the demarcation point — not your workload, not the hypervisor, not the storage layer.

Maintenance Windows and Exclusions That Quietly Swallow Your SLO

A four-hour monthly maintenance window excluded from the availability calculation is 240 minutes out of roughly 43,830 in a month: 0.55%. Your 99.9% commitment now has a structural ceiling near 99.45% before anything unplanned happens.

Read for these specifically:

  • "Emergency maintenance" with no definition and no notice period. The single most expensive undefined term in a colocation contract.
  • "Reasonable endeavours" where you expected a commitment.
  • Per-port measurement that never sees tenant-level degradation.
  • Exclusion for "customer equipment" broad enough to cover the cross-connect you rent from them.

Ask for the maintenance calendar as a contract exhibit, with a notification period and a credit if they miss it.

Exit Terms: Egress, Portability, and Termination Clauses That Outlive the Deal

Egress, Portability, and Data Format Obligations

Get the egress price list with tier boundaries into the contract, plus a change-notice period and a cap on increases. "Prices subject to change with 30 days' notice" combined with egress as the margin centre is how a cheap rack becomes an expensive year three.

Portability needs four things written down, not promised:

  1. The right to export full-fidelity data without assistance — logical dumps and raw object storage, not a proprietary snapshot format.
  2. A rate limit guarantee on export. Throttled to 50 MB/s, a two-day migration becomes a three-week one.
  3. Clarity that export traffic is not billed as a separate "export fee" on top of egress.
  4. Format documentation that survives the account closing.

There is regulatory tailwind here. Regulation (EU) 2023/2854, the Data Act, includes switching provisions for data processing services, with a staged applicability timetable beginning 12 September 2025 and a later stage addressing switching charges. Whether your specific service and contract fall inside the switching chapter is a question for your counsel, not for a blog post — but it is worth asking the provider what evidence of compliance they have, because the answer tells you how seriously they have thought about exit.

Colocation Traps: Cross-Connects, Cages, and Power Commitments

  • Cross-connects carry a setup fee and a monthly recurring charge each, and the contract is with the datacenter — not your network provider. Redundant paths mean two cross-connects, and possibly a "diversity" surcharge on the second.
  • Cages are capex you amortize over the term and cannot move. Ask about make-good and restoration obligations at exit; some contracts require you to return the space to shell condition at your cost.
  • Power is usually take-or-pay in kW reserved. Under-run and you still pay. Over-run and you hit a punitive marginal rate or a hard cap. Get the ramp schedule in writing, and get the overage rate.
  • Remote hands billing increments. Fifteen-minute increments and one-hour increments differ by a factor of four across a year of small interventions.

Notice Periods, Minimum Commitments, and Termination Math

Run the arithmetic before you sign. Thirty-six months at €9,500/month with 24 months remaining is €228,000 of exposure. The same contract with termination for convenience after month 12, on 90 days' notice, at a fee of three months' MRC, is €28,500. That difference is the price of an option, and in a competitive market it is usually negotiable.

Two clauses to diarize the day you sign:

  • Auto-renewal with a 90-day non-renewal window. Miss the window, gain 12 months.
  • Termination-for-convenience notice period measured in months, not days.

What to Get in Writing Before Signing

  1. Full price list as an exhibit — rack, power, cross-connects, remote hands, egress — with a change-notice period and a cap on increases.
  2. Maintenance calendar as an exhibit, with notification period and a credit if missed.
  3. Egress cap or fixed rate for the term.
  4. Export assistance hours and an export rate limit.
  5. Cross-connect pricing at renewal, not just at signing.
  6. Termination for convenience, with the fee stated in months of MRC.
  7. Renewal notice date written into the contract, and a calendar reminder you own.
  8. Named escalation contacts with contractual response times for P1.
  9. Security attestations with the site named in scope.
  10. Check whether there is a benchmarking or non-disparagement clause that would restrict publishing your own latency results. If there is, strike it.

Building the Datacenter Decision Matrix

Scoring Criteria and Weights

Score each candidate 1–5 and weight to your business. The weights below follow the analysis above: latency is capped because it is bounded, and failover and exit carry the risk.

CriterionWeightWhat earns a 5
Failover evidence20%You watched a game day, or ran one, with RTO/RPO numbers
Exit and portability terms20%Fixed egress, export without assistance, termination for convenience
Latency headroom20%p99 inside budget with margin, measured from your vantage points
Contract availability language15%Narrow exclusions, maintenance calendar as exhibit
Interconnection ecosystem10%IX presence, published cross-connect pricing, cloud on-ramp
Power and cooling transparency10%Per-hall kW/rack, single-line diagram, density guarantee
Security attestations in scope5%Certificate names the site, current, with a report you can read

Kill Criteria Versus Negotiable Gaps

Kill criteria — walk away, do not negotiate:

  • No third failure domain available for anything quorum-bearing.
  • No written egress price, or a unilateral change right with no cap.
  • No termination for convenience at any price on a term longer than 24 months.
  • No site-scoped attestation.
  • Measured p99 outside budget with no remediation date.

Negotiable gaps — price them and move on:

  • Cross-connect MRC and remote hands rates.
  • Credit schedule tiers. Ask for a higher cap; you will rarely get it.
  • Notice period length within a band.
  • Power ramp schedule.

What Would Change This Heim Datacenter Assessment

The list I would watch, and each item is falsifiable rather than a vibe:

  • A published site list naming metros that match your traffic-weighted ranking. Until that exists, "European expansion" does not affect your roadmap.
  • Energisation dates backed by utility agreements. Capital does not shorten a grid queue.
  • IX port availability and a published cross-connect price list at each new site.
  • Third-party latency data, or your own four-week run, showing p99 inside budget from at least three vantage points.
  • Evidence the capital is build-out rather than refinancing. New halls and new pricing tiers are the observable signal; a refinancing shows up later as margin pressure, likely in egress and cross-connect pricing.
  • A contract that will take a fixed egress rate and a termination for convenience. A provider confident in its operations will trade on those terms.
  • A game day you are allowed to observe, with RTO and RPO numbers shared afterwards.
  • Integration risk if the expansion is an acquisition. Untested, but acquisitions are where network fabrics get re-architected and where the maintenance calendar gets interesting.

None of these are criticisms of Heim in particular. They are the standard set, and the announcement answers none of them.

Further Reading

Where This Leaves Your Heim Migration Plan

Treat the Heim announcement as a calendar entry, not a decision. Concretely:

  1. Do not extend an existing commitment on the strength of it. If you are already a Heim tenant, the right response to "our provider raised capital for expansion" is to ask for the site list and a price commitment, not to sign a longer term.
  2. Start the four-week latency run now, from three vantage points per candidate metro. It costs one small instance and a cron entry.
  3. Book the game day before the contract, not after. A provider who will not support a partition test before signature will not support one after.
  4. Send the twelve-question document request this week. The quality of the written answers tells you more about the operations team than any call.
  5. Negotiate the exit before you negotiate the price. Egress, export, and termination for convenience are cheaper to win while the sales team is still closing a new logo.
  6. Diarize the renewal notice date the day you sign, with two reminders.

The expansion may turn out to be exactly the capacity you need in exactly the right metros, with a fabric that survives a partition and a contract that lets you leave. That would be a good outcome. But the announcement does not say so, and the only way to find out is to measure it.

Share this post

More posts

Loading comments…