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

推荐订阅源

Security Archives - TechRepublic
Security Archives - TechRepublic
罗磊的独立博客
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
Apple Machine Learning Research
Apple Machine Learning Research
The Register - Security
The Register - Security
J
Java Code Geeks
V2EX - 技术
V2EX - 技术
Vercel News
Vercel News
N
News and Events Feed by Topic
腾讯CDC
P
Proofpoint News Feed
N
News | PayPal Newsroom
www.infosecurity-magazine.com
www.infosecurity-magazine.com
爱范儿
爱范儿
O
OpenAI News
酷 壳 – CoolShell
酷 壳 – CoolShell
月光博客
月光博客
Martin Fowler
Martin Fowler
Engineering at Meta
Engineering at Meta
D
Docker
Y
Y Combinator Blog
博客园 - 聂微东
G
Google Developers Blog
S
Security @ Cisco Blogs
Simon Willison's Weblog
Simon Willison's Weblog
S
Schneier on Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
S
SegmentFault 最新的问题
云风的 BLOG
云风的 BLOG
阮一峰的网络日志
阮一峰的网络日志
C
CXSECURITY Database RSS Feed - CXSecurity.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
CERT Recently Published Vulnerability Notes
I
Intezer
G
GRAHAM CLULEY
有赞技术团队
有赞技术团队
Attack and Defense Labs
Attack and Defense Labs
V
Visual Studio Blog
博客园 - Franky
博客园 - 三生石上(FineUI控件)
W
WeLiveSecurity
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Hugging Face - Blog
Hugging Face - Blog
Scott Helme
Scott Helme
T
Troy Hunt's Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
L
LINUX DO - 最新话题
C
Cybersecurity and Infrastructure Security Agency CISA

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
Choosing Postgres, MongoDB, or DynamoDB: The 4 Questions That Actually Decide It
Gabriel Anha · 2026-04-26 · via DEV Community

Picture the startup CTO with a 14-tab spreadsheet comparing Postgres, MongoDB Atlas, DynamoDB, CockroachDB, and Aurora. Cost columns. Latency columns. Replication-lag columns. Three of the columns are wrong. Two of them are measuring different things under the same heading. The team picks DynamoDB because the spreadsheet has the most green cells in its row, and ten months later they are rebuilding the analytics path on Postgres because every cross-customer report requires a full table scan.

Feature matrices do not pick databases. The reason teams keep producing them is that the actual decision feels uncomfortable: it depends on what you know about your access patterns, your write semantics, your query mix, and whether you have a DBA. Four questions, in order, resolve about 80% of cases. The remaining 20% are the cases where you genuinely need both and end up with two stores.

The three options on the table:

  • Postgres — relational, mature, one of the few engines where you can change your mind later without rewriting your data layer. With pgvector 0.8 it now does ANN search well enough for most RAG workloads.
  • MongoDB — document store, Atlas dedicated tiers start around $57/month for M10 (AWS us-east-1, as of April 2026, per mongodb.com/pricing) and scale up smoothly. Schema flexibility that is sometimes a feature and sometimes a gun.
  • DynamoDB — key-value with an index sidecar, single-digit-ms reads at any scale. On-demand pricing is roughly $1.25 per million writes and $0.25 per million reads (us-east-1, as of April 2026, per the AWS DynamoDB pricing page), which is cheap until your access pattern requires GSIs — each GSI carries its own write cost, so a write fanned out across two or three indexes can multiply the effective per-write spend.

Here are the four questions.

Question 1: are your access patterns known up front, or exploratory?

This is the load-bearing question. Everything else routes through it.

DynamoDB tables are designed around access patterns. The partition key, sort key, and global secondary indexes are decisions you make on day one and live with forever. Adding a new query pattern after launch usually means a new GSI, a new write path, or a single-table redesign that effectively rewrites every row. If you cannot list the queries your service will serve at design time, DynamoDB will hurt you.

Postgres assumes you do not know your queries up front. You add an index when a query is slow. You add a column when a column is needed. The query planner re-optimizes on every statement. This is the freedom you trade away when you pick DynamoDB.

MongoDB sits in the middle. The schema is flexible: add a field, write code that reads it. Indexes are added without table rewrites. Aggregation pipelines handle the queries that do not fit the document model. You pay for that flexibility in operational complexity at scale, but you do not pay for it on day one.

