Using DuckDB for a Simple Bill Splitting Solution

For over a decade, my friends and I used a popular bill-splitting app to manage group expenses after trips or outings. The process was…

For over a decade, my friends and I used a popular bill-splitting app to manage group expenses after trips or outings. The process was simple: log all the expenses, assign each to specific group members, and calculate the final amount owed by each person. However, a recent change to its free plan introduced a frustrating limitation: users could only add 4–5 expenses per day. For someone managing upwards of 10–15 expenses from a single trip, this change rendered the app almost unusable.

This frustration led me to explore whether I could quickly build a simple bill-splitting tool that focused purely on the basics: calculations and group expense sharing, without unnecessary features like analytics or currency conversion. While it wasn’t about innovation, it was an opportunity to solve a problem for myself and potentially others.

Repurposing DuckDB

Around this time, I had been learning about DuckDB, an in-process analytical database designed for OLAP (Online Analytical Processing) workloads. It is typically used for analytical data processing tasks, but I saw an opportunity to repurpose it for something simpler: temporary data storage and calculation for bill-splitting. DuckDB’s flexibility, lightweight design, and SQL capabilities made it a suitable choice for this project, even though the use case was unconventional.

The Technical Approach

Here’s how I built the project:

1. Session Isolation with UUIDs Each session generates a unique UUID to create and identify a temporary DuckDB database file. This ensures that data for each group or session remains isolated and secure.

2. Temporary Data Persistence DuckDB files created during a session are stored temporarily. To prevent data buildup, a cron job automatically deletes files that haven’t been accessed for 72 hours. This approach ensures efficient storage management without requiring long-term data retention.

3. Backend Functionality Using Python, I developed the backend to manage database file creation, data storage, and cleanup. Python’s integration with DuckDB made it easy to execute queries and handle data efficiently.

4. Frontend Simplicity For the frontend, I used Next.js and Tailwind CSS to create a minimal and functional user interface. The UI is basic but sufficient for the core purpose of inputting expenses and viewing calculated results.

5. Cost-Effective Deployment The project is hosted using:

  • Netlify for the frontend on its free tier.
  • Oracle Cloud for the backend using its free-tier instance.

With this setup, the operational cost remains under INR 300 per month, excluding the domain cost.

A Quick Build

The entire project, which I call Splitzer, was built in under 48 hours. While it’s not groundbreaking, it serves its purpose: offering a lightweight, no-frills solution to a common problem. By using DuckDB for a task outside its typical use case, I was able to create a practical tool for group expense sharing.

Reflecting on the Experience

What stands out most from this project is how flexible tools like DuckDB can be when applied to unconventional problems. Although it’s primarily designed for analytical workloads, its ability to handle temporary data storage and SQL queries made it a good fit for this simple bill-splitting app.

This wasn’t about reinventing the wheel but about repurposing available tools to address a personal frustration — one that I imagine many others may share.

Conclusion

Splitzer may not be innovative, but it’s an example of how technology can be applied creatively to solve everyday problems. By focusing on simplicity and leveraging the right tools, it’s possible to build something useful quickly and affordably.

Have you ever used a tool in a way it wasn’t originally intended for? I’d love to hear your experiences.