Join the discussion

Write your take first — we'll ask for email only when you're ready to publish.

  • Hacker News
  • While I love postgres, I take issue with coupling too much application logic to the DB. It’s much easier to update/rollback stateless containers/cloud functions/VMs than to recover a DB.
  • Why is it easier?

    You don’t need to operate on the entire database. You can backup or roll back individual tables and schemas.

  • PostgreSQL is a powerhouse. It has a solution for everything. Especially when you start a project you might be better off just using PostgreSQL instead of a specialized solution. You can optimize it later.
  • Moving business logic into database functions is the shortest path to insanity.
  • I agree with that. You can use Postgres as a message queue / task manager backing store without a database function, though, and it works quite well at the small scale that most sites / SaaS products operate at.
  • I remember an old colleague telling me at a previous job they'd moved all business logic into triggers and stored procedures because their database was on their most powerful server. And then one day it wasn't and the database started to choke horrifically.
  • I like postgres. I use it for lots of projects. I like other databases too. I think thats okay.

    Here's Malcom Gladwell discussing spagetti sauce which feels oddly relevant: https://youtu.be/iIiAAhUeR6Y?si=UJUUiF6H0j6IY3lL

  • > But the bar should be high: only after pushing Postgres to its limits, documenting why it was insufficient, and accepting the operational cost of the alternative

    Why do I need to push Postgres to its limits before using a different solution? Throwing a hosted Redis in front of some hot-path API calls is very straightforward and easier to reason about than materialized views or UNLOGGED tables.

  • Those examples are all equally difficult to reason about. Cache invalidation is equivalent to refreshing a materialized view, and UNLOGGED tables bring about new and exciting ways lose data.
  • I haven't really used redis much so curious to hear your perspective - this seems the opposite to me? A materialised view is just taking the data I already have and rendering it in a different way to speed up my access patterns. It's easy for me to understand where its all coming from, and it's all directly mapped back to the source data so if things change I can easily understand why it might break etc.

    For redis, it seems there's no "out of the box" way to take some data from my DB and cache it. It seems it needs to be hand rolled per query you're optimising, you lose any structural link to the source data (redis doesn't know about my table structure), and now I have another service I need to worry about. Or is it much easier nowadays than I am thinking?

  • Because it's less moving pieces to only have one bit of state to think about.

    You already have a connection string to your database with a password or authn/z with your cloud provider. If this is a "serious" application, you have backups, monitoring, user roles, pgbouncer, partitioning, and other Postgres-specific things to think about. With just a little bit of care, you can make whatever queries you are running fast enough to not need redis.

    But ok, you think adding redis is going to solve your performance problem because you can just cache API responses in redis instead of hitting the DB. Maybe, but now you have to think about cache invalidation, eviction behavior, sizing the redis instance, another set of authn/z roles to think about, and of course more cost.

    I realize we're speaking past each other, but IME Postgres will work well into the terabyte range and if you can't tune your database setup for performance then reaching for cache is a form of premature optimization.

  • Postgres has its advantages, but for message queues I’d stick with SQS. I built out a trading firm last year that was basically Postgres, some dotnet services and SQS queues and we got acquired for $140M. You can build some fairly formidable systems if you keep them simple.
  • Sounds interesting. Can you elaborate? You got acquired one year into doing business for 100M+? Impressive
  • As @f3408fh has said, I am also curious to knowing more about it if possible.

    I had always thought that trading firms might be some of the sole exceptions of over-engineering as I had went into the rabbit-holes of FPGA's and found that some of the use-cases of that technology was trading firms using it to literally shave off even a few milliseconds and so the amount of optimization there

    So I am a bit curious how postgres/some dotnet services and SQS queues is able to create a trading firm and scale it and even sell it for 140M$. It feels like my understanding of the situation was a bit uncertain then but could you please elaborate more if possible?

  • The page makes an argument that having a bunch of disparate databases doing specialized things means you have a higher maintenance burden, since you are maintaining more things and will be paged for more failures, but in my 20+ years maintaining production infrastructure, I find that it is often much more difficult to maintain one large database than multiple smaller ones.

    You have pushed your entire infrastructure into a single failure domain, for one thing. You make it certain that if your database fails, EVERYTHING fails.

    In addition, there is resource contention and workload variability. As you start to push your postgres instance, all the workloads hitting your database are going to be competing for resources. While postgres itself is good at parallelizing the work it is doing, all that work is still going to be hitting the same database, and competing for the same kcache. Your entire infrastructure might degrade in performance at the same time.

    Any issue with one component can cascade very easily if they all share the same database. If your login functionality has a bug and is creating churn on your database, it can lock everything.

    With multiple databases, you have a much smaller blast radius when you do database operations. You isolate your workloads and can independently scale them.

    Admittedly, all of these issues occurred at a place that had high traffic and high availability requirements. Honestly, though, if your load is so low that you never feel infrastructure pressure, it probably doesn't matter what strategy you use.

  • Seems to me that a single database does reduce maintenance burden, just at the cost of higher risk of failure. The trade off should be for the architect to decide.
  • I love Postgres. I buy using it for many many things.

    I really don’t understand why everyone insists that you should use it as a work/message queue.

    There are lots of purpose-built bullet proof queuing systems that are simple to setup and administer (or just use SQS).

    Your queue is likely to have very different access patterns than the rest of your data, and sticking it in Postgres means you’re probably going to end up setting up partitions or optimizing auto-vacuum on that table way earlier than you probably need to mess around with this things in your scaling.

    If your queue has more than a few hundred jobs a day (or you anticipate that like anytime soon), just use a queue.

  • In some ways, Apache Kafka and RabbitMQ can help force better design choices.

    A db can be performant, but at a certain point the global locks incremental primary keys create just strangle throughput. What makes a good db design normal form, is almost guaranteed to be inefficient at scale sooner or later. =3

  • A few hundred jobs a day doesn't seem like it would even be close to what postgres could handle easily, does it?

    I'm thinking of the problem as using a small amount of text to represent the work that needs to be done and then using a postgres table where some entries are being added as work that needs to be done, and then a worker is pulling the rows of work out of that table, and maybe putting a completion message somewhere in postgres. I'll concede that is more transient data than probably most of the other tables, it might benefit from vacuuming more often. Does the autovacuuming system not figure out it needs to run more often and do it?

    Wouldn't the issue would be more overall queries per second, the amount of writes you're already doing, and the general load on the database. We just added some audit tables that are quickly growing to millions of rows, and it seems like Postgres isn't even breaking a sweat. I'm mostly spit balling here and probably glossing over some details.

    But, like you said SQS is pretty easy too.

  • Because you can’t two-phase commit between Postgres and the message broker, so you end up with a transactional outbox, which is already a queue.
  • I agree but with a caveat that it depends entirely on what your queue represents. If it's part of your data model then keep it with the other data. If it's separate then keep it separate.

    Using Postgres gives you transactions and consistency if you have to restore from a backup. Most of the time this doesn't matter (and is a liability) and you can just use some external queue system but sometimes it does matter.

  • > There are lots of purpose-built bullet proof queuing systems that are simple to setup and administer (or just use SQS).

    Because in 99% of cases you don't need a purpose built solution (Even if engineers often think that) at the scale that most people operate in. Nothing is easier to setup and administer than the database you already use.

    We are using Postgres as a worker queue in production for many years, with millions of items being processed at any time and it's been perfectly fine. If you have hundreds like in your example...might as well use sqlite.

    There's great projects like https://github.com/NikolayS/pgque and https://lucumr.pocoo.org/2026/4/4/absurd-in-production/ that give you even some tooling around that.

  • PostgreSQL is good enough until it's not good enough, when you realize all the bad design decisions that were made before it hits scale. It is the decisions people make around not partitioning, HA, replication that makes it not good enough.
  • Everything is "good enough until it's not good enough". That's engineering.
  • Re: bad design decisions - This can be said about any technology.
  • That's fine. There are plenty of projects that don't hit that scale.
  • I feel like any problem that Postgres can't handle is a good problem to have. Either you've got so many customers that you're hitting sharp edges, or you're working on such an interesting problem that you're out of the domain where Postgres is helpful. That I should be so lucky
  • HA is now pretty good on Postgres.

    As for scale... Just use a larger machine. This works for regular transactional data until you're at something like Amazon scale.

    Edit:

    Think about this, suppose that you store 1 megabyte of data for each of your customers. So if you have a million customers, it's just 1Tb. And these days, you can have a server with 10Tb RAM delivered overnight. Although you might have to sell your firstborn son (offer applies only to royal families) to fund it.

    A lot of sharding/no-sql/... development happened in the late 2000-s when computers were about ~100 times less powerful than now. You _could_ get a system with 10Tb RAM in 2010, but as a specially-designed supercomputer.

  • These are not bad decisions they are reasonable tradeoffs at the beginning.

    Requiring HA, partitioning, and replication are good problems to have.

    The alternative is spending engineering time on setting all these up for a failed service with like 100 users.

  • Lots of the alternatives that this site claims Postgres will do are things you'd only consider well past the point that Postgres would be viable.

    Kafka? No one wants to operate Kafka, if it's a serious contender it's because you need things only it can do. Same with Elasticsearch, it sucks to operate, sucks to build a second stack just for search, so you'd only consider it at the point that Postgres is no longer suitable. Same with Snowflake.