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

推荐订阅源

cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MyScale Blog
MyScale Blog
Microsoft Azure Blog
Microsoft Azure Blog
N
Netflix TechBlog - Medium
M
MIT News - Artificial intelligence
GbyAI
GbyAI
人人都是产品经理
人人都是产品经理
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园_首页
爱范儿
爱范儿
博客园 - 三生石上(FineUI控件)
L
LangChain Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
云风的 BLOG
云风的 BLOG
Y
Y Combinator Blog
L
LINUX DO - 热门话题
Project Zero
Project Zero
罗磊的独立博客
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
MongoDB | Blog
MongoDB | Blog
Spread Privacy
Spread Privacy
S
Schneier on Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
J
Java Code Geeks
P
Palo Alto Networks Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园 - Franky
T
Threat Research - Cisco Blogs
D
Docker
Hugging Face - Blog
Hugging Face - Blog
S
Securelist
Google DeepMind News
Google DeepMind News
T
The Exploit Database - CXSecurity.com
L
Lohrmann on Cybersecurity
月光博客
月光博客
V
Vulnerabilities – Threatpost
NISL@THU
NISL@THU
V
Visual Studio Blog
AWS News Blog
AWS News Blog
I
Intezer
T
The Blog of Author Tim Ferriss
P
Privacy International News Feed
T
Tor Project blog
F
Full Disclosure
P
Proofpoint News Feed
SecWiki News
SecWiki News
H
Heimdal Security Blog
Help Net Security
Help Net Security
The Hacker News
The Hacker News

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
MVCC Misconceptions: The Indie Hacker's Database Choice Dilemma
Mustafa ERBA · 2026-05-20 · via DEV Community

Database selection is a critical decision, especially for indie hackers developing their own projects. Often, technology choices are driven by PR, and the daily impact of fundamental mechanisms like MVCC (Multi-Version Concurrency Control) can be overlooked. However, this can lead to unexpected performance issues and surprises during the development process. In this post, I will share my experiences on what MVCC means in practice, how databases like PostgreSQL and SQLite behave in scenarios commonly faced by indie hackers, and the long-term implications of these choices.

For indie hackers, database selection is usually made based on immediate needs. Concerns like project scalability, maintenance costs, and potential performance bottlenecks might take a backseat in the initial stages. However, over time, as the application grows, these "small" technical details can determine the fate of a project. Understanding what MVCC is and why it's important is the first step to minimizing such risks.

What is MVCC and Why is it Important?

MVCC is a mechanism used in databases to manage concurrent access. Its core idea is to maintain different versions of data for each transaction. This allows one transaction to read or write data without blocking other transactions. In traditional locking-based systems, a read operation can block a write operation, and a write operation can block a read operation. MVCC reduces these blockages, enabling the database to achieve higher levels of concurrency.

This mechanism is vital, especially for high-traffic web applications and systems requiring intensive read/write operations. For example, in an e-commerce site, there might be transactions simultaneously updating product stock and user-facing transactions displaying products. Thanks to MVCC, product listing operations are not affected while stock updates occur, which positively impacts the user experience.

ℹ️ Key Benefits of MVCC

  • Increased concurrency
  • Reduced locking
  • Better read performance
  • More consistent read results

The operating principle of MVCC relies on tagging each row with timestamps or visibility maps. When a transaction reads a row, it sees the version of the row valid from the moment that transaction started. If another transaction updates the same row, a new version is created, and the old version is not immediately deleted. When these old versions are deleted depends on the database's garbage collection mechanism. This management of "old versions" is one of the most crucial practical aspects of MVCC and has a direct impact on performance.

PostgreSQL: A Robust MVCC Implementation

PostgreSQL is one of the databases that implements MVCC in the most advanced way. Every update or delete operation creates a new version of the row and does not immediately remove the old version. This is managed by structures like "transaction ID" and "visibility map". A transaction determines which row versions it can see based on its own transaction ID.

The most significant result of this approach is that PostgreSQL performs relatively well even in high-concurrency scenarios. While one user views a report (intensive read), another user can simultaneously place an order (intensive write). PostgreSQL, thanks to MVCC, isolates these two operations as much as possible. However, this is not a perfect solution; especially long-running transactions or frequently updated data increase the importance of the VACUUM operation.

