Hey PTA community! Marcus here (the Austin software dev). Several people have asked about my transition from hledger to Beancount, so here’s my detailed comparison after using both extensively.
My Journey: 2 Years hledger → 6 Months Beancount
Started with ledger-cli in 2022, switched to hledger for better tooling, then moved to Beancount for Python integration. Here’s what I learned:
Language & Syntax Comparison
hledger Syntax (Ledger-style)
2025-01-15 * Grocery shopping
expenses:food:groceries $85.43
assets:checking $-85.43
2025-01-15 * Stock purchase
assets:brokerage:VTI 4.5 VTI @ $442.50
assets:brokerage $-1991.25
Beancount Syntax
2025-01-15 * "Whole Foods" "Grocery shopping"
Expenses:Food:Groceries 85.43 USD
Assets:US:Chase:Checking -85.43 USD
2025-01-15 * "Schwab" "Stock purchase"
Assets:US:Schwab:VTI 4.5 VTI {442.50 USD}
Assets:US:Schwab:Cash -1991.25 USD
Key Differences:
- Account names: hledger uses lowercase with colons, Beancount uses TitleCase
- Commodities: Beancount requires explicit currency units everywhere
- Lot tracking: Beancount’s
{cost}syntax is more explicit - Metadata: Beancount has structured payee/narration fields
Technical Architecture
hledger (Haskell)
Pros:
- Fast: Haskell’s compiled performance
- Functional: Pure functional programming principles
- Type safety: Strong Haskell type system
- Multiple formats: Reads ledger, CSV, timeclock formats
Cons:
- Haskell barrier: Hard to contribute unless you know Haskell
- Limited extensibility: Adding features requires Haskell expertise
- Smaller ecosystem: Fewer third-party tools
Beancount (Python)
Pros:
- Python ecosystem: Massive library availability
- Easy customization: Simple to write importers, reports, plugins
- Data science integration: Works with pandas, numpy, matplotlib
- Readable codebase: Most developers can understand and contribute
Cons:
- Slower: Python performance vs compiled Haskell
- Memory usage: Higher memory footprint for large ledgers
- Dependency management: Python packaging complexities
Feature Comparison
Query Systems
hledger queries:
hledger balance expenses -p 2024 --monthly
hledger register checking --cleared
hledger accounts --tree
Beancount queries:
SELECT month, sum(position)
WHERE account ~ '^Expenses:' AND year = 2024
GROUP BY month
Winner: Beancount - SQL is more powerful and familiar to developers
Reporting
hledger:
- Built-in reports (balance, register, cashflow)
- hledger-web for browser interface
- Multiple output formats (CSV, JSON, HTML)
- Excellent balance sheet formatting
Beancount:
- Fava web interface (much more polished)
- Custom reports via Python
- Integration with Jupyter notebooks
- Beautiful charts and visualizations
Winner: Beancount - Fava is significantly better than hledger-web
Data Validation
hledger:
- Basic balance assertions
- Account name validation
- Date range checks
Beancount:
- Strict account declarations
- Opening/closing account dates
- Commodity declarations
- Balance assertions with tolerances
- Plugin system for custom validations
Winner: Beancount - Much more rigorous validation system
Ecosystem & Tooling
Import & Automation
hledger:
- hledger import with CSV rules
- Limited bank format support
- Manual rule configuration
Beancount:
- Python-based importers (highly flexible)
- Machine learning categorization possible
- Easy integration with bank APIs
- Large community of shared importers
Winner: Beancount - Python ecosystem enables much better automation
Third-party Tools
hledger ecosystem:
- hledger-ui (terminal interface)
- hledger-web (basic web interface)
- hledger-interest (interest calculation)
- Smaller community
Beancount ecosystem:
- Fava (excellent web interface)
- bean-check, bean-query, bean-report
- Extensive plugin system
- Integration with financial data sources
- Much larger community
Winner: Beancount - Significantly larger ecosystem
Performance Comparison (My 3-Year Ledger)
File Processing Speed
- hledger: ~0.2 seconds (15,000 transactions)
- Beancount: ~1.1 seconds (same data)
Memory Usage
- hledger: ~45MB RAM
- Beancount: ~180MB RAM
Query Performance
- hledger: Sub-second for most queries
- Beancount: 1-3 seconds for complex SQL queries
Winner: hledger - But Beancount performance is acceptable for most users
Learning Curve
hledger
- Simpler syntax (fewer required fields)
- Good documentation
- Familiar to ledger-cli users
- Less opinionated about account structure
Beancount
- More explicit syntax (steeper initial learning)
- Excellent documentation and cookbook
- Forces good accounting practices
- More structured approach
Winner: Draw - hledger easier to start, Beancount teaches better practices
Why I Switched to Beancount
1. Python Ecosystem
As a software developer, being able to:
- Write custom importers in Python
- Use pandas for data analysis
- Create custom reports with matplotlib
- Integrate with Jupyter notebooks
- Leverage machine learning for categorization
This was huge for me.
2. Data Validation
Beancount’s strict validation caught errors that hledger missed:
- Typos in account names
- Missing commodity declarations
- Inconsistent date ranges
3. Fava Interface
hledger-web feels like a prototype compared to Fava:
- Better visualizations
- Mobile responsive
- Query builder interface
- Document attachments
4. Community & Future
Beancount has:
- Larger, more active community
- More frequent updates
- Better integration with modern tools
- Growing adoption in finance industry
When to Choose hledger
Choose hledger if:
- Performance matters: Large ledgers (100k+ transactions)
- Simplicity preferred: Want minimal syntax
- Haskell familiarity: Comfortable with functional programming
- Ledger-cli migration: Coming from original ledger
- Minimal dependencies: Want single binary deployment
Real hledger advantages:
- Faster processing
- Lower memory usage
- More mature (longer development history)
- Better balance sheet formatting
- Simpler installation
When to Choose Beancount
Choose Beancount if:
- Automation important: Want sophisticated importers
- Data analysis needs: Integration with Python data tools
- Web interface priority: Fava is significantly better
- Strict validation: Want rigorous error checking
- Growing ecosystem: Access to more tools and plugins
Real Beancount advantages:
- Python extensibility
- Superior web interface
- Better data validation
- Larger community
- More automation possibilities
Migration Experience
hledger → Beancount Migration
I wrote a Python script to convert my hledger files:
# Key conversion challenges:
# 1. Account name format
'expenses:food:groceries' → 'Expenses:Food:Groceries'
# 2. Add explicit currencies
'$85.43' → '85.43 USD'
# 3. Restructure transactions
hledger_txn = "2025-01-15 * Grocery\n expenses:food $50\n assets:cash $-50"
beancount_txn = "2025-01-15 * \"Store\" \"Grocery\"\n Expenses:Food 50.00 USD\n Assets:Cash -50.00 USD"
# 4. Add account declarations
# Had to explicitly declare all accounts used
Migration took 2 weekends - mostly writing conversion scripts and cleaning up data.
Performance in Practice
My Current Setup (Beancount)
- Transactions: 15,000+ over 3 years
- File size: 2.8MB
- Fava startup: ~3 seconds
- Complex queries: 1-5 seconds
- Daily usage: Perfectly responsive
Verdict: Beancount performance is fine for personal use. hledger advantage only matters for very large datasets.
Community & Documentation
hledger Community
- Smaller but knowledgeable
- Helpful mailing list
- Good documentation
- Strong functional programming influence
Beancount Community
- Larger and growing
- More active GitHub discussions
- Extensive cookbook and examples
- More diversity in backgrounds (not just Haskell devs)
My Recommendation
For Most People: Beancount
- Better tooling (Fava)
- Easier automation
- More extensible
- Growing ecosystem
- Python accessibility
For Performance-Critical: hledger
- Large datasets (100k+ transactions)
- Resource-constrained environments
- Preference for functional programming
- Simpler deployment needs
For Beginners: Depends
- Technical background: Beancount
- Simplicity preference: hledger
- Want best tools: Beancount
- Performance concerns: hledger
The Future
Both projects are actively developed, but:
- Beancount: Growing faster, more innovation
- hledger: Stable, mature, focused on core functionality
I predict Beancount will become the dominant PTA tool due to:
- Python ecosystem advantages
- Superior user interfaces (Fava)
- Easier extensibility for non-Haskell developers
- Growing adoption in professional settings
Questions for Discussion
- What’s your experience with both tools?
- Performance vs features - which matters more to you?
- Have you migrated between PTA tools? How was it?
- What features are missing from both that you’d want?
Happy to answer any specific technical questions about either tool!
Marcus | Choosing the right PTA tool for your needs