All you need is PostgreSQL

b-man1 pts0 comments

All you need is PostgreSQL

All you need is PostgreSQL

June 25, 2026<br>by Eduardo Bellani

Introduction

The setup

Laying the foundation

The foundation: schemas and user roles for modularity

Domains

Accounts, managed and external

Transfers, constrained by a state machine and temporal periods

Transfer state history

Account auditing

Transactions, the immutable events

On maintaining business rules via meaningful constraints

The transfer state machine

Transactions must fall within the transfer period

Pending transactions require a pending transfer

No future transactions when closing a transfer

On capacity planning

Working set estimation

On write throughput

Enabling HOT Updates for Transfers

Making sure there are no Unused indexes

OLTP

Listing

The history of a transfer

OLAP

Balance ledger

Incremental maintenance via triggers

On serializable isolation

On decoupling

Benchmarking the startup scenario

Seed data

Write script: full transfer lifecycle

Read script: activity stream and balance

Running the benchmark

Results

Conclusion

Appendix A: Full code suite

Introduction

There is a deep cultural reflex in modern engineering: whenever a<br>problem appears, reach for a packaged solution instead of thinking from<br>first principles. The result is architectural cargo culting and lots of<br>missed opportunities. Some intentionally absurd-but-familiar examples:

We need an audit trail, let&rsquo;s use {temporal/event sourcing DBMS}

Our application is slow, let&rsquo;s cache that using {in-memory key-value database}

And since a relational database like PostgreSQL is still considered<br>mandatory,thanks mostly to its unmatched reputation, companies end up<br>stacking product on top of product on top of PostgreSQL. They inflate the<br>number of moving parts, operational risk, headcount demand, and overall<br>system entropy. Complexity1 grows, not because the problems demand it,<br>but because someone reached for a tool they saw in a conference talk.

In this post, I&rsquo;ll walk through a set of common misconceptions that<br>drive teams to introduce new infrastructure when they don&rsquo;t need to. All<br>of these can be solved with vanilla PostgreSQL 18 using standard<br>extensions available on RDS, with no special infrastructure and no<br>distributed-systems cosplay.

The goal in this article is not to argue that specialized systems are<br>never appropriate, but to show that the default assumption for your data<br>problems should be that my company can do fine with just PostgreSQL .

The setup

Here is a list of arguments that people put forth to reach for other<br>tools besides PostgreSQL, based on my experience:

I&rsquo;ll need auditing and reconstructing state

Write throughput is too low

The transactional queries are too slow

The analytical queries are too slow

My app will be coupled to the Database

To address these, I&rsquo;m going to use a variation of the Drosophila<br>melanogaster of the database field: the classic Supplier and Parts<br>database(Date 2003). I&rsquo;ll update it to be more in line with<br>the usual problematic tables: Financial Transaction and their<br>originating transfers.

For the rest of this article we will be constructing a database design<br>based on modern PostgreSQL that will achieve the general goals listed<br>above and specific business requirements. Here is a requirements snippet<br>from a very popular banking API company:

Transactions: are immutable records of financial interactions with<br>Increase. You can think of them as the line items on your bank<br>statement. A Transaction with a positive amount means there&rsquo;s more money<br>in your account. A Transaction with a negative amount means there&rsquo;s less<br>money in your account. You can&rsquo;t directly create a Transaction, and they<br>never change after they are made. Anything that causes money to move<br>around your Increase account results in a Transaction - initiated or<br>received transfers, card payments, earned interest, and more.

Transfers: which includes ACH Transfers, Wire Transfers, etc - are the<br>most common way to initiate money movement over external networks with<br>Increase. Transfers are one-to-many with Transactions, which they create<br>as side-effects. Unlike Transactions, Transfers are stateful and<br>transition through a lifecycle of different statuses as they move across<br>the network.

Pending Transactions: represent potential future credits or debits of<br>money into your account and are a separate resource from Transactions<br>(despite their similar name). Notably, while Transactions are immutable,<br>Pending Transactions are not, as they don&rsquo;t guarantee the movement of<br>money. For example, Pending Transactions are created for card<br>authorizations (which can mutate or timeout) and also when placing a<br>hold on an account (which can be removed). Pending Transactions do not<br>affect your current balance (which is the balance you earn interest on),<br>but do affect your available balance (which is the amount you&rsquo;re able to<br>move out of Increase). (Increase, Inc....

transactions rsquo postgresql transfers transfer account

Related Articles