Do you know about the Winklevoss twins, Cameron and Tyler? They grew up together, went to the same university, and eventually built very different things around technology, finance, and entrepreneurship. Whatever you think of their story, there is something fascinating about twins who start from the same place and then take their abilities into different directions.
Now imagine two twins who grow up in completely different families.
One becomes obsessed with organizing information, while the other becomes obsessed with doing enormous amounts of work at the same time.
They spend years in completely different worlds. Then one day, they meet. And someone says:
“You two might actually work really well together.”
That is the story I want to tell about PostgreSQL and CUDA.
They are not really twins, of course. They were born almost a decade apart, built for different purposes, and live at very different levels of the computing stack.
But there is an uncanny similarity in one of the ideas behind them.
Let me explain.
Two births, roughly a decade apart
PostgreSQL's story goes back to the POSTGRES project at the University of California, Berkeley. In 1996, the project moved from the name Postgres95 to PostgreSQL, starting with version 6.0.
Then, roughly ten years later, another important piece of the computing world arrived.
In 2006, NVIDIA introduced CUDA, giving developers a programming model for using GPUs for general-purpose computation.
Two technologies with very different beginnings. Relational databases like PostgreSQL have been dealing with something, humans have been struggling with forever:
How do you keep information organized and reliable when lots of people are using it at the same time?
CUDA came from a very different question:
What if we could use the enormous number of computing resources inside a GPU for things other than drawing pixels?
Different questions with different answers.
But there is a common idea hiding underneath both.
Don't make independent work wait unnecessarily.
And to understand why it is important, we need to start with PostgreSQL.
PostgreSQL has a very clever way of saying "you go ahead"
Imagine a PostgreSQL database serving a busy application.
- Someone is placing an order.
- Someone else is updating a customer record.
- A reporting query is reading thousands of rows.
- Another user is looking at the same data.
If PostgreSQL stopped everything every time one transaction changed something, our database would become a very expensive queue.
Instead, PostgreSQL uses MVCC, Multi-Version Concurrency Control.
The easiest way to think about MVCC is through versions. When a transaction changes a row, PostgreSQL doesn't simply shout:
“EVERYBODY STOP. THIS ROW IS BUSY.”
Instead, PostgreSQL maintains information about row versions and transaction visibility. Different transactions can therefore see the appropriate version of the data according to their snapshot. A reader doesn't necessarily have to stand outside the door waiting for a writer to finish.
That is one of the reasons PostgreSQL can handle a lot of concurrent activity. The important idea here isn't simply “PostgreSQL is fast.” It is more interesting than that.
PostgreSQL looks at a busy database and says:
“If these things don't need to wait for each other, let them work independently.”
Keep that thought. We are going to need it.
Now meet CUDA
CUDA comes from another part of the computing family.
A CPU is excellent at many things. It is designed to handle complex instructions, branching, sequential work and a relatively small number of powerful threads.
A GPU takes a different approach. Modern GPUs contain huge numbers of execution resources and are designed to handle large amounts of similar work concurrently.
So let's forget databases for a moment and do some very simple mathematics.
Suppose I give you this function:
f(x) = 2x + 1
Easy.
Give me x = 3:
f(3) = 2(3) + 1 = 7
Now give me five values:
1, 2, 3, 4, 5
We get:
f(1) = 3
f(2) = 5
f(3) = 7
f(4) = 9
f(5) = 11
Still easy.
Now imagine I give you 100 million values. The equation hasn't become more complicated.
That is the funny part. It is still:
2x + 1
The problem is that we have to do it an enormous number of times. And each calculation is independent.
- f(10) doesn't need the answer from f(9).
- f(50,000) doesn't care whether f(49,999) has finished.
There is no grand mathematical conversation happening between them. They are just a huge pile of little jobs.
And this is exactly the kind of situation where GPU parallelism becomes interesting.
The GPU looks at the problem and effectively says:
“Why are you making me wait for the previous calculation?”
Now let's give the twins the same job
Let's bring PostgreSQL back into the room.
Suppose we have a table called sales:
CREATE TABLE sales ( product text, quantity integer, price numeric ); And our boss walks over and says:
“I want the total value of every sale.”
Fair enough. Mathematically, our function is:
f(quantity, price) = quantity x price
If someone bought three products at 100 INR each:
3 x 100 = 300
In PostgreSQL, we can simply write:
SELECT product, quantity, price, quantity * price AS total_value FROM sales; PostgreSQL understands what we are asking.
- It knows what sales, quantity, price is.
- It knows the data types.
- It knows which rows are visible to our transaction.
- It knows what the SQL statement means.
For five rows, nobody needs to call a GPU. We would probably spend more time explaining why we needed a GPU than actually doing the calculation.
But now imagine the table contains 100 million rows.
The calculation itself is still laughably simple:
quantity x price
The interesting part is the amount of work.
We now have something like:
row 1 -> quantity x price
row 2 -> quantity x price
row 3 -> quantity x price
row 4 -> quantity x price
row 5 -> quantity x price
...
row 100,000,000 -> quantity x price
And suddenly our simple little equation has become a very large workload.
PostgreSQL's way
PostgreSQL receives the query:
SELECT product, quantity, price, quantity * price AS total_value FROM sales; It understands the database problem. Then finds the rows and reads the values. Then it performs the expression and produces the result.
And PostgreSQL is very good at this.
But notice something. The database has already done a lot of thinking before we even get to the multiplication.
Which table? Which rows? Which columns? Which transaction snapshot? Which data is visible? What does the query mean?
That's database work.
Then there is this:
quantity x price
Again.
And again. And again.
Millions of times.
This is where our second twin starts getting interested.
CUDA's way
CUDA gives us a programming model for using the GPU to perform this kind of massively parallel work.
Instead of thinking:
“I have 100 million calculations to perform.”
we can think:
“I have 100 million independent pieces of work.”
That difference is important. If the calculation for one row doesn't depend on another row, there is an opportunity to process many of them concurrently.
The GPU can have many threads working on the same kind of operation across different pieces of data.
Neither the mathematics hasn't changed nor the result hasn't changed. What changes is the way we attack the workload. And now the two twins have something to talk about.
What if PostgreSQL and CUDA worked together?
Here's the hypothetical.
PostgreSQL receives our query.
- It remains responsible for understanding the SQL and the database.
- It knows the data.
- It knows the schema.
- It knows the transaction.
- It knows which rows are important.
But then it encounters a part of the workload that looks suspiciously repetitive:
quantity x price
quantity x price
quantity x price
quantity x price
...
Millions of times.
That's where a GPU starts looking attractive. Instead of making the CPU perform every piece of that repetitive computation itself, suitable work could be moved toward the GPU.
The CPU doesn't disappear. PostgreSQL doesn't disappear. The GPU simply gets invited into the room.
And now our twins have different jobs.
PostgreSQL:
“I'll handle the database.”
CUDA:
“I'll give the GPU a way to handle the parallel computation.”
GPU:
“Fine. Give me the big pile of similar calculations.”
That is the basic attraction of combining PostgreSQL with GPU computing. And this is where PG-Strom enters our story.
Enter PG-Strom
PG-Strom is a PostgreSQL extension focused on GPU acceleration. It uses NVIDIA GPUs and CUDA to accelerate suitable PostgreSQL workloads.
And the important word here is suitable.
A GPU is not a magical “make PostgreSQL faster” button. If the workload is tiny, highly sequential, dominated by branching, or constantly moving small pieces of data back and forth, a GPU may not help much. But give it a large workload where many operations can happen independently?
Now we have something worth discussing.
PG-Strom explores exactly this territory: bringing GPU computation closer to PostgreSQL workloads rather than treating the database and GPU as two completely separate worlds.
That's what makes the idea interesting.
We are not saying:
PostgreSQL is old and the GPU is new. Replace one with the other.
We are saying:
PostgreSQL and GPUs are good at different things. What happens when we let each do the work it is naturally good at?
That's a much better question.
A Few Practicals
Before we get practical, one small disclaimer, I don't currently have access to a GPU to run these examples myself. So I went back to the public PG-Strom documentation and adapted one of its examples around the same function we started with, f(x) = 2x + 1. The execution result mentioned below belongs to the published PG-Strom example, not to my own machine.
The example in the current PG-Strom documentation is actually quite nice for this. It filters rows from a large table, performs a calculation, and then aggregates the result:
SELECT sum(lo_extendedprice * lo_discount) AS revenue FROM f_lineorder WHERE year = 1993 AND lo_discount BETWEEN 1 AND 3 AND lo_quantity < 25; The calculation here is lo_extendedprice * lo_discount. For our little experiment, let's replace that with our familiar function:
f(x) = 2x + 1
So the simplified idea becomes:
SELECT
SUM(x * 2 + 1) AS result
FROM numbers
WHERE x > 10;
Now our tiny equation has a little more company. The database first finds the rows we want, applies 2x + 1, and then adds those results together.
In the PG-Strom example, the documented execution plan uses GpuPreAgg, with the calculation and aggregation performed as part of GPU processing. The plan also shows the filtering conditions being handled as GPU scan qualifications. The documented execution time for that example is about 55 ms.
I have not run our 2x + 1 version hence, I cannot claim 55 ms for our query. I am simply taking the shape of the documented workload and putting our own little function inside it.
Now, the equation feels a little different. We started with:
f(x) = 2x + 1
Now there are rows to find, values to calculate and results to aggregate. The mathematics stayed small but the workload around it grew.
CYBERTEC has also published earlier experiments with PG-Strom, including cases where GPU execution helped and cases where the difference was small. It is an interesting bit of history alongside the current documentation.
And that leaves me with one question.
“If a simple function can grow from a calculation into a workload where PostgreSQL, CUDA and the GPU all have a part to play, what does a PostgreSQL environment look like when GPU-oriented workloads are considered from the beginning?”
And here we are in 2026
This conversation feels particularly relevant now. We are teaching machines almost everything.
We teach them language, images, patterns, how to write code, how to answer questions, and more.
Then we give them more GPUs. And then we ask them to do even more. But there is an old problem sitting quietly underneath all this new machinery.
Is the data right?
Because giving a machine more computational power doesn't automatically make the information underneath it more trustworthy. If the data is wrong, incomplete or inconsistent, throwing more GPU cores at the problem doesn't solve it.
It simply gives you a very efficient way of processing the wrong information. And this is where I think the PostgreSQL and CUDA relationship becomes genuinely interesting.
PostgreSQL brings decades of work around data, transactions, consistency, visibility and structure. CUDA brings a model for exploiting massive parallel computation.
One is deeply concerned with what the data means. The other is exceptionally good at doing enormous amounts of similar work.
Why force them to compete?
Let them cooperate. PostgreSQL understands the data. So, the CPU can handle the parts of the workload that require control, branching and sequential reasoning.
And CUDA and the GPU handle the parts that are naturally parallel. This makes the system decide where each piece of work makes the most sense.
That, to me, is the real opportunity. Not simply:
“How do we make PostgreSQL faster?”
But:
“How do we get the right piece of work to the right piece of hardware without losing the correctness and context of the data?”
Because there is one more thing we need to remember in 2026. The machine can speak too in real time. And once the machine starts speaking, the question isn't only how quickly it can produce an answer.
We also need to care about what it learned from, what it calculated, and whether the answer deserves to be trusted. Maybe that's what two twins can teach us.
They don't need to become the same. They just need to know what each one is good at.
And when they do?
Well, that's when things get interesting.
The post CUDA and PostgreSQL: Twins from two Worlds appeared first on CYBERTEC PostgreSQL | Services & Support.
