$ from dataclasses import dataclass
from typing import Literal @dataclass
class Workload: write_shape: Literal["append_only", "mutable", "mixed"] read_pattern: Literal["range", "key", "fulltext", "mixed"] consistency: Literal["acid", "eventual"] series_cardinality: int # only meaningful for time-series ops_headcount: float # FTE you can dedicate to the DB def recommend(w: Workload) -> str: # Branch 1: ACID money/orders/accounts. Stop trying to be clever. if w.consistency == "acid": if w.write_shape == "append_only" and w.ops_headcount >= 0.5: return "Postgres + TimescaleDB extension" return "Postgres (managed)" # Branch 2: append-only telemetry. Cardinality and ops budget pick the engine. if w.write_shape == "append_only": if w.series_cardinality > 10_000_000: return "ClickHouse" if w.ops_headcount >= 1 else "BigQuery" if w.ops_headcount < 0.5: return "TimescaleDB on managed Postgres" return "ClickHouse" if w.read_pattern == "range" else "TimescaleDB" # Branch 3: mutable rows. Read pattern decides the row store. if w.write_shape == "mutable": if w.read_pattern == "key" and w.ops_headcount < 0.2: return "DynamoDB" if w.read_pattern == "fulltext": return "Postgres + tsvector (or OpenSearch if heavy)" return "Postgres" # Branch 4: mixed write shape. Default to Postgres unless you have ops budget. if w.ops_headcount < 1: return "Postgres + TimescaleDB extension" return "Postgres for hot data, ClickHouse replica for analytics" print(recommend(Workload( write_shape="append_only", read_pattern="range", consistency="eventual", series_cardinality=2_000_000, ops_headcount=0.3,
)))
# -> TimescaleDB on managed Postgres
from dataclasses import dataclass
from typing import Literal @dataclass
class Workload: write_shape: Literal["append_only", "mutable", "mixed"] read_pattern: Literal["range", "key", "fulltext", "mixed"] consistency: Literal["acid", "eventual"] series_cardinality: int # only meaningful for time-series ops_headcount: float # FTE you can dedicate to the DB def recommend(w: Workload) -> str: # Branch 1: ACID money/orders/accounts. Stop trying to be clever. if w.consistency == "acid": if w.write_shape == "append_only" and w.ops_headcount >= 0.5: return "Postgres + TimescaleDB extension" return "Postgres (managed)" # Branch 2: append-only telemetry. Cardinality and ops budget pick the engine. if w.write_shape == "append_only": if w.series_cardinality > 10_000_000: return "ClickHouse" if w.ops_headcount >= 1 else "BigQuery" if w.ops_headcount < 0.5: return "TimescaleDB on managed Postgres" return "ClickHouse" if w.read_pattern == "range" else "TimescaleDB" # Branch 3: mutable rows. Read pattern decides the row store. if w.write_shape == "mutable": if w.read_pattern == "key" and w.ops_headcount < 0.2: return "DynamoDB" if w.read_pattern == "fulltext": return "Postgres + tsvector (or OpenSearch if heavy)" return "Postgres" # Branch 4: mixed write shape. Default to Postgres unless you have ops budget. if w.ops_headcount < 1: return "Postgres + TimescaleDB extension" return "Postgres for hot data, ClickHouse replica for analytics" print(recommend(Workload( write_shape="append_only", read_pattern="range", consistency="eventual", series_cardinality=2_000_000, ops_headcount=0.3,
)))
# -> TimescaleDB on managed Postgres
from dataclasses import dataclass
from typing import Literal @dataclass
class Workload: write_shape: Literal["append_only", "mutable", "mixed"] read_pattern: Literal["range", "key", "fulltext", "mixed"] consistency: Literal["acid", "eventual"] series_cardinality: int # only meaningful for time-series ops_headcount: float # FTE you can dedicate to the DB def recommend(w: Workload) -> str: # Branch 1: ACID money/orders/accounts. Stop trying to be clever. if w.consistency == "acid": if w.write_shape == "append_only" and w.ops_headcount >= 0.5: return "Postgres + TimescaleDB extension" return "Postgres (managed)" # Branch 2: append-only telemetry. Cardinality and ops budget pick the engine. if w.write_shape == "append_only": if w.series_cardinality > 10_000_000: return "ClickHouse" if w.ops_headcount >= 1 else "BigQuery" if w.ops_headcount < 0.5: return "TimescaleDB on managed Postgres" return "ClickHouse" if w.read_pattern == "range" else "TimescaleDB" # Branch 3: mutable rows. Read pattern decides the row store. if w.write_shape == "mutable": if w.read_pattern == "key" and w.ops_headcount < 0.2: return "DynamoDB" if w.read_pattern == "fulltext": return "Postgres + tsvector (or OpenSearch if heavy)" return "Postgres" # Branch 4: mixed write shape. Default to Postgres unless you have ops budget. if w.ops_headcount < 1: return "Postgres + TimescaleDB extension" return "Postgres for hot data, ClickHouse replica for analytics" print(recommend(Workload( write_shape="append_only", read_pattern="range", consistency="eventual", series_cardinality=2_000_000, ops_headcount=0.3,
)))
# -> TimescaleDB on managed Postgres - Book: Database Playbook
- My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools
- Me: xgabriel.com | GitHub