Do folks have any thoughts on ways of avoiding deadlocking access patterns? In a codebase where folks are sort of adding ad-hoc endpoints left and right, it's hard to avoid the case of two endpoints that more or less want to do: tx1: update a tx2: update b tx1: update b tx2: update a Is there a "discipline" or practice that works well? Like, can you realistically, in a real-world messy business codebase, impose an "o…
The startup's Postgres survival guide
181–190 of 255 posts
Re: The startup's Postgres survival guide
#182Earlier quoted context omitted.
It is just „SQL people” crying out not knowing how to work with ORM. They always claim that devs who use ORM don’t know SQL. But I never seen or hired a dev that doesn’t know SQL and yet for each project we use ORM. I also never seen anyone claiming that you doesn’t have to know SQL and ORM is enough from the opposite side. If you really run into spot where your ORM breaks you can always drop to SQL. If you build pro…
The issue is if you use the ORM, you still need to understand the DB it's on top of. There isn't much point in using such a leaky abstraction when it's easy enough to just use SQL.
You can use well known library that more people will comfortably using
or
given enough time you will build crooked, half baked ORM of your own.
Re: The startup's Postgres survival guide
#183Schema blot issues are real when you are vibe coding. Our engineers vibe coded and bloated our schema from 230 tables to 600+ tables. Many of them have repetitions of columns across the tables and often too much indexing. If your Postgres is on Aurora, the bloat easily multiplies your bills.
Re: The startup's Postgres survival guide
#184Earlier quoted context omitted.
I might be outing myself as a noob here, but... what is the (better) alternative?
You inject the pool itself.
I still have to get a connection from the pool, I just do it inside the function body now, right?
So this
@app.get("/users")
def get_users(conn = Depends[get_db_conn]):
users = conn.execute("SELECT * FROM users")
return users
would become that instead: @app.get("/users")
def get_users(pool = Depends[get_db_pool]):
with pool.get_conn() as conn:
users = conn.execute("SELECT * FROM users")
return users
But I still need enough connections in the pool to handle all concurrent requests, no?Re: The startup's Postgres survival guide
#185This advice is good, but every startup I've worked with has run into lower hanging fruit than this even. Less scaling problems and more just organizational. Usually what fixes that is: 1. Don't use an ORM. 2. Use serial PKs, not meaningful fields (article mentions this). 3. Use jsonb if needed, but sparingly. 4. Make your source of truth append-only, meaning you only insert, never update or delete. You can have secon…
Don't use an ORM . Highly debatable. When your highest cost is developers salaries. Don't reinvent a type system by having a single table where each row can mean many different things depending on a "type int" enum col. Easy to say, harder to not do when you have business requirements on table, customer pressure and budget already gone on discussing with DBA who maybe is right but you are burning money right here and…
The biggest consequence of forcing the RDBMS through a lazily evaluated object graph is that we've become decoupled from the mechanical realities of what the database provider can do. I had a client quickly drop the "you must use EF" commandment for the project I was assisting on once they saw how many rows it was loading per unit time without EF. "I didn't know that was possible". Many such cases.
Re: The startup's Postgres survival guide
#186Re: The startup's Postgres survival guide
#187This advice is good, but every startup I've worked with has run into lower hanging fruit than this even. Less scaling problems and more just organizational. Usually what fixes that is: 1. Don't use an ORM. 2. Use serial PKs, not meaningful fields (article mentions this). 3. Use jsonb if needed, but sparingly. 4. Make your source of truth append-only, meaning you only insert, never update or delete. You can have secon…
In the PHP back end I work on, I find the ORM immensely helpful because we need to instantiate objects to do things like permissions checks. The alternative seems like much more work. What am I missing with regards to ORMs being a bad idea?
There are reasonable arguments for leaving most to the db; effectively exposing some VIEWs and FUNCTIONs as the application interface for any and all bindings. Like legacy java and greenfield php for example.
I'd say it's different work rather than strictly more work.
Re: The startup's Postgres survival guide
#188Earlier quoted context omitted.
It’s really not that hard, especially with an AI agent to help you. Running a Postgres server and a read replica in Hetzner with pgBackRest backing up to their S3 buckets and a cloud volume can be had for under 50€, has HA, PITR, 3-2-1 backups, and will carry you through your series A comfortably, with GDPR compliance built-in. What does the equivalent RDS setup cost you?
RDS gets you easy integration with the rest of the AWS services, which as a startup, you’re probably using quite a few of. Also, if you are nickel and diming over expenses in the 50€ range, you’re probably at the wrong startup.
Re: The startup's Postgres survival guide
#189This advice is good, but every startup I've worked with has run into lower hanging fruit than this even. Less scaling problems and more just organizational. Usually what fixes that is: 1. Don't use an ORM. 2. Use serial PKs, not meaningful fields (article mentions this). 3. Use jsonb if needed, but sparingly. 4. Make your source of truth append-only, meaning you only insert, never update or delete. You can have secon…
I'd like to add: stay away from using arrays and user defined types. They feel like a good idea at first, but will become a problem when using fetched data in your code.
And another miss, if you're managing your servers: pgtune. The default postgres configuration is very conservative regarding resources so you can get good performance gains just by adjusting them to your server specifications.