This is the part-1 of the invoice settlement system. Read it here
This story is the direct comparison of the system design comparison between Elixir & Go, we will build the same system in both of the languages and see which provides what benefit.
Why This Story Matters
Ten years ago, I was working at a fast-growing B2B marketplace startup. We were the middleman connecting businesses with vendors. The revenue model was simple: take a commission from every transaction and pay vendors weekly, biweekly, or monthly based on their contracts.
Sounds straightforward, right? It wasn’t.
The Real Problem That Kept Me Up at Night
Picture this scenario: You have 5,000+ active vendors, each with different settlement schedules. Some get paid daily , others weekly, and some monthly. Every settlement period, we needed to:
- Calculate what we owe each vendor — Commission after our cut, minus any disputes or chargebacks
- Generate detailed invoices — Line items, tax calculations, dispute deductions, promotional credits
- Create PDF invoices — Professional looking documents with our branding and vendor’s business details
- Email invoices to vendors — With payment timeline and dispute resolution info
- Initiate bank transfers — Usually through our payment processor, pending finance team approval
The stakes were brutal: Miss a vendor’s invoice? They’d be calling our customer support within hours. Miss their payment? They’d threaten to stop serving our customers. One major vendor leaving could cost us $500K+ in monthly revenue.

The 2014 Tech Reality Check
Back then, we were running on .NET Framework 4.5 (not the modern .NET you know today). PDF generation was a nightmare — libraries were expensive, buggy, or both. Crystal Reports was still a thing people used unironically. Cloud services? Limited and costly.
We experienced several critical issues with our automated vendor payment and invoicing system, which required significant manual intervention. The main challenges were:
- System Performance: The report generation process consistently overloaded our system, leading to failures during the crucial weekend vendor settlement runs.
- Unreliable Document Creation: The PDF generator was fragile, failing on invoices with a large number of items and also crashing when vendor names contained special characters.
- Incomplete Processing: We discovered that payment batches were created with missing vendors, and some generated invoices were never sent due to email server timeouts.
- Lack of Monitoring: A core problem was the absence of system monitoring and automated alerts. We had no easy way to know when or why a process failed, which delayed our response and required manual database checks to identify the errors.
Why This Problem Is Still Relevant Today
You might think, “This was 2014, surely things are easier now?” Yes and no.
What’s Better Today:
- Cloud services for PDF generation (like PDFShift, Bannerbear)
- Better email services (SendGrid, Mailgun with webhooks)
- Modern payment APIs (Stripe Connect, PayPal for Marketplaces)
- Container orchestration and monitoring tools
What Hasn’t Changed:
- Business criticality — Vendors still expect their money on time
- Complexity of state management — Multi-step processes still fail in the middle
- Scale challenges — More vendors means more edge cases
- Regulatory requirements — Financial audit trails are more important than ever
We have previously encountered several significant technical issues that had a direct impact on our operations and vendor relationships. The key incidents include:
- Systematic Invoice Generation Failures: A recurring software bug (a memory leak) would cause our PDF generation service to crash after a certain volume. The failure was silent, without any alerts, meaning the issue was only discovered when vendors reported they hadn’t received their invoices. This required extensive manual work to resolve.
- Email Delivery Blackouts: An issue with our email provider led to a three-day period where thousands of invoices were not delivered, even though our system incorrectly logged them as “sent successfully.” This forced us to re-send over 2,000 invoices, causing confusion and requiring manual verification.
- Duplicate Payment Processing: A scheduling bug occasionally caused duplicate payment jobs to run for the same vendor at the same time. This created incorrect payment requests, leading to bank transfer failures and a week-long reconciliation effort by the finance team to correct the errors.
Why Modern Solutions Still Need This Thinking
Today’s startups face the same challenges, just with different technology:
SaaS Companies: Need to generate invoices for thousands of customers monthly, handle failed payments, send dunning emails.
Marketplace Platforms: Uber, DoorDash, Airbnb all have to settle with millions of drivers, restaurants, and hosts regularly.
Financial Services: Payroll companies, expense management tools, and accounting software all handle critical financial workflows.
E-commerce Platforms: Shopify has to settle with millions of merchants, handling refunds, chargebacks, and payout schedules.
The common thread? These are mission-critical workflows that absolutely cannot fail silently or lose data.
What We’re Really Comparing
In this blog series, we’re not just comparing Go vs Elixir syntax. We’re comparing two fundamentally different approaches to building reliable systems:
Go’s Philosophy: “Give developers simple, powerful tools and let them build reliability mechanisms themselves.”
Elixir’s Philosophy: “Build reliability into the platform itself, so developers can focus on business logic.”
Both are valid approaches, but they lead to vastly different development experiences and maintenance burdens.
The Questions This Series Will Answer
As we dive into the implementations, keep these questions in mind:
- Time to Market: How quickly can you build a reliable system?
- Operational Complexity: What happens when things go wrong at 2 AM?
- Developer Onboarding: How long does it take a new team member to understand the system?
- Maintenance Burden: How much code do you need to maintain for reliability?
- Debugging Experience: How easy is it to diagnose and fix issues in production?
Setting Expectations
In the next parts, we’ll build the same invoice settlement system in both languages. But I want to be upfront about what we’re optimizing for:
This isn’t about performance — Both Go and Elixir can handle thousands of invoices per minute.
This isn’t about popularity — Both languages have thriving ecosystems.
This is about: Which approach lets you sleep better at night knowing your critical business processes are reliable?
Ten years later, I still have flashbacks about those Monday morning “where are our invoices?” calls. The system we’re about to build would have saved us countless hours of manual fixes and customer escalations.
Ready to dive into the technical implementations? Let’s start with Go and see exactly what it takes to build reliability from scratch.
In Part 2, we’ll tackle the same problem with Go and then in part 3 with Elixir’s OTP and do the comparison between the Go and the Erlang ecosystem.

