Multi-Version Concurrency Control Explained
Snapshot isolation, transaction IDs and cleanup demystified
Imagine a database system where readers never block writers, writers never block readers, and your application scales effortlessly under heavy concurrent load.
238 pages11 chaptersDec 23, 2025Databases
About this book
Multi-Version Concurrency Control makes this possible by maintaining multiple versions of data and allowing transactions to work with consistent snapshots. This comprehensive guide takes you from foundational concepts to production-ready implementation strategies. You'll learn how MVCC eliminates traditional locking bottlenecks, understand the intricate mechanics of version visibility and isolation levels, and discover how to optimize your database for maximum performance. Whether you're designing a new system, troubleshooting concurrency issues, or preparing for high-scale deployments, this book provides the practical knowledge and architectural insights you need to master MVCC and build databases that truly scale.
Table of contents
- IntroductionWhy Concurrency Control Matters, The Limitations of Traditional Locking, What MVCC Offers: A New Approach, How to Use This BookRead below
- Chapter 1: Concurrency FundamentalsUnderstanding Transactions and ACID Properties, Common Concurrency Problems: Dirty Reads, Lost Updates, and Phantoms, Isolation Levels and Their Trade-offs
- Chapter 2: Traditional Locking MechanismsLock Types: Shared, Exclusive, and Intent Locks, Deadlock Detection and Prevention, Performance Bottlenecks in Lock-Based Systems
- Chapter 3: MVCC Architecture and Core ConceptsCore Principles of Multi-Version Concurrency Control, How Versions Are Stored and Managed, Version Visibility Rules and Snapshot Consistency
- Chapter 4: Transaction IDs and Timestamp ManagementTransaction ID Allocation Strategies, Timestamp-Based Ordering and Snapshot Assignment, Clock Synchronization in Distributed Systems
- Chapter 5: Snapshot Isolation and ConsistencyUnderstanding Snapshot Isolation, Detecting and Handling Read-Write Conflicts, Serialization Anomalies and How to Prevent Them
- Chapter 6: Garbage Collection and Version CleanupGarbage Collection Strategies and Algorithms, Managing Transaction Bloat and Long-Running Transactions, Storage Optimization and Cleanup Efficiency
- Chapter 7: MVCC in PostgreSQLPostgreSQL's MVCC Implementation, Visibility Maps and HOT Updates, Tuning PostgreSQL for MVCC Performance
- Chapter 8: MVCC in MySQL and InnoDBInnoDB's MVCC and Undo Log Design, Isolation Levels in InnoDB, Optimizing InnoDB for Concurrent Workloads
- Chapter 9: MVCC in Other Database SystemsOracle's Approach to MVCC and Undo Segments, MVCC in Modern Databases: CockroachDB, TiDB, and Others, Comparing MVCC Implementations Across Systems
- Chapter 10: Performance Tuning and OptimizationKey Metrics for Monitoring MVCC Performance, Critical MVCC Parameters and Tuning Strategies, Advanced Optimization Techniques for High Concurrency
- Chapter 11: Troubleshooting and Common IssuesDiagnosing MVCC-Related Performance Issues, Common Pitfalls and How to Avoid Them, Real-World Case Studies and Solutions
- ConclusionKey Takeaways and Best Practices, The Future of Concurrency Control
- Glossary
- Further Reading and Resources
Introduction
Modern applications demand databases that can handle hundreds or thousands of concurrent users without grinding to a halt. Every time someone checks their bank balance while another person transfers money, or when multiple customers simultaneously purchase the last item in stock, your database faces a fundamental challenge: how to maintain data consistency while allowing multiple operations to proceed at the same time. The solution to this challenge determines whether your application scales gracefully or collapses under load. Multi-Version Concurrency Control represents one of the most elegant and powerful approaches to this problem, fundamentally changing how databases handle concurrent access.
Traditional database systems rely heavily on locks to coordinate access between competing transactions. When one transaction needs to modify data, it acquires a lock that prevents others from accessing that same data until the modification completes. This approach works, but it creates bottlenecks that become increasingly severe as concurrency increases. MVCC takes a radically different approach: instead of blocking readers when writers are active, it maintains multiple versions of data and allows each transaction to work with a consistent snapshot. This architectural shift eliminates many of the performance bottlenecks that plague lock-based systems, enabling databases to scale to levels that would be impossible with traditional locking alone.
This book provides a comprehensive exploration of MVCC from foundational concepts to production implementation strategies. You'll learn not just what MVCC is, but how it works at a deep technical level, why certain design decisions matter, and how to apply this knowledge to build and optimize real database systems. Whether you're troubleshooting performance issues in an existing system, designing a new database architecture, or preparing for high-scale deployments, understanding MVCC is essential. The concepts and techniques covered here apply across multiple database systems, from PostgreSQL and MySQL to Oracle and modern distributed databases, giving you knowledge that transfers across platforms and technologies.
Why Concurrency Control Matters
Concurrency control sits at the heart of every multi-user database system. Without proper concurrency mechanisms, databases would be forced to process transactions one at a time, serializing all operations and creating massive performance bottlenecks. Consider an e-commerce platform during a flash sale: thousands of users simultaneously browse products, add items to carts, and complete purchases. Each of these operations involves multiple database reads and writes. If the database could only handle one operation at a time, response times would stretch from milliseconds to minutes, and the system would effectively be unusable. Concurrency control makes it possible for all these operations to proceed simultaneously while maintaining data integrity.
The challenge of concurrency control becomes apparent when you consider what can go wrong without it. Imagine two users attempting to purchase the last item in stock at exactly the same moment. Both transactions read the inventory count, see one item available, and proceed to complete the purchase. Without proper concurrency control, both transactions succeed, and you've now sold an item you don't have. This scenario, known as a lost update, represents just one of several concurrency anomalies that can corrupt data and violate business rules. Other problems include dirty reads (reading uncommitted changes from other transactions), non-repeatable reads (getting different results when reading the same data twice), and phantom reads (seeing different sets of rows in repeated queries).
The performance implications of concurrency control extend far beyond simple throughput numbers. Poor concurrency control creates cascading effects throughout your entire application stack. When database operations block waiting for locks, application threads sit idle, connection pools fill up, and response times spike. Users experience timeouts and errors, retry their operations, and create even more load on an already struggling system. In extreme cases, deadlocks occur when transactions wait for each other in a circular dependency, forcing the database to abort transactions and roll back work. These issues don't just affect performance—they directly impact user experience, revenue, and system reliability.
Modern applications have pushed concurrency requirements to unprecedented levels. Cloud-based systems serve global user bases across multiple time zones, creating 24/7 peak load conditions. Microservices architectures multiply the number of concurrent database connections as each service maintains its own connection pool. Real-time analytics workloads run alongside transactional operations, creating mixed workloads where long-running analytical queries compete with short transactional updates. Mobile applications with offline capabilities synchronize changes when connectivity returns, creating bursts of concurrent write operations. All of these trends increase the importance of efficient concurrency control mechanisms.
The business impact of concurrency control decisions manifests in concrete ways. A financial services company processing millions of transactions per day needs absolute consistency—no lost updates, no phantom reads, no data corruption. An e-commerce platform prioritizes availability and responsiveness, accepting some eventual consistency in exchange for better performance. A social media application handles massive read loads with occasional writes, requiring different optimization strategies than a write-heavy system. Understanding concurrency control allows you to make informed trade-offs between consistency, availability, and performance based on your specific requirements. These aren't just technical decisions—they're business decisions that affect user satisfaction, operational costs, and competitive advantage.
Concurrency control also determines how your database scales as load increases. Some concurrency mechanisms scale linearly with additional hardware resources, while others hit fundamental bottlenecks that no amount of hardware can overcome. Lock-based systems often encounter contention hotspots where multiple transactions compete for the same locks, creating serialization points that limit scalability. MVCC-based systems avoid many of these bottlenecks but introduce different challenges around version storage and garbage collection. Understanding these scaling characteristics helps you predict how your system will behave under increasing load and plan capacity accordingly. The concurrency control mechanism you choose today will influence your system's scalability for years to come.
The complexity of concurrency control increases dramatically in distributed database systems. When data is partitioned across multiple nodes, coordinating transactions that span multiple partitions requires distributed consensus protocols and careful management of transaction isolation. Network latency adds delays that amplify the cost of coordination. Clock skew between nodes complicates timestamp-based ordering. Partial failures require sophisticated recovery mechanisms. Despite these challenges, distributed databases have become increasingly common as applications scale beyond what a single node can handle. Modern MVCC implementations address these distributed challenges with techniques like hybrid logical clocks, distributed snapshot isolation, and optimistic concurrency control, extending MVCC's benefits to distributed environments.
The Limitations of Traditional Locking
Traditional lock-based concurrency control operates on a simple principle: when a transaction needs to access data, it acquires a lock that prevents conflicting access by other transactions. Readers acquire shared locks that allow other readers but block writers. Writers acquire exclusive locks that block both readers and other writers. This approach provides strong consistency guarantees and is relatively straightforward to reason about. However, it creates fundamental performance bottlenecks that become increasingly severe as concurrency increases. Every lock acquisition represents a potential point of contention where transactions must wait, and these wait times accumulate to create significant performance degradation under high load.
The most obvious limitation of locking is that readers block writers and writers block readers. Consider a reporting query that scans millions of rows to generate a monthly summary. While this query runs, holding shared locks on the data it reads, any transaction attempting to update that data must wait. In a busy system, this means that long-running analytical queries can effectively freeze transactional processing, forcing you to choose between running reports and maintaining acceptable transaction response times. Many organizations resort to maintaining separate reporting databases or running reports only during off-peak hours, adding complexity and cost to work around this fundamental limitation of lock-based concurrency control.
Lock contention creates unpredictable performance characteristics that make capacity planning difficult. Under light load, transactions acquire locks immediately and complete quickly. As load increases, transactions begin waiting for locks, and wait times grow non-linearly. A system that handles 100 transactions per second with millisecond response times might struggle to handle 150 transactions per second, with response times jumping to seconds or even minutes. This non-linear scaling behavior makes it difficult to predict how your system will perform under increased load. You can't simply extrapolate from current performance—you need to understand the contention patterns and identify potential hotspots before they become problems in production.
Deadlocks represent another significant challenge in lock-based systems. A deadlock occurs when two or more transactions wait for each other in a circular dependency, creating a situation where none of them can proceed. For example, Transaction A holds a lock on row X and waits for a lock on row Y, while Transaction B holds a lock on row Y and waits for a lock on row X. Neither transaction can proceed, and the database must detect this situation and abort one of the transactions to break the cycle. Deadlock detection adds overhead, and deadlock resolution forces applications to handle transaction aborts and implement retry logic. In systems with complex transaction patterns, deadlocks can become frequent enough to significantly impact performance and reliability.
Lock escalation introduces another layer of complexity and potential performance problems. To reduce the memory overhead of tracking individual row locks, databases often escalate from row-level locks to page-level or table-level locks when a transaction holds too many locks. While this reduces memory consumption, it dramatically increases contention by locking more data than the transaction actually needs. A transaction that updates 10,000 rows in a table might trigger lock escalation and acquire a table-level lock, blocking all other transactions attempting to access any row in that table. This creates a situation where the database's own optimization mechanism becomes a source of performance problems, and tuning lock escalation thresholds becomes yet another parameter to manage.
The overhead of lock management itself becomes significant in high-concurrency systems. Every lock acquisition and release requires coordination through shared data structures that must be protected by latches (lightweight locks used internally by the database). These latches create their own contention points, and the CPU overhead of lock management can become substantial. In extreme cases, the database spends more time managing locks than actually processing transactions. This overhead is particularly problematic for short transactions that access small amounts of data—the lock management overhead can exceed the actual work being done. Profiling lock-based systems often reveals that a significant portion of CPU time goes to lock management rather than useful work.
Lock-based systems also struggle with priority inversion problems, where high-priority transactions wait for locks held by low-priority transactions. Imagine a critical transaction that needs to complete quickly waiting for a lock held by a long-running batch job. The database has no inherent mechanism to prioritize the critical transaction—it simply waits in line like any other transaction. Some databases provide lock timeout mechanisms or priority-based scheduling, but these add complexity and don't fully solve the fundamental problem. In systems with mixed workloads combining short transactional operations and long analytical queries, priority inversion can cause critical transactions to miss their latency targets, impacting user experience and business operations.
Real-world example: A major financial services company experienced severe performance degradation during month-end processing. Their lock-based database system handled normal daily transaction volumes without issues, processing thousands of transactions per second with sub-second response times. However, month-end batch jobs that calculated account balances and generated statements created massive lock contention. These jobs acquired locks on customer account records while performing complex calculations, blocking online transactions from accessing those same accounts. Response times for online transactions spiked from milliseconds to tens of seconds, causing timeouts and customer complaints. The company was forced to schedule month-end processing during maintenance windows, limiting their ability to offer 24/7 service and requiring complex coordination between operations teams.
What MVCC Offers: A New Approach
Multi-Version Concurrency Control fundamentally reimagines how databases handle concurrent access by maintaining multiple versions of data rather than forcing transactions to coordinate through locks. When a transaction reads data, it sees a consistent snapshot of the database as it existed at a specific point in time, regardless of what other transactions are doing. When a transaction modifies data, it creates a new version rather than overwriting the existing version. This approach allows readers and writers to operate simultaneously without blocking each other, eliminating one of the primary bottlenecks in lock-based systems. The elegance of MVCC lies in its ability to provide strong consistency guarantees while dramatically improving concurrency.
The core insight behind MVCC is that most concurrency conflicts are unnecessary. In a lock-based system, a reader blocks a writer even though the reader doesn't care about changes that haven't been committed yet—it just wants to see a consistent view of the data. MVCC recognizes this and gives each transaction its own consistent snapshot. A transaction that starts at time T sees the database exactly as it existed at time T, even if other transactions are simultaneously modifying data. This snapshot isolation eliminates the need for readers to acquire locks, allowing read operations to proceed without any coordination overhead. The performance implications are dramatic: read-heavy workloads that would be severely bottlenecked in lock-based systems can scale nearly linearly with MVCC.
MVCC's approach to write operations is equally sophisticated. When a transaction modifies a row, it doesn't overwrite the existing version—instead, it creates a new version with a timestamp or transaction ID indicating when it was created. The old version remains available for transactions that started before the modification. This versioning strategy means that writers don't block readers: a transaction reading data sees the version that was current when it started, while a concurrent writer creates a new version that won't be visible to the reading transaction. Only write-write conflicts require coordination, and even these can often be handled optimistically, allowing transactions to proceed without acquiring locks and only checking for conflicts at commit time.
The visibility rules that determine which version of data each transaction sees are central to MVCC's correctness. Each transaction receives a snapshot timestamp when it starts, and it can only see versions created by transactions that committed before that timestamp. This ensures that each transaction sees a consistent view of the database—it never sees partial results from uncommitted transactions, and it always sees a state that actually existed at some point in time. These visibility rules are implemented efficiently using transaction IDs and version metadata stored alongside each data version. The database can quickly determine which version is visible to a given transaction without scanning through all versions or acquiring locks.
MVCC enables isolation levels that would be prohibitively expensive in lock-based systems. Snapshot isolation, the most common isolation level in MVCC systems, provides a strong consistency guarantee: each transaction sees a consistent snapshot of the database, and write-write conflicts are detected and prevented. This isolation level prevents most concurrency anomalies while maintaining excellent performance. Some MVCC systems also support serializable isolation, the strongest isolation level, using techniques like serializable snapshot isolation (SSI) that detect potential conflicts and abort transactions when necessary. These isolation levels provide application developers with clear consistency guarantees without requiring them to understand complex locking protocols.
The performance characteristics of MVCC differ fundamentally from lock-based systems. Read operations scale almost linearly with hardware resources because they don't require coordination with writers. Long-running analytical queries can coexist with high-throughput transactional workloads without causing mutual interference. Response times remain predictable even under high load because transactions don't wait for locks. However, MVCC introduces its own challenges: maintaining multiple versions consumes storage space, and old versions must be garbage collected to prevent unbounded growth. Write-heavy workloads can create version bloat that degrades performance if not managed properly. Understanding these trade-offs is essential for effectively deploying MVCC systems.
MVCC's benefits extend beyond raw performance to operational simplicity and system reliability. Deadlocks become much less common because readers never acquire locks, eliminating a major source of circular dependencies. Priority inversion problems are reduced because high-priority read transactions don't wait for locks held by low-priority transactions. The predictable performance characteristics make capacity planning more straightforward—you can more reliably extrapolate from current performance to predict behavior under increased load. These operational benefits translate to reduced complexity in application code, fewer production incidents, and more reliable service delivery. The combination of performance improvements and operational simplicity makes MVCC attractive for a wide range of applications.
Practical comparison: Consider a social media application with 10 million active users. In a lock-based system, every time a user views their feed (a read operation), the database must acquire shared locks on potentially thousands of rows representing posts, comments, and user profiles. If another user simultaneously posts new content (a write operation), that transaction must wait for all those shared locks to be released. During peak hours with thousands of concurrent users, lock contention becomes severe, and response times degrade. With MVCC, read operations don't acquire locks at all—each user sees a consistent snapshot of their feed without blocking writers. New posts create new versions without blocking readers. The system scales to handle peak load without the lock contention bottlenecks that would cripple a lock-based implementation.
How to Use This Book
This book is structured to build your understanding of MVCC progressively, from foundational concepts to advanced implementation details and optimization techniques. The early chapters establish the context and fundamentals you need to understand why MVCC exists and how it differs from traditional approaches. The middle chapters dive deep into MVCC's internal mechanisms, exploring how different database systems implement versioning, visibility rules, and garbage collection. The later chapters focus on practical concerns: performance tuning, troubleshooting, and real-world implementation strategies. You can read the book sequentially for a comprehensive education, or jump to specific chapters that address your immediate needs.
Chapters 1 and 2 provide essential background on concurrency control fundamentals and traditional locking mechanisms. If you're already familiar with ACID properties, isolation levels, and lock-based concurrency control, you might skim these chapters or use them as reference material. However, even experienced database professionals often find value in revisiting these fundamentals, as they provide the context for understanding MVCC's advantages and trade-offs. These chapters establish a common vocabulary and conceptual framework that the rest of the book builds upon. They also highlight specific problems with lock-based systems that MVCC addresses, making the motivation for MVCC's design decisions clear.
Chapters 3 through 6 form the technical core of the book, explaining how MVCC actually works. Chapter 3 introduces MVCC's architecture and core concepts, including version storage and visibility rules. Chapter 4 explores transaction ID management and timestamp allocation, which are critical to MVCC's correctness and performance. Chapter 5 examines snapshot isolation in detail, including how different types of conflicts are detected and handled. Chapter 6 addresses garbage collection and version cleanup, operational concerns that directly impact MVCC performance in production. These chapters contain the deep technical knowledge you need to understand MVCC at a fundamental level, regardless of which specific database system you're working with.
Chapters 7 through 9 examine how specific database systems implement MVCC, providing concrete examples of the concepts introduced earlier. Chapter 7 focuses on PostgreSQL, one of the most widely used open-source databases with a sophisticated MVCC implementation. Chapter 8 covers MySQL's InnoDB storage engine, which takes a different approach to MVCC with distinct trade-offs. Chapter 9 surveys MVCC implementations in Oracle, CockroachDB, TiDB, and other systems, highlighting the diversity of approaches and the reasoning behind different design decisions. These chapters are valuable even if you work primarily with one database system, as understanding different implementations deepens your conceptual understanding and helps you recognize which approaches work best for different use cases.
Chapters 10 and 11 shift focus to practical operational concerns. Chapter 10 covers performance tuning and optimization, including which metrics to monitor, how to interpret them, and which parameters to adjust for different workloads. This chapter provides actionable guidance you can apply immediately to improve performance in production systems. Chapter 11 addresses troubleshooting, walking through common MVCC-related problems, their symptoms, and their solutions. This chapter includes real-world case studies that illustrate how MVCC issues manifest in practice and how to resolve them. These chapters are particularly valuable for database administrators and operations teams responsible for maintaining MVCC systems in production.
Throughout the book, you'll find several types of supplementary content designed to reinforce key concepts and provide practical context:
- Code examples and configuration snippets demonstrate specific techniques and settings you can apply in your own systems
- Blockquotes highlighting real-world scenarios illustrate how MVCC concepts play out in production environments
- Performance comparisons and benchmarks quantify the impact of different approaches and configurations
- Diagrams and visual representations clarify complex concepts and system architectures
- Footnotes and references point to academic papers, documentation, and additional resources for deeper exploration
The book assumes you have intermediate knowledge of database systems, including familiarity with SQL, basic understanding of database architecture, and some experience working with production database systems. You don't need to be a database internals expert, but you should be comfortable with concepts like transactions, indexes, and query execution. If you're new to databases, consider supplementing this book with introductory material on database fundamentals. If you're an experienced database professional, you'll find that the book goes deep enough to satisfy your curiosity about internal mechanisms while remaining practical and applicable to real-world problems.
As you read, consider how the concepts apply to your specific context. Are you designing a new system where you can choose the database and configure it optimally for MVCC? Are you troubleshooting performance issues in an existing system? Are you evaluating different database systems for a new project? The book provides knowledge applicable to all these scenarios, but you'll get the most value by actively connecting the concepts to your own challenges and opportunities. Take notes on specific techniques you want to try, parameters you want to adjust, or monitoring metrics you want to track. The goal isn't just to understand MVCC intellectually, but to apply that understanding to build better database systems.
Finally, remember that MVCC is a tool, not a silver bullet. It solves certain problems elegantly while introducing new challenges. The best database architecture for your application depends on your specific requirements, workload characteristics, and operational constraints. This book gives you the knowledge to make informed decisions about when and how to use MVCC effectively. By understanding both the benefits and the limitations, you'll be equipped to design systems that leverage MVCC's strengths while mitigating its weaknesses. The journey from understanding MVCC conceptually to implementing it effectively in production is substantial, but the performance and scalability benefits make it worthwhile for systems that demand high concurrency.
This is the end of the free sample. The full book has 11 chapters.
Want this book written for you?
Tell us your goals and background, and get your own version of this book, tailored by AI to you.
Benefits of AI-tailored books
- Read one book, not ten:
- all the Databases knowledge you need, gathered into a single book.
- Save days of learning:
- tell us your goals, choose your topics, and the whole book is built around them.
- Learn effortlessly:
- Databases book written for your specific background and expertise.
- Understand at a glance:
- includes charts, tables, timelines, checklists, decision trees, and more.
- Stay current:
- written the day you order it, not years ago.
- Trust what you read:
- every book is checked for accuracy, with real research when your subject needs it.
Create your unique book in 3 steps
- 1. Select your focus
Select the focus of your Databases book and share your background
- 2. Personalize your book
Specify your goals and choose sub-topics to include
- 3. Get your tailored book
Your book is ready in 10 minutes. Read it online, download as EPUB or PDF, or send to Kindle.
Frequently asked questions
- What is TailoredRead?
TailoredRead creates complete, full-length nonfiction ebooks, written specifically for you. Tell us what you want to learn and why, and TailoredRead writes you a complete ebook on it, with charts, tables, and diagrams throughout. Read it online, on Kindle, or on any e-reader, or download it as a PDF or EPUB. Every book is written fresh the day you order it.
- How is the book tailored to me?
Before anything is written, you answer a few short questions about your goals, your background, and the topics you care about. Your book is then planned around your answers: written at your level, focused on your goals, and covering the topics you chose, instead of the one-size-fits-all book a store sells everyone.
- Will it read like generic AI content?
No. Your book isn't a chat transcript: it's planned chapter by chapter before a single word is written, told in a clear book voice, and explains ideas visually with charts, tables, and diagrams. After writing, every book goes through an editorial pass that polishes chapters so the book reads consistent from start to finish. Judge for yourself: browse thousands of sample books on our Explore Books page.
- How accurate is the content?
Our AI first checks whether your subject needs live research. Niche and fast-moving subjects are researched before writing, and the book plan and chapters are grounded in what it finds. After writing, every book goes through a quality pass that checks its facts and consistency, and researched books list their sources in a Notes section at the back.
- How long is the book?
You choose the length: Comprehensive (250-300 pages), Detailed (150-200 pages), Essential (70-100 pages), or Short (30-50 pages).
- Does the book include visuals?
Yes. Every book includes visual elements such as timelines, checklists, step-by-step guides, decision trees, comparison tables, and matrices, and many include bar charts. A typical book includes dozens of these visual elements.
- Can I read it on Kindle? What formats can I download?
Yes. Every book can be read in our online reader or downloaded as a PDF or EPUB. The EPUB can be opened with Kindle, Apple Books, Kobo, and any e-reader. The Commercial and Author licenses also include an editable Word (DOCX) and Markdown download.
- How much does it cost?
About the price of a regular ebook. The exact price depends on your book's length and complexity, from $2 for the shortest books to $35 for the most comprehensive, and it's shown when you review your book, before you commit to anything. Each book is a one-time purchase, yours to keep, no subscription. Licenses that let you share, teach, or publish your book range from $35.99 to $49.99.
- Can I preview the book before purchasing?
Before you pay, you'll see what your book will cover: the title, a detailed description, the estimated length, and the complete chapter-by-chapter table of contents, so you know what you're getting before you decide. The full text itself is written after you purchase.
- How long does it take to create a book?
About 10 minutes. You can start reading the opening chapters while the rest is still being written.


