Scaling Payment Processing to 1 Billion Transactions
By James Park
When Meridian processed its billionth transaction last month, we took a moment to look back at the architectural decisions that made it possible. Some were brilliant foresight. Others were lucky accidents. A few nearly killed us.
The Early Days: 10K Transactions Per Day
Our first architecture was embarrassingly simple. A single PostgreSQL database, a Node.js API server, and a Redis queue for async processing. It handled 10K transactions per day without breaking a sweat.
The decision that saved us later: we made the payment processing pipeline idempotent from day one. Every operation could be safely retried without double-charging customers. This added complexity early but became our most important reliability guarantee at scale.
The Growth Phase: 100K to 1M Daily
At 100K daily transactions, PostgreSQL started showing strain. Our p99 latency for payment authorization went from 50ms to 400ms. The fix was straightforward — read replicas for analytics, write optimization for the hot path, and connection pooling.
The Scale Phase: 1M to 10M Daily
This is where simple solutions stopped working. We moved to a distributed architecture with regional processing nodes, each capable of handling the full payment lifecycle independently. Consistency was maintained through an event-sourcing pattern that could reconstruct any transaction state from its event history.
Today: 47M Daily
Our current architecture processes 47 million transactions daily across 6 regions with a p50 latency of 23ms. The system has maintained 99.99% uptime for the past 18 months.