NAME
WWW::Hetzner::Cloud::Costs - Current running cost of a Hetzner Cloud project
VERSION
version 0.102
SYNOPSIS
use WWW::Hetzner::Cloud;
my $cloud = WWW::Hetzner::Cloud->new(token => $ENV{HETZNER_API_TOKEN});
my $costs = $cloud->costs(label_selector => 'env=live');
for my $r (@{ $costs->{resources} }) {
printf "%-14s %-20s %-8s %8.4f %8.2f\n",
$r->{kind}, $r->{name}, $r->{location} // '-',
$r->{hourly}, $r->{monthly};
}
printf "Total: %.4f %s/h, %.2f %s/month (%s)\n",
$costs->{totals}{hourly}, $costs->{currency},
$costs->{totals}{monthly}, $costs->{currency}, $costs->{price};
DESCRIPTION
Sums what the resources of a Hetzner Cloud project cost right now, per hour and per month. This is a calculator over existing controllers, not an API resource of its own: it reads the price list via "get" in WWW::Hetzner::Cloud::API::Pricing and the resources via the list_all method of the servers, volumes, primary IPs, floating IPs and load balancers controllers. Every request goes through the client's normal IO path; nothing is modified.
Usually reached through "costs" in WWW::Hetzner::Cloud.
What is counted
server -- every server that exists, whatever its status. Hetzner bills stopped servers too, so an
offserver is counted at full price; the row carriesstatusso callers can see it.server_backup -- for servers with backups enabled (a
backup_windowis set), the backup surcharge:server_backup.percentageof the server's price.volume --
sizeGB timesvolume.price_per_gb_month.primary_ip -- priced by type (
ipv4/ipv6) and location. A type the price list does not mention at all (currentlyipv6) is free and counted as0.floating_ip -- priced by type and home location.
load_balancer -- priced by load balancer type and location.
Not counted: traffic beyond the included volume, images/snapshots, and anything outside the five resource kinds above.
Prices: location, net/gross, hourly
Server, load balancer, primary IP and floating IP prices are taken for the resource's own location. If the price list has no entry for a resource's type and location, the row gets undef prices, is left out of the totals, and a message is added to warnings.
Prices are gross by default (what the price list calls gross, i.e. including vat_rate); pass price => 'net' for net prices. The result always says which one was used, together with vat_rate.
monthly is the full-month price, which is also the cap of hourly billing. hourly is the price per hour the resource exists. For volumes and floating IPs the price list carries no hourly price; there the hourly figure is derived as monthly / 624 and the row is flagged hourly_derived. 624 hours is the ratio Hetzner uses for every item that has both prices (e.g. cx23 5.49/month at 0.0088/h, ipv4 0.50/month at 0.0008/h), i.e. the monthly cap is reached after 624 hours.
client
The WWW::Hetzner::Cloud client used for all requests (required).
calculate
my $costs = $calculator->calculate(
label_selector => 'env=live', # optional, passed to every list call
price => 'net', # optional, 'gross' (default) or 'net'
);
Fetches the price list and all priced resources and returns a hashref:
{
currency => 'EUR',
vat_rate => '19.00',
price => 'gross', # which price column was used
label_selector => 'env=live', # or undef
hours_per_month => 624, # divisor for derived hourly prices
resources => [
{
kind => 'server', # server, server_backup, volume,
# primary_ip, floating_ip, load_balancer
id => 42,
name => 'web-1',
type => 'cx23', # type name, IP type, or "<size> GB"
location => 'fsn1',
status => 'running', # resource status, or (un)assigned for IPs
hourly => 0.0088,
monthly => 5.49,
hourly_derived => 0, # 1 if hourly = monthly / hours_per_month
size => 10, # volumes only
},
...
],
totals => { hourly => 0.0657, monthly => 40.98 },
warnings => [ 'no gross price for server ...' ],
}
label_selector is applied to each resource's own labels on every list request (servers, volumes, primary IPs, floating IPs, load balancers). A server backup row inherits its server's label match.
SEE ALSO
WWW::Hetzner::Cloud - Main Cloud API client (
costsmethod)WWW::Hetzner::Cloud::API::Pricing - Price list
WWW::Hetzner::CLI::Cmd::Costs -
hcloud.pl costs
SUPPORT
Issues
Please report bugs and feature requests on GitHub at https://github.com/Getty/p5-www-hetzner/issues.
IRC
Join #kubernetes on irc.perl.org or message Getty directly.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <torsten@raudssus.de>
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.