Backend Development8 min read

What a front-end developer actually needs from PostgreSQL

By Marin Cholakov07/28/2026
PostgreSQLSQLPrismaFull Stack

I've built front-ends against other people's APIs for five years. This year I went and learned the database side properly — SQL, PostgreSQL, then Prisma.

I expected to come away able to write queries. What I actually came away with was an explanation for a decade of API decisions I had previously just worked around.

The endpoint that returns almost what you need

Every front-end developer knows this endpoint. It returns the list you asked for, but the one field you need for the card is missing, so you either fire N follow-up requests or ask for a change and wait a sprint.

That field is missing because it lives in another table, and joining it is not free. Once you have written the query yourself, the request you make of the back-end team changes shape. Instead of "can you add authorName to the response", it becomes "can we join authors on this list endpoint — it's one join on an indexed foreign key". One of those gets scheduled. The other gets discussed.

N+1, seen from the other side

I knew the term. I did not feel it until I wrote the loop that caused it.

// one query for the list
const posts = await prisma.post.findMany();

// and then one more per post — 51 queries for 50 posts
for (const post of posts) {
  post.author = await prisma.user.findUnique({ where: { id: post.authorId } });
}

versus

const posts = await prisma.post.findMany({
  include: { author: true },
});

The second is one round trip. On a list of fifty, that is the difference between a page that feels instant and a page that feels broken — and it is entirely invisible from the front-end, where both versions return the same JSON.

This is the same shape as fetching inside a mapped component. I had been careful about it in React for years without recognising it as the same mistake one layer down.

Indexes explain your loading states

A query on an unindexed column scans the whole table. It is fine at a thousand rows and unusable at a million, and nothing about the code changes in between — which is why the search box that was fine in staging is not fine in production.

Knowing this changed how I read a slow endpoint. It is often not "the back-end is slow"; it is one missing index on the column your filter uses. That is a five-minute fix that someone has to know to make.

Where Prisma helped and where it hid things

Prisma made the modelling click. Writing a schema and having the types flow into TypeScript closed the gap between the database and the component in a way that made the whole stack feel like one program.

It also makes it very easy to write an expensive query that looks cheap. A nested include three levels deep is one readable expression and a genuinely heavy query. The habit worth building is to look at the SQL it generates, at least once per new query shape. It is a log line away, and it is the difference between using an ORM and being used by one.

What I'd tell a front-end developer

You do not need to become a DBA. But there is a specific, small amount of database knowledge that pays for itself immediately in front-end work: what a join costs, what an index is for, why pagination exists, and what N+1 looks like in code.

That knowledge does not make you full-stack. It makes you the front-end developer who asks the back-end team for the right thing — and in my experience that is worth more to a team than either title.