FinOps on OVHcloud: Pricing Model, Egress and the Levers That Actually Move the Bill
FinOps & Coûts

FinOps on OVHcloud: Pricing Model, Egress and the Levers That Actually Move the Bill

October 20, 20268 min readOVHcloudFinOpsKubernetes

OVHcloud's pricing model removes egress fees from the equation — which means your FinOps levers lie elsewhere. A practical guide to compute, storage, Kubernetes and the bare metal arbitrage.

Why OVHcloud changes the FinOps equation

Most FinOps playbooks were written for AWS, Azure and GCP. They optimise for three things: compute commitments, storage tiering, and network egress. On OVHcloud, the third pillar largely disappears — and that single structural difference reshuffles the whole optimisation priority list.

OVHcloud's commercial positioning has long been bandwidth included: on Public Cloud instances in European and North American regions, public outbound traffic is not metered per gigabyte. You pay for a guaranteed bandwidth capacity tied to the instance flavour, not for the volume you push. The consequence is that architectures that would be financially punished on a hyperscaler — streaming, media delivery, large dataset distribution, chatty cross-region replication, data exports to partners — become economically viable without contortions.

That doesn't mean FinOps on OVHcloud is trivial. It means the levers are elsewhere: provisioned (not consumed) block storage, idle instances left running, oversized managed Kubernetes node pools, orphaned snapshots, and the perennial bare metal versus Public Cloud arbitrage. This article walks through the pricing model, what is genuinely included on egress, and the concrete actions that move the invoice.

The OVHcloud pricing model in five dimensions

A Public Cloud bill decomposes into a small number of line items. Knowing which ones are elastic and which are structural is the first step.

DimensionBilling basisElasticityMain lever
Compute (instances)Hourly, monthly, or commitment-based savings planHighRight-sizing, billing mode, autoscaling, scheduling
Block storagePer GB provisioned per month, by performance classLow once attachedCorrect class, correct size, delete orphans
Object storagePer GB stored, by storage class; retrieval fees on archive tiersHighLifecycle rules, class selection, multipart cleanup
NetworkPublic bandwidth included on instances in EU/NA; private vRack traffic free; additional public IPs and load balancers billedMediumRemove unused floating IPs and load balancers
Managed servicesPer node / per plan (databases, Kubernetes worker nodes, registry)MediumPlan tier, node pool sizing, cluster consolidation

Two points deserve emphasis. First, the Managed Kubernetes control plane is provided at no additional charge — you pay for worker nodes, their volumes, load balancers and storage. Second, block storage is billed on what you provision, not on what the filesystem actually uses. A 500 GB volume that holds 40 GB costs the price of 500 GB, every month, forever. This is by far the most common source of silent waste we find in audits.

Egress: what is actually included, and the exceptions

The marketing line "no egress fees" is broadly accurate on OVHcloud Public Cloud, but a FinOps practitioner should know the boundaries:

  • Instances in European and North American regions: public outbound traffic is unmetered. The constraint is bandwidth capacity (guaranteed and burst rates depend on the flavour), not volume.
  • Asia-Pacific regions: historically treated differently, with outbound traffic metered. If you run a multi-region footprint, verify the current price grid for each region before assuming parity.
  • Object storage: policy depends on the storage class. Standard classes have been positioned with traffic included, while archive/cold tiers carry retrieval costs that are deliberately asymmetric — cheap to store, expensive to read back. Treat cold tiers as insurance, not as a working set.
  • vRack private network: traffic between your own resources over the private backbone is not billed, which makes hybrid designs (bare metal + Public Cloud + dedicated databases on the same vRack) financially clean.

Strategically, this matters beyond the invoice. The European Data Act progressively removes switching charges and egress fees across the market, pushing hyperscalers toward the model OVHcloud already applies. For organisations building an exit strategy or a multi-cloud posture, a provider whose pricing does not penalise moving data out removes a structural lock-in argument from the table.

Observe before you optimise: the usage API

You cannot optimise a bill you only see once a month in PDF form. OVHcloud exposes consumption through its public API, with current, historical and forecast views per Public Cloud project. Wire this into your existing observability stack rather than relying on the control panel.

# Current month consumption for a project, via the OVHcloud API
GET /cloud/project/{serviceName}/usage/current

# Historical consumption (useful for trend and seasonality)
GET /cloud/project/{serviceName}/usage/history?from=2025-01-01&to=2025-06-30

# Forecast for the running month
GET /cloud/project/{serviceName}/usage/forecast

The returned payload breaks down by resource type (instance, volume, snapshot, object storage, bandwidth where applicable) with per-resource identifiers. Dump it daily into a columnar store or a Prometheus exporter, and you get showback without buying a third-party platform. The key design decision upstream: use Public Cloud projects as your cost allocation boundary. One project per team-environment pair is far more actionable than one giant project with fifty people in it, because the project is the natural aggregation unit of the invoice.

Compute: billing mode is a lever, not a detail