💡 The Role of VACUUM in PostgreSQL

PostgreSQL uses the VACUUM command to clean up old data versions, called "dead tuples," to support MVCC. When VACUUM is not run or not run frequently enough, the database size increases, query performance decreases, and the statistics from the ANALYZE command become outdated. Even if autovacuum is enabled by default, manual adjustments or more frequent triggers might be necessary for heavily loaded systems.

While working on an ERP system for a manufacturing company, I encountered a scenario where the VACUUM operation was not running in a timely manner. Daily stock movements amounted to millions, and each movement created a new row version. autovacuum was running with default settings, but "dead tuples" were accumulating due to the heavy load. As a result, SELECT query performance dropped by up to 30%. To resolve the issue, I optimized database size and query times by reducing autovacuum parameters (especially autovacuum_vacuum_threshold and autovacuum_analyze_threshold) and using the VACUUM FULL command (with caution regarding disk space). This experience showed me how critical the "cleanup" operations behind the power of MVCC truly are.

SQLite: Simplicity and MVCC Limitations

SQLite is one of the first names that come to mind when talking about embedded and lightweight databases. Stored typically as a single file, this database is popular among indie hackers due to its extreme simplicity in setup and management. However, SQLite's MVCC implementation differs considerably from PostgreSQL's and has some limitations.

SQLite's default WAL (Write-Ahead Logging) mode helps it implement MVCC more effectively. In WAL mode, write operations are recorded in a separate file called sqlite-wal. This allows read and write operations to occur concurrently. That is, while one transaction writes data, other transactions can read data simultaneously. This offers a sufficient level of concurrency for many indie hacker projects.

However, due to SQLite's fundamental architecture, only one write operation can occur at a time. When multiple threads try to write to the same database file, one thread will lock the database file, and the others will have to wait. This can create a significant bottleneck, especially when the application's concurrent write load increases.

⚠️ Concurrent Write Limitations in SQLite

Because SQLite operates through a single database file, it supports only one write operation at a time. If multiple threads attempt to write concurrently, deadlocks and wait times become inevitable. This situation is a major disadvantage for applications with high write traffic.

I encountered this limitation in a project where I used SQLite as the local database for a mobile application I developed. The application was continuously recording sensor data in the background, and simultaneously, there were operations changing some settings from the user interface. Initially, everything seemed fine, but as concurrency increased, the database started locking frequently for write operations. The user interface would freeze, and recordings were delayed. As a solution, I tried queuing write operations and writing them to the database serially through a single thread. This largely resolved the problem but increased the application's complexity. This experience concretely showed me the concurrency limits underlying SQLite's simplicity.

MVCC and Trade-offs for Indie Hackers

While MVCC has become a cornerstone feature for many databases, it may not perfectly suit every application's needs. When choosing a database for indie hackers, the advantages and disadvantages of MVCC should be carefully evaluated.

Performance: MVCC can improve overall performance by increasing the concurrency of read and write operations. However, this improvement depends on how the database is structured, data volume, and query patterns. Advanced MVCC implementations like PostgreSQL offer excellent performance in complex scenarios, while in simpler systems like SQLite, locking mechanisms might be more prominent.

Storage Space: MVCC keeps multiple versions of data, which can increase storage space requirements, especially for frequently updated data. Regular execution of the VACUUM operation in PostgreSQL is critical for managing this issue. In SQLite, WAL mode also creates additional files, but this impact is generally not as pronounced as in PostgreSQL.

Complexity: The complex mechanisms of MVCC can make understanding and managing the database more challenging. Especially for beginners, these details can be confusing. PostgreSQL's MVCC requires more configuration and maintenance compared to SQLite's simplicity.

💡 Database Selection Guide for Indie Hackers

  • Simple, single-user projects: SQLite is usually sufficient. It's easy to set up and performs well in most scenarios.
  • Web applications requiring high concurrency: PostgreSQL is a more suitable option. It offers better performance due to its advanced MVCC implementation and scalability.
  • Data integrity and complex queries: PostgreSQL stands out with its ACID compliance and richer feature set.
  • Mobile applications (local data storage): SQLite is preferred for its small footprint and simplicity. However, consider concurrent write needs.

