惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Register - Security
The Register - Security
A
About on SuperTechFans
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
LangChain Blog
N
Netflix TechBlog - Medium
量子位
博客园 - 三生石上(FineUI控件)
宝玉的分享
宝玉的分享
H
Help Net Security
D
Docker
D
DataBreaches.Net
T
Tailwind CSS Blog
阮一峰的网络日志
阮一峰的网络日志
B
Blog
博客园 - 聂微东
Apple Machine Learning Research
Apple Machine Learning Research
Google DeepMind News
Google DeepMind News
The Cloudflare Blog
F
Full Disclosure
GbyAI
GbyAI
F
Fortinet All Blogs
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
人人都是产品经理
人人都是产品经理
Recent Announcements
Recent Announcements
博客园 - Franky
MongoDB | Blog
MongoDB | Blog
有赞技术团队
有赞技术团队
博客园 - 叶小钗
小众软件
小众软件
V
Visual Studio Blog
月光博客
月光博客
Stack Overflow Blog
Stack Overflow Blog
The GitHub Blog
The GitHub Blog
Recorded Future
Recorded Future
J
Java Code Geeks
雷峰网
雷峰网
P
Privacy & Cybersecurity Law Blog
C
Cisco Blogs
C
Cyber Attacks, Cyber Crime and Cyber Security
AWS News Blog
AWS News Blog
Webroot Blog
Webroot Blog
美团技术团队
N
News | PayPal Newsroom
G
Google Developers Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
博客园_首页
V
Vulnerabilities – Threatpost

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Time-Series, Document, or Relational? The 5-Question Test Every New Project Needs
Gabriel Anha · 2026-04-27 · via DEV Community

Picture the IoT telemetry team that spends weeks moving multi-TB workloads from MongoDB to ClickHouse, watches a Grafana dashboard drop from 14 seconds to under 200 ms on an hourly aggregate, and confirms the migration was the right call. (Numbers illustrative; the shape of the win is the common one.)

Picture the other team, the one that moved customer profile data from Postgres to MongoDB after reading a blog post about "schema flexibility," and discovered every customer-facing query now needed two round-trips and a manual join in application code. An engineer I know rolled that exact migration back. The bill was paid in developer-weeks and one Friday-night incident.

The difference between those stories isn't which database is "better." It's whether the team asked the five questions below first. ClickHouse is excellent for IoT telemetry and bad for customer profiles. Postgres handles profiles cleanly and stays fine for telemetry up to a few TB. MongoDB shines on shape-flexible documents; cross-entity reporting will eat your weekend. Every "X is faster than Y" benchmark is true for that benchmark and silent about your project.

One independent comparison (sanj.dev, 2026) reports ClickHouse ingestion at 2-3M points/sec versus TimescaleDB at 100k-500k, and compression 10-30x better. The same comparison puts ClickHouse point-lookup latency at 15 ms versus TimescaleDB at 10 ms. Treat these as one data point, not consensus. The five questions:

Question 1: what's the dominant write shape?

The single most important question. Two extreme shapes:

Append-only timestamped events. A new row arrives every second (or every microsecond), no row is ever updated, and old rows are aged out by retention policy. IoT, application logs, financial ticks, observability metrics. Time is part of the primary key.

Mutable rows keyed by entity. A user updates their profile, an order moves through statuses, an inventory count adjusts. Rows have lifetimes measured in months or years and change tens of times. The primary key is an entity id, not a timestamp.

If your write shape is append-only and high-volume, time-series stores (TimescaleDB, ClickHouse, QuestDB, InfluxDB) are designed exactly for this. They use columnar storage, time-based partitioning, and aggressive compression that assumes rows are immutable. ClickHouse in particular achieves the compression and ingestion ratios it does by treating updates as a hostile case.

If your write shape is mutable, you want a row-store. Postgres and MariaDB are the boring correct answer for most workloads. They handle updates as a first-class operation, support transactions across rows, and won't punish you with a multi-second OPTIMIZE TABLE when an HR manager fixes a typo in a name field.

There's a middle case: mutable but mostly insert. Order events, audit trails, append-with-occasional-correction. As a rough rule of thumb, Postgres handles this until you cross the low-TB range of hot data, at which point TimescaleDB (Postgres-compatible, hypertable-partitioned) gives you append-shape performance without a migration.

Question 2: what's the read pattern?

Three rough buckets:

Range scans over time. "Average CPU per host over 24 hours, bucketed by minute." Time-series engines crush this. Columnar layout reads only the columns you aggregate, partition pruning skips data outside the range, pre-aggregations give sub-second response on million-point buckets.

Key lookups. "Get the user with id X." Row or KV stores: DynamoDB, Redis, Postgres with a btree index. ClickHouse is bad at this. Single-row lookups pay the columnar tax without any wins. Per the comparison cited above, the 15 ms vs 10 ms gap is real, and on a 200-lookup endpoint it's 1 second of latency you didn't budget.

Full-text or graph traversal. Postgres with pg_trgm or tsvector for moderate full-text. Elasticsearch or OpenSearch for serious search. Neo4j or Memgraph for traversal. Don't ask MongoDB's $graphLookup to scale: it tends to struggle at large dataset sizes — every team I've seen rely on it for cross-collection traversal at scale ended up moving the workload to a graph engine or denormalising into a single collection.

The trap: most projects have more than one read pattern. A telemetry platform needs range scans for dashboards and point lookups for "latest reading from this sensor." The hybrid setups described in the TimescaleDB/ClickHouse comparison split the workload: Postgres for hot operational data, with a ClickHouse replica for analytics. They exist because real systems can't pick one bucket.