Stable, high-throughput access patterns (session stores, feature flags, leaderboards): DynamoDB. Exploratory or product-driven patterns (every CRUD app, every dashboard, every B2B tool whose customers ask for new reports): Postgres. If you are between, MongoDB is a reasonable hedge.

Question 2: do you need strong consistency across multi-row writes?

If you charge a customer, decrement their balance, and write a transaction record, those three operations have to either all happen or all not happen. In Postgres, that is BEGIN; ...; COMMIT; and you go home. In MongoDB, you have multi-document transactions inside a replica set since 4.0, and they work, but they hold locks and they do not love long-running operations. In DynamoDB, you have TransactWriteItems with a per-call cap of 100 actions / 4 MB, and it counts as 2× the write capacity of the same writes done individually.

The honest version: Postgres is built for multi-row ACID and wears it lightly. MongoDB can do it. DynamoDB will let you do it, but the moment you depend on it you are working against the grain of the system.

If your writes are mostly single-row (a session, a counter, an event), the consistency question evaporates and the answer is whatever else the questions point to. If your writes are inherently multi-row (an order with line items, a transfer between accounts), Postgres is the path of least resistance, and you should pick MongoDB or DynamoDB only if Q1 forced you there and you are willing to write the saga.

Question 3: what is your single-key vs multi-attribute query mix?

DynamoDB is fast at single-key lookups and at single-key range scans. Its query model targets primary-key access; a request like "find all orders where status = pending AND amount > 100 AND placed_at > yesterday" — the multi-attribute filter any back-office tool needs — typically requires a GSI, a composite sort key, or a scan with filter expressions. You can model your way around it, but you are now denormalizing for queries you have not been asked yet, and the bill grows.

MongoDB is good at multi-attribute filters within a collection. Compound indexes work, the aggregation pipeline handles group-by, and you can run the filter without rebuilding the schema. In practice, an M30-class Atlas cluster has handled multi-attribute queries over multi-million-document collections in workloads I have shipped without sharding becoming the next problem; your mileage will vary with index design and document shape.

Postgres is good at all of this. It is the only one of the three where "join three tables and aggregate" is a normal sentence. If your read traffic includes ad-hoc queries (admin tools, analytics, internal dashboards), you are going to end up with Postgres in the stack one way or another, even if the operational store is something else.

The mix that points cleanly at DynamoDB: 90% single-key reads, the rest a small number of well-known secondary access patterns. The mix that points away: anything where a product manager might ask "can we filter by X" next quarter.

Question 4: do you operate the database yourself, or pay someone else?

The headcount question. The one nobody puts in the spreadsheet.

DynamoDB has no DBAs. You configure the table, set on-demand or provisioned, and AWS runs it. There is no failover to plan, no replica to size, no vacuum to schedule. The cost shows up as the AWS bill — and DynamoDB on-demand can be expensive at high steady throughput. A rough break-even against well-utilized provisioned capacity (derived from current on-demand vs provisioned rates, us-east-1 as of April 2026) lands somewhere around 15% of provisioned utilization; treat that as a back-of-the-envelope estimate, not a published number.

MongoDB Atlas is similar in spirit but more of an operational surface: you pick cluster tiers, you watch replica lag, you tune indexes, you pay attention to oplog size. An M30 dedicated cluster on AWS us-east-1 runs roughly $0.54/hour, or about $390/month (per mongodb.com/pricing, April 2026), before you add backups, multi-region, or analytics nodes. Manageable for a small team, but it is not zero work.

Postgres on RDS or Aurora is cheap for the throughput you get, but you make decisions other engines make for you — instance class, IOPS, vacuum, replication, failover testing. Self-hosted Postgres on EC2 is cheaper and even more work. The reward is that the database does more, so you can ship features without reaching for a second store.

If your team has zero database operations capacity and your workload fits the access pattern, DynamoDB. If you have one engineer who can own the database for an hour a week, Atlas or RDS works. If you have a real backend team, Postgres on RDS or Aurora is almost always the right call — it does the most work per store.

A decision script you can run

The four questions in code. Print the recommendation, print the reasons.

def ask(q: str) -> bool:
    return input(f"{q} ").strip().lower().startswith("y")