OVHcloud offers hourly billing, monthly billing and commitment-based savings plans. The arbitrage is mechanical:

  • Hourly for anything ephemeral: CI runners, preview environments, batch jobs, load test fleets. Combine with Terraform so environments are genuinely destroyed, not just stopped. A stopped instance may still bill for its attached volumes and reserved resources.
  • Monthly for anything that runs continuously — the unit price is materially lower and the operational cost of managing the switch is near zero.
  • Savings plans for the stable baseline you are confident about over a one- or three-year horizon. Size the commitment to your floor, not your average; cover the peak with hourly instances.

On flavour selection, don't default to general-purpose. OVHcloud's ranges are differentiated for a reason: discovery instances for dev and test, general-purpose for web tiers, CPU-optimised for compute-bound services, RAM-optimised for caches and in-memory analytics, GPU for inference and training. Picking a RAM-optimised flavour for a stateless API with 2 GB of working set is a recurring and expensive mistake.

Managed Kubernetes: the specific traps

Free control plane is attractive, but the cost reality lives in node pools. Three patterns dominate our findings:

1. Node pools that never scale down. Enable autoscaling with a realistic minimum, and let the cluster autoscaler do its job. Pod disruption budgets that are too strict and DaemonSets without proper tolerations will silently block scale-down.

resource "ovh_cloud_project_kube_nodepool" "workers" {
  service_name  = var.project_id
  kube_id       = ovh_cloud_project_kube.cluster.id
  name          = "workers-b3"
  flavor_name   = "b3-8"
  autoscale     = true
  desired_nodes = 3
  min_nodes     = 2
  max_nodes     = 10

  template {
    metadata { labels = { "workload" = "general" } }
    spec     { unschedulable = false }
  }
}

2. Requests set far above real usage. The cluster autoscaler schedules on requests, not on actual consumption. If every team requests 2 CPU "to be safe" for workloads using 150m, you pay for roughly thirteen times the compute you need. Deploy a vertical pod autoscaler in recommendation mode, or run OpenCost in the cluster to produce per-namespace showback and confront teams with their own numbers.

3. One load balancer per service. Each public load balancer and each additional public IP is a billed line. Consolidate behind a single ingress controller and route by hostname.

Storage: lifecycle rules and orphan hunting

Object storage on OVHcloud is S3-compatible, which means the standard tooling and the standard lifecycle semantics apply. Two rules pay for themselves immediately: expire or transition old objects, and abort incomplete multipart uploads — fragments from failed uploads are invisible in most consoles but fully billed.

<LifecycleConfiguration>
  <Rule>
    <ID>abort-incomplete-mpu</ID>
    <Status>Enabled</Status>
    <Filter><Prefix></Prefix></Filter>
    <AbortIncompleteMultipartUpload>
      <DaysAfterInitiation>7</DaysAfterInitiation>
    </AbortIncompleteMultipartUpload>
  </Rule>
  <Rule>
    <ID>expire-build-artifacts</ID>
    <Status>Enabled</Status>
    <Filter><Prefix>ci/artifacts/</Prefix></Filter>
    <Expiration><Days>30</Days></Expiration>
  </Rule>
</LifecycleConfiguration>

On block storage, run a monthly reconciliation: list volumes with no attachment, list snapshots older than your retention policy, and compare provisioned size against filesystem usage. A short script against the OpenStack API, scheduled in your CI, turns this from a good intention into a control.

Bare metal versus Public Cloud: the arbitrage people skip

This is where OVHcloud differs most from a pure hyperscaler strategy. For workloads with a stable, predictable baseline — a production database, a Kafka cluster, a self-managed Kubernetes data plane, a storage back end — dedicated servers typically deliver a far better cost per core and per gigabyte of RAM than equivalent virtualised instances, with local NVMe included rather than billed as network storage.

The pragmatic architecture is hybrid: dedicated servers for the stable baseline, Public Cloud for elasticity and for anything that must scale in minutes, both joined on the same vRack so that inter-component traffic is private and unbilled. The trade-off is real — you take back operational responsibility for the bare metal layer, provisioning is in minutes to tens of minutes rather than seconds, and you need a credible failure-domain strategy. Make that decision explicitly, with numbers, rather than by default.

A monthly FinOps routine that actually holds

Tooling without cadence produces dashboards nobody opens. A workable rhythm:

  • Weekly, automated: orphan detection (unattached volumes, unused floating IPs, idle load balancers, snapshots past retention) with a report pushed to the owning team's channel.
  • Monthly, human: review the top ten cost lines per project, compare to the previous month, and require an explanation for any variance above a threshold you agree on.
  • Quarterly, strategic: revisit commitment coverage against the actual floor, re-run the bare metal versus Public Cloud arbitrage on the two or three largest workloads, and check whether the storage class distribution still matches access patterns.

Key takeaways

FinOps on OVHcloud is not hyperscaler FinOps with different prices. Because public egress is included in the main European regions, the optimisation energy that elsewhere goes into data-transfer gymnastics can be redirected to where the money actually is: compute right-sizing, billing mode, provisioned block storage, Kubernetes resource requests, and the bare metal arbitrage. Build project-level cost allocation from day one, automate the usage API into your observability stack, and treat orphan resources as a control rather than a cleanup task. The gains are unglamorous, repeatable, and substantial.

← Back to blog