Question 3: what are the consistency requirements?

Money: ACID, no exceptions. A relational database with transactions. Postgres, MariaDB, MySQL with InnoDB. The consistency story matters more than the analytics story. You can replicate to a warehouse later.

User-generated content where eventual consistency is fine: most document stores work. MongoDB, DynamoDB. The "I posted a comment and didn't see it for 200 ms" experience is acceptable.

Telemetry: you can usually tolerate the occasional dropped row, and "exactly-once" insert is a research project. ClickHouse and most time-series stores are eventually consistent on replicas; you tune for throughput, not correctness, and you handle dedup at ingest.

The honest version of this question: what's the cost of one wrong row? If the answer is "lawsuit" or "rollback the deploy," you need transactions. If the answer is "a noisy 5-minute bucket on a dashboard," you don't.

Question 4: what's the cardinality of unique series?

This question is specific to time-series and it's where teams get blindsided.

A "series" in time-series terminology is a unique combination of tags or labels. {host="web-01", region="us-east", service="api"} is one series; changing host to web-02 is a different series. Per CrateDB's comparison, tag-indexed time-series engines like InfluxDB degrade once active series climb into the millions, with the practical wall arriving earlier on modest hardware.

If you're tagging by user id, request id, or any high-cardinality dimension, you have a cardinality problem. ClickHouse handles billions of distinct series fine because tags are just columns. TimescaleDB handles tens of millions before you start tuning chunk intervals. Tag-indexed engines hit their wall well before that — your safe ceiling depends on hardware and tag layout, not a single magic number.

Easy check: estimate cardinality as roughly the product of distinct values across all tag dimensions. If users × endpoints × regions is above 10 million and one of those is "users", you do not want a tag-indexed time-series engine. You want a columnar store like ClickHouse, or a wide-column architecture, or to drop the user-id tag and join against a row store at query time.

Question 5: what's your operational headcount?

The question nobody asks until production wakes them up.

As a rough industry rule of thumb: managed Postgres on RDS or Cloud SQL runs at about 0.1 FTE. A self-hosted ClickHouse cluster with proper backup, monitoring, and version management lands at 0.5 to 1 FTE. Self-hosted Cassandra has historically been closer to 2. DynamoDB costs roughly nothing operationally, but it costs you the freedom to ever JOIN. Calibrate against your own ops surface; these are SRE-forum estimates, not measurements.

For dollar costs, one third-party pricing comparison (illustrative, sourced ~2024; confirm current vendor pricing before you act on it) puts 10M reads / 2M writes / 50 GB at roughly: DynamoDB on-demand ~$105/mo, MongoDB Atlas M30 ~$330, DynamoDB reserved ~$45. Postgres pricing was not in that source — for managed Postgres, expect a comparable 50 GB instance on RDS or Cloud SQL to land in the same low-to-mid hundreds, depending on instance class. Add engineer-weeks and the picture shifts.

The pattern that's killed more startups than wrong technology: a 4-person team adopts ClickHouse because it's "right" for telemetry and discovers the on-call rotation is one of the four, full-time.

If you're a 3-person team building anything that doesn't demonstrably break Postgres, the answer is Postgres. With JSONB. With TimescaleDB if you have time-series. Postgres isn't best at any one thing. One team member can run it.

A small decision script

Here's the decision flow as runnable pseudocode. Change the inputs to match your project. Read the output. Argue with it before you migrate.

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

Enter fullscreen mode Exit fullscreen mode

Three example app shapes through that function:

IoT telemetry, 50k devices, 1 reading/sec, dashboards over hours-to-weeks. append_only, range, eventual, ~50k cardinality, 0.5 FTE. Output: ClickHouse. The cardinality is comfortable, the read pattern is range-heavy, and the ingestion rate (50k points/sec) sits in ClickHouse's sweet spot. TimescaleDB would handle it too, but expect noticeably higher storage cost — the same independent comparison cited earlier puts ClickHouse compression 10-30x ahead.

E-commerce: customers, orders, products, returns, with admin dashboards. mutable, mixed (key for product page, range for "orders this week"), acid, cardinality N/A, 0.5 FTE. Output: Postgres. Everything you need is in Postgres: JSONB for product attributes, partial indexes for hot queries, materialized views for the dashboards. Don't move to MongoDB, don't move to DynamoDB. You are not at the scale where the migration pays off. You may never be.

Analytics warehouse for a 200-person SaaS, daily ETL from app DB plus event tracking. append_only from the events side, mixed overall, eventual, low-to-moderate cardinality, 0.3 FTE. Output: managed BigQuery, Snowflake, or ClickHouse Cloud. The 0.3 FTE rules out self-hosted. Pick by pricing model: BigQuery for spiky workloads, Snowflake for steady ones, ClickHouse Cloud if your SQL team is already used to ClickHouse syntax.

The pattern under all five questions

The five questions are really one meta-question: does my workload fit the assumptions the database was designed under? Time-series engines assume immutable, time-keyed data and reward you for it; punish them with updates and they crawl. Relational engines assume normalized rows and reward you with consistency; punish them with 50 TB of telemetry and they'll need babysitting.

Every clean migration started by asking the five questions and getting a different answer than the team's gut. Every horror story skipped that step.

If this was useful

The Database Playbook covers each store family (relational, document, time-series, KV, search) with the workload signatures, the migration cost, and the operational quirks that don't make it into the marketing pages. If you're picking storage for a new project this quarter, it's the short read that saves you from the migration you'll otherwise do twelve months in.