def recommend_db() -> None:
    print("Answer y/n.")
    known = ask("Known access patterns up front?")
    multi_row = ask("Need multi-row strong consistency?")
    multi_attr = ask("Multi-attribute / ad-hoc queries?")
    self_op = ask("Will you operate the DB yourself?")

    score = {"postgres": 0, "mongodb": 0, "dynamodb": 0}
    reasons = {"postgres": [], "mongodb": [], "dynamodb": []}

    if known:
        score["dynamodb"] += 2
        reasons["dynamodb"].append("stable access patterns")
    else:
        score["postgres"] += 2
        score["mongodb"] += 1
        reasons["postgres"].append("exploratory queries")

    if multi_row:
        score["postgres"] += 2
        reasons["postgres"].append("native multi-row ACID")
    else:
        score["dynamodb"] += 1
        score["mongodb"] += 1

    if multi_attr:
        score["postgres"] += 2
        score["mongodb"] += 1
        reasons["postgres"].append("ad-hoc filters")
        reasons["mongodb"].append("aggregation pipeline")
    else:
        score["dynamodb"] += 2
        reasons["dynamodb"].append("single-key dominant")

    if not self_op:
        score["dynamodb"] += 2
        reasons["dynamodb"].append("zero-ops managed")
    else:
        score["postgres"] += 1
        score["mongodb"] += 1

    # Print the full score so a tie is visible — max() resolves ties by
    # insertion order, which means Postgres wins silently otherwise.
    print(f"\nScores: {score}")
    top = max(score.values())
    tied = [db for db, s in score.items() if s == top]
    if len(tied) > 1:
        print(f"Tie between {tied}; defaulting to postgres as the safer pick.")
        pick = "postgres" if "postgres" in tied else tied[0]
    else:
        pick = tied[0]
    print(f"Recommendation: {pick}")
    for r in reasons[pick]:
        print(f"  - {r}")


if __name__ == "__main__":
    recommend_db()

Enter fullscreen mode Exit fullscreen mode

Run this on a real workload and the answer is rarely surprising. What it does is force the four questions to be answered separately rather than mashed together in a vague gut call. Most arguments about database choice are arguments where one person is answering Q1 and the other is answering Q4, and neither has noticed.

Two anti-patterns

"MongoDB because schema-less is faster." The schema does not go away when you remove it from the database. It moves into your application code, where it is enforced inconsistently by whichever engineer is on the keyboard that week. Three months in, the users collection has documents with seven different shapes, and the bug report is "sometimes the email field is missing." The right reason to pick MongoDB is that your data is genuinely document-shaped (nested, variable, hierarchical), and you want the database to handle that natively. "Schema-less is faster" is a story you tell on day one and pay for on day ninety.

"DynamoDB because Amazon." Picking DynamoDB because the rest of the stack is on AWS, with no other reason, is how teams end up redesigning their data model six months in. DynamoDB is a great fit when Q1 (known patterns), Q2 (single-row writes), and Q3 (single-key reads) all point at it. If only one of them points at it, you are going to fight the database. If none of them do, you have invented a problem that did not exist on Postgres.

The variant of this is "DynamoDB for serverless." Serverless apps run fine on Postgres with a connection pooler. The "Lambda-cold-start-with-Postgres-connections" argument was a real problem in 2019 and has been solved twice over since. RDS Proxy, Aurora Serverless, Neon, and Supabase all handle the connection problem. Pick the database for the access pattern, not the runtime.

When you end up with two

The honest end state for many systems is two databases. Postgres for the operational core: orders, users, the relational ground truth. DynamoDB or Redis for a high-throughput hot path: sessions, feature flags, leaderboards, rate-limit counters. MongoDB for a document-shaped subdomain: content, configuration, audit blobs.

This is not a failure of architecture. It is what happens when the four questions have different answers for different parts of the system. The mistake is picking one database for all of it because the spreadsheet said so.

The other mistake is picking three databases on day one because someone read the same paragraph above. Start with one. Add the second when a real workload makes the first one sweat. The team most likely to ship is the team with the fewest stores in production.


If this was useful

The Database Playbook goes through these decisions store by store — Postgres, MongoDB, DynamoDB, plus Redis, Cassandra, ClickHouse, and the vector engines — with the access-pattern modeling worked through end to end. If you are picking a database for something real and the decision keeps slipping, it is the longer version of this post.

Database Playbook