At one point, I was developing a web service that powered my financial calculators. Initially, I used SQLite as the database because I wanted to quickly build a prototype. However, as the project grew and more users started performing calculations simultaneously, SQLite's concurrent write limitations became evident. Queries slowed down, and sometimes I even encountered errors. At this point, I decided to switch to PostgreSQL. Although the migration process took some time, the concurrency and performance improvements provided by MVCC proved critical for the project's long-term success. This transition once again showed me how important it is to correctly evaluate trade-offs.

Real-World Scenarios and Performance Analyses

To better understand the practical implications of MVCC, let's look at examples from real-world scenarios. These scenarios will illustrate how different databases' MVCC mechanisms behave and their effects on performance.

Scenario 1: E-commerce Site Stock Management

On an e-commerce site, thousands of users are simultaneously viewing products while stocks are being updated in the background.

  • PostgreSQL: Thanks to MVCC, stock update operations (writes) do not largely block product viewing operations (reads). Users can smoothly view products while stocks are updated in the background. However, very frequent and large-scale stock updates might require VACUUM to run more often. For instance, if there are hundreds of stock updates per second during a sale campaign, the n_dead_tup (number of dead tuples) in the pg_stat_user_tables table can increase rapidly.
  • SQLite (WAL Mode): WAL mode enables concurrent reading and writing. However, if multiple stock update operations arrive simultaneously, these operations become serialized. If the system needs to perform 500 stock updates per second and each update takes an average of 10ms, SQLite might struggle to handle this load alone, and wait times could increase. Although settings like PRAGMA busy_timeout = 5000; exist, the fundamental locking mechanism will be limiting.

Scenario 2: Blog Comment System

On a blog site, readers comment on articles while editors add new articles or update existing ones.

  • PostgreSQL: MVCC seamlessly separates comment submission and article addition operations. When a user submits a comment, an editor adding a new article does not directly affect their transaction. pg_locks table typically shows only short-lived and specific locks.
  • SQLite: Similarly, with WAL mode, comment and article addition operations can run concurrently. However, if a large number of comments arrive simultaneously and attempt to be written to the database at the same time, SQLite's single write lock can come into play. This situation can lead to delayed comments or users receiving "database is locked" errors.

Scenario 3: Mobile Application Synchronization

A mobile application stores user data locally and synchronizes it with a server periodically.

  • SQLite: This is one of SQLite's most common use cases. While the application reads data, new data from the server can be synchronized in the background. WAL mode ensures this synchronization occurs without degrading the application's overall performance. However, if a large amount of data is being written during synchronization and, at the same time, data is being changed from the user interface, deadlocks can occur. In one project, I tried to manage these deadlocks using sqlite3_busy_handler during synchronization, but this increased the complexity of the code.

These scenarios demonstrate how MVCC can yield different results in various databases. For indie hackers, choosing the right database by considering the project's current and future needs is key to avoiding such performance bottlenecks.

Conclusion: A Pragmatic Approach

MVCC is a cornerstone of modern databases and a powerful mechanism for resolving concurrency issues. However, MVCC itself is not a magic wand. Application architecture, database selection, and configuration determine the extent to which the benefits of MVCC will be realized.

As indie hackers, our resources are often limited, and our time is valuable. Therefore, when choosing a database, it's essential to evaluate how well it fits the project's real needs, rather than just how "cool" the technology is. PostgreSQL, with its advanced MVCC capabilities and scalability, is a strong option for many scenarios, while SQLite's simplicity and lightweight nature can make it more suitable for specific use cases.

In my own experiences, I've seen that understanding the details of a database's MVCC implementation is critical for predicting and resolving performance issues. Topics like the importance of VACUUM in PostgreSQL or concurrent write limitations in SQLite, when overlooked early in a project, can become the source of major headaches later on.

In conclusion, understanding what MVCC is and what it means in practice will help indie hackers make more informed and strategic database choices. This not only optimizes the performance of current projects but also lays a solid foundation for future growth and scalability.