Skip to main content

Shared Cost Allocation

Status: PLANNED — This feature is not yet implemented. The allocation_rules and allocated_costs tables, and the cost_allocator collector do not exist yet. This document is the design specification for future development.

Some costs don't belong to any single customer — NAT gateways in shared VPCs, the Marqo control plane, Polo itself, shared S3 buckets. Without explicit allocation, per-customer margins look artificially good because shared costs are invisible.

Allocation Methods

MethodHow it worksUse case
proportionalDistribute cost based on a metric (network bytes, instance count, existing cost)NAT gateway cost split by customer traffic volume
equalDivide evenly across all active targetsControl plane cost across all customers
fixed_pctAssign fixed percentages to specific targetsKnown cost-sharing agreements
overheadDon't allocate — bucket as platform overheadPolo's own infrastructure

Schema

allocation_rules

CREATE TABLE polo.allocation_rules
(
rule_id String,
rule_name String,
source_filter Map(String, String), -- what costs this applies to
method LowCardinality(String), -- 'proportional', 'equal', 'fixed_pct', 'overhead'
proportion_key String DEFAULT '', -- for proportional: 'network_bytes', 'instance_count', 'cost'
target_node_type LowCardinality(String), -- 'customer'
fixed_allocations Map(String, Float64) DEFAULT map(),
enabled UInt8 DEFAULT 1,
_version UInt64
)
ENGINE = ReplacingMergeTree(_version) ORDER BY (rule_id);

allocated_costs

CREATE TABLE polo.allocated_costs
(
day Date,
rule_id String,
source_arn String, -- the shared resource
target_node_id String, -- the customer/node allocated to
allocated_usd Float64,
method LowCardinality(String),
proportion Float64 -- fraction allocated (for auditability)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(day)
ORDER BY (day, target_node_id, source_arn);

Integration with Cost Rollups

The daily cost rollup job includes allocated costs in per-customer totals. The UI shows allocated vs direct cost separately so users understand how much of a customer's cost is direct infrastructure vs shared overhead.

Example Rules

-- Spread shared-account NAT costs by customer instance count
INSERT INTO polo.allocation_rules VALUES (
'nat-by-instances', 'NAT cost by instance count',
{'resource_type': 'vpc:nat_gateway', 'account_role': 'shared'},
'proportional', 'instance_count', 'customer', map(), 1, 1
);

-- Control plane cost divided equally
INSERT INTO polo.allocation_rules VALUES (
'control-plane-equal', 'Control plane overhead',
{'account_role': 'internal', 'marqo_purpose': 'control_plane'},
'equal', '', 'customer', map(), 1, 1
);

-- Polo's own costs as platform overhead (not allocated)
INSERT INTO polo.allocation_rules VALUES (
'polo-overhead', 'Polo infrastructure',
{'marqo_purpose': 'polo-infrastructure'},
'overhead', '', '', map(), 1, 1
);