Cost Calculation Algorithms
This document explains how FinFocus calculates costs, including projected cost estimation, actual cost retrieval, aggregation algorithms, and cross-provider cost analysis.
Overview
Section titled “Overview”FinFocus supports two types of cost calculations:
- Projected Costs - Estimate future infrastructure costs from Pulumi plans
- Actual Costs - Retrieve historical costs from cloud providers via plugins
See Cost Calculation Flow Diagram for a visual representation of the calculation pipeline.
Projected Cost Calculation
Section titled “Projected Cost Calculation”Formula
Section titled “Formula”Monthly Cost = Unit Price × Hours Per Month
Where: Unit Price = From plugin or local spec ($/hour) Hours Per Month = 730 (constant)Calculation Steps
Section titled “Calculation Steps”- Resource Ingestion - Parse Pulumi plan JSON to extract resources
- Plugin Query - Query plugin for unit price via
GetProjectedCost() - Monthly Calculation - Multiply unit price by 730 hours
- Aggregation - Sum costs across all resources
- Output - Format as table, JSON, or NDJSON
Example: AWS EC2 Instance
Section titled “Example: AWS EC2 Instance”Resource:
{ "provider": "aws", "resource_type": "ec2:Instance", "sku": "t3.micro", "region": "us-east-1", "tags": { "env": "prod" }}Plugin Response:
{ "unit_price": 0.0104, "currency": "USD", "cost_per_month": 7.592, "billing_detail": "on-demand"}Calculation:
Monthly Cost = 0.0104 $/hour × 730 hours/month = 7.592 $/monthHours Per Month Constant
Section titled “Hours Per Month Constant”The standard month is defined as 730 hours:
730 hours = 365.25 days/year ÷ 12 months × 24 hours/day ≈ 30.4375 days/month × 24 hours/dayThis constant is used consistently across all projected cost calculations to ensure comparability.
Actual Cost Calculation
Section titled “Actual Cost Calculation”Retrieval Process
Section titled “Retrieval Process”- Time Range - User specifies start and end dates
- Filtering - Optional tag-based filtering (
tag:key=value) - Plugin Query - Query plugin for actual costs via
GetActualCost() - Aggregation - Sum daily/monthly costs
- Grouping - Optional grouping by resource, type, provider, or date
Example: Actual Cost Query
Section titled “Example: Actual Cost Query”Request:
finfocus cost actual \ --start-date 2024-01-01 \ --end-date 2024-01-31 \ --filter "tag:env=prod"Plugin API Call:
{ "resource_id": "aws-prod-*", "start": "2024-01-01T00:00:00Z", "end": "2024-01-31T23:59:59Z", "tags": { "env": "prod" }}Plugin Response:
{ "results": [ { "timestamp": "2024-01-01T00:00:00Z", "cost": 73.42, "usage_amount": 730.0, "usage_unit": "hour", "source": "kubecost" }, { "timestamp": "2024-01-02T00:00:00Z", "cost": 74.18, "usage_amount": 730.0, "usage_unit": "hour", "source": "kubecost" } ]}Aggregation:
Total Cost = 73.42 + 74.18 + ... (31 days) = 2,287.64 USDAggregation Algorithms
Section titled “Aggregation Algorithms”By Resource
Section titled “By Resource”Sum costs for each individual resource:
For each unique resource_id: Total[resource_id] = Σ cost where resource matches resource_idExample Output:
aws-ec2-i-123: $1,234.56aws-ec2-i-456: $1,053.08Total: $2,287.64By Type
Section titled “By Type”Sum costs for each resource type:
For each unique resource_type: Total[type] = Σ cost where resource matches typeExample Output:
ec2: $1,834.22s3: $312.48rds: $140.94Total: $2,287.64By Provider
Section titled “By Provider”Sum costs for each cloud provider:
For each unique provider: Total[provider] = Σ cost where resource matches providerExample Output:
aws: $1,987.23azure: $200.19gcp: $100.22Total: $2,287.64By Date (Daily)
Section titled “By Date (Daily)”Sum costs for each day:
For each date in [start, end]: Total[date] = Σ cost where timestamp.Date == dateExample Output:
2024-01-01: $73.422024-01-02: $74.182024-01-03: $73.89...Total: $2,287.64By Date (Monthly)
Section titled “By Date (Monthly)”Sum costs for each month:
For each month in [start, end]: Total[month] = Σ cost where timestamp.Month == monthExample Output:
2024-01: $2,287.642024-02: $2,102.34Total: $4,389.98Cross-Provider Aggregation
Section titled “Cross-Provider Aggregation”Algorithm
Section titled “Algorithm”The CreateCrossProviderAggregation() method aggregates costs across
multiple cloud providers with validation and normalization.
Input:
type ActualCostResult struct { ResourceID string Provider string TotalCost float64 Currency string StartDate time.Time EndDate time.Time GroupBy GroupByType}Validation Steps:
- Empty Check - Ensure results array is not empty
- Currency Validation - Ensure all results use same currency
- Date Range Validation - Ensure EndDate > StartDate
- GroupBy Validation - Ensure time-based grouping (daily or monthly)
Aggregation Steps:
- Provider Extraction - Extract provider from resource type
(
aws:ec2:Instance→aws) - Cost Calculation - Convert costs to daily/monthly based on time period
- Grouping - Aggregate by date dimension
- Sorting - Sort chronologically for trend analysis
Currency Validation
Section titled “Currency Validation”func validateCurrency(results []ActualCostResult) error { currency := "" for _, r := range results { if currency == "" { currency = r.Currency } else if r.Currency != currency { return ErrMixedCurrencies } } return nil}Error Handling:
ErrMixedCurrencies- Different currencies detected (USD vs EUR)ErrInvalidGroupBy- Non-time-based grouping attemptedErrInvalidDateRange- EndDate before StartDate
Cost Period Conversion
Section titled “Cost Period Conversion”When actual costs span different time periods, costs are normalized:
Daily Costs:
If period > 1 day: Daily Cost = Total Cost ÷ Days in PeriodElse: Daily Cost = Total CostMonthly Costs:
If period > 1 month: Monthly Cost = Total Cost ÷ Months in PeriodElse if period < 1 month: Monthly Cost = Total Cost × (30.4375 ÷ Days in Period)Else: Monthly Cost = Total CostExample: Cross-Provider Aggregation
Section titled “Example: Cross-Provider Aggregation”Input (3 providers):
[ { "resource_id": "aws-ec2-i-123", "provider": "aws", "total_cost": 1500.0, "currency": "USD", "start_date": "2024-01-01", "end_date": "2024-01-31" }, { "resource_id": "azure-vm-456", "provider": "azure", "total_cost": 500.0, "currency": "USD", "start_date": "2024-01-01", "end_date": "2024-01-31" }, { "resource_id": "gcp-instance-789", "provider": "gcp", "total_cost": 287.64, "currency": "USD", "start_date": "2024-01-01", "end_date": "2024-01-31" }]Output (Daily Aggregation):
[ { "date": "2024-01-01", "total_cost": 73.47, "currency": "USD", "breakdown": { "aws": 48.39, "azure": 16.13, "gcp": 9.28 } }, { "date": "2024-01-02", "total_cost": 73.47, "currency": "USD", "breakdown": { "aws": 48.39, "azure": 16.13, "gcp": 9.28 } }]Cost Flow Through System
Section titled “Cost Flow Through System”Projected Cost Flow
Section titled “Projected Cost Flow”1. Pulumi Plan JSON ↓2. Resource Descriptors provider: aws, type: ec2, sku: t3.micro, region: us-east-1 ↓3. Plugin Query (GetProjectedCost) ↓4. Plugin Response unit_price: 0.0104, currency: USD ↓5. Monthly Calculation 0.0104 × 730 = 7.592 USD/month ↓6. Aggregation Sum all resources ↓7. Output Formatting Table/JSON/NDJSONActual Cost Flow
Section titled “Actual Cost Flow”1. User Request start: 2024-01-01, end: 2024-01-31, filter: tag:env=prod ↓2. Plugin Query (GetActualCost) ↓3. Plugin API Call Kubecost/Vantage/CloudProvider API ↓4. Plugin Response 31 daily cost entries ↓5. Aggregation Sum daily costs, group by dimension ↓6. Currency Validation Ensure consistent currency ↓7. Output Formatting Table/JSON/NDJSONFallback Cost Calculation
Section titled “Fallback Cost Calculation”When plugins are unavailable, FinFocus uses local YAML specifications.
Spec Format
Section titled “Spec Format”provider: awsresource_type: ec2sku: t3.microregion: us-east-1billing_mode: per_hourrate_per_unit: 0.0104currency: USDdescription: AWS EC2 t3.micro instance pricingCalculation
Section titled “Calculation”Monthly Cost = rate_per_unit × Hours Per Month = 0.0104 × 730 = 7.592 USD/monthPlaceholder Costs
Section titled “Placeholder Costs”If no plugin or spec is available:
{ "cost_per_month": 0.0, "currency": "USD", "source": "unknown", "note": "No pricing data available"}Real-World Examples
Section titled “Real-World Examples”Example 1: Simple EC2 Cost
Section titled “Example 1: Simple EC2 Cost”Input:
finfocus cost projected --pulumi-json plan.jsonPlan (10 t3.micro instances):
{ "resources": [ { "type": "aws:ec2/instance:Instance", "inputs": { "instanceType": "t3.micro" } } ]}Calculation:
Per Instance: 0.0104 × 730 = 7.592 USD/monthTotal (10 instances): 10 × 7.592 = 75.92 USD/monthExample 2: Mixed Resource Types
Section titled “Example 2: Mixed Resource Types”Resources:
- 5x EC2 t3.micro ($7.592/mo each)
- 3x RDS db.t3.micro ($24.82/mo each)
- 1x S3 bucket (100GB at $0.023/GB/mo)
Calculation:
EC2: 5 × 7.592 = 37.96 USD/monthRDS: 3 × 24.82 = 74.46 USD/monthS3: 100 × 0.023 = 2.30 USD/monthTotal: 37.96 + 74.46 + 2.30 = 114.72 USD/monthExample 3: Actual Cost with Grouping
Section titled “Example 3: Actual Cost with Grouping”Request:
finfocus cost actual \ --start-date 2024-01-01 \ --end-date 2024-01-31 \ --group-by dailyOutput:
Date | Cost (USD)-------------|------------2024-01-01 | 73.422024-01-02 | 74.182024-01-03 | 73.89...2024-01-31 | 72.95-------------|------------Total | 2,287.64Performance Considerations
Section titled “Performance Considerations”Plugin Caching
Section titled “Plugin Caching”Plugins are kept alive between requests to reduce startup overhead:
- First request: 100-500ms (plugin startup + API call)
- Subsequent requests: 10-50ms (API call only)
Parallel Processing
Section titled “Parallel Processing”Cost calculations for multiple resources are parallelized:
Sequential: 100 resources × 50ms = 5000msParallel (10 workers): 100 resources ÷ 10 × 50ms = 500msAPI Rate Limiting
Section titled “API Rate Limiting”Plugins implement rate limiting to avoid API throttling:
- Exponential backoff on rate limit errors
- Request queuing and batching
- Configurable rate limits per plugin
Related Documentation:
- System Overview - High-level architecture
- Plugin Protocol - gRPC protocol specification
- Cost Calculation Flow - Flow diagram
- Engine Implementation - Code details