After spending the last 3 months testing all three major plain text accounting tools with the same dataset, I’m ready to share a comprehensive comparison. This isn’t “which is best” - it’s “which is best FOR YOU.”
The Contenders
Ledger - The original, created by John Wiegley in 2003
hledger - Modern Haskell rewrite, emphasizing UX and reliability
Beancount - Python-based, focusing on data integrity and validation
All three are mature, actively developed, and production-ready.
Performance Benchmarks (2025)
I tested with identical datasets on the same hardware (M2 Max, 32GB RAM).
1 Million Transactions Test
| Tool | Parse Time | Throughput | Memory |
|---|---|---|---|
| Ledger | 6.2s | ~161K txn/s | 1.5GB |
| hledger | 80.2s | ~12.5K txn/s | 3.2GB |
| Beancount v3 | 25s | ~40K txn/s | 5.2GB |
Winner (performance): Ledger by a wide margin
100K Transactions (More Realistic)
| Tool | Parse Time | Memory |
|---|---|---|
| Ledger | 0.8s | 180MB |
| hledger | 8.5s | 420MB |
| Beancount v3 | 2.1s | 520MB |
At typical dataset sizes (< 100K), all three are fast enough that performance isn’t a deciding factor.
Philosophy & Approach
Ledger: Flexibility First
Philosophy: Trust the user, provide maximum flexibility
Account creation: Automatic (just use it)
Validation: Minimal (assumes correctness)
Error handling: Permissive
Example:
2025-11-08 Grocery Store
Expenses:Groceries $50.00
Assets:Checking
If you typo “Groceries” as “Grocerys” - Ledger silently creates a new account. Pro: Fast entry. Con: Easy to make errors.
hledger: Practicality & UX
Philosophy: Balance between flexibility and structure
Account creation: Automatic with warnings
Validation: Moderate (helpful suggestions)
Error handling: Informative
Focus areas:
- Best documentation in plain text accounting
- Most user-friendly error messages
- Web UI included (hledger-web)
- Designed for beginners AND experts
Beancount: Correctness & Validation
Philosophy: Prevent errors before they happen
Account creation: Explicit declaration required
Validation: Strict (errors halt processing)
Error handling: Detailed and precise
Example:
2025-01-01 open Assets:Checking
2025-01-01 open Expenses:Groceries
2025-11-08 * "Grocery Store"
Expenses:Groceries 50.00 USD
Assets:Checking
Typo “Grocerys”? Error: Account does not exist. You fix it before it becomes a problem.
File Format Comparison
Ledger Format
2025-11-08 * Grocery Store
Expenses:Food:Groceries $50.00
Assets:Bank:Checking
hledger Format (Same as Ledger)
2025-11-08 * Grocery Store
Expenses:Food:Groceries $50.00
Assets:Bank:Checking
Beancount Format
2025-11-08 * "Grocery Store" "Weekly shopping"
Expenses:Food:Groceries 50.00 USD
Assets:Bank:Checking -50.00 USD
Differences:
- Beancount requires explicit amounts (both sides)
- Beancount uses quotes for payee/narration
- Ledger/hledger infer second amount
- Syntax incompatible (can’t just switch)
Feature Comparison
| Feature | Ledger | hledger | Beancount |
|---|---|---|---|
| Multi-currency | ✓ | ✓ | ✓ |
| Stock/commodity | ✓ | ✓ | ✓ |
| Virtual transactions | ✓ | ✓ | ✗ |
| Budgeting | ✓ | ✓ | Plugin |
| Web UI | ✗ | ✓ (hledger-web) | ✓ (Fava) |
| Python API | ✗ | ✗ | ✓ |
| Import tools | Community | Community | Built-in |
| Explicit accounts | ✗ | ✗ | ✓ (required) |
| Price history | ✓ | ✓ | ✓ |
| Tags/metadata | ✓ | ✓ | ✓ |
Ecosystem & Community
Ledger
- Age: 22 years (since 2003)
- Community: Largest, but fragmented
- Development: Slower (mature/stable)
- Documentation: Comprehensive but dense
- Tools: Many community tools, varying quality
hledger
- Age: 13 years (since 2012)
- Community: Growing, very active
- Development: Most active development
- Documentation: Best in class
- Tools: Curated, high quality
Beancount
- Age: 12 years (since 2013)
- Community: Developer-heavy, enthusiastic
- Development: Active (v3 major release)
- Documentation: Excellent, technical
- Tools: Fava (outstanding), growing ecosystem
Learning Curve
Ledger:
- Quickest to start (permissive)
- Steepest to master (many features)
- Documentation: Reference manual style
hledger:
- Gentle learning curve (best docs)
- Progressive complexity
- Documentation: Tutorial style
Beancount:
- Moderate learning curve (stricter syntax)
- Rewards learning with safety
- Documentation: Technical but thorough
Use Case Recommendations
Choose Ledger If:
✓ You have huge files (500K+ transactions)
✓ You want maximum flexibility
✓ You’re comfortable debugging issues
✓ You prefer C++ performance
✓ You like terminal-first workflow
Choose hledger If:
✓ You’re new to plain text accounting
✓ You want excellent documentation
✓ You value UX and error messages
✓ You want included web UI
✓ You prefer Haskell reliability
Choose Beancount If:
✓ You want strict validation
✓ You need Python API for automation
✓ You prefer errors over silent failures
✓ You want Fava web interface
✓ You value data integrity over flexibility
My Personal Recommendation Framework
Question 1: Are you new to plain text accounting?
- Yes → hledger (best documentation and UX)
- No → Continue
Question 2: Do you need Python automation/scripting?
- Yes → Beancount (only one with Python API)
- No → Continue
Question 3: Do you have 500K+ transactions?
- Yes → Ledger (best performance)
- No → Continue
Question 4: Do you value catching errors automatically?
- Yes → Beancount (strict validation)
- No → Ledger or hledger (both flexible)
Can You Switch Between Them?
Ledger ↔ hledger: Easy (mostly compatible)
Ledger/hledger → Beancount: Converters exist, some manual work
Beancount → Ledger/hledger: Harder (different philosophy)
The Verdict
There is no single “best” tool. All three are excellent and actively maintained.
My take:
- 2025 “most evolved”: hledger (best balance)
- 2025 “most powerful”: Ledger (if you need raw speed)
- 2025 “most innovative”: Beancount (Python API + Fava)
Try multiple tools with the same month of data and see which workflow feels better.
What do others think? Which tool do you use and why?