Ask
118
@iron_camber ·

prisma opened 190 connections on neon during a spike and connection_limit=1 didn't help Serverless Driver

Small app, normally 2-3 req/s. A newsletter mention took us to about 40 req/s for an hour and the logs filled with FATAL: sorry, too many clients already. The Neon dashboard showed 190 active connections. I added ?connection_limit=1&pool_timeout=20 to the direct connection string, redeployed, and peak came down to about 48 but requests started timing out around 10 seconds instead. What am I missing?

9 answers Share
Report

Answering anonymously — a moderator will review it first.

  • @migration_marek · 3h ago · 3 replies

    connection_limit caps the pool inside one process. You have roughly 48 warm instances, so you got 48 pools of one, which is exactly what you measured. There is no client-side setting that can cap a number your platform decides.

    Use the pooled endpoint — on Neon that is the host with -pooler in it, which is pgbouncer in transaction mode. Keep connection_limit=1 as well, and add pgbouncer=true to the URL so the client stops using named prepared statements.

    What you give up in transaction mode: session state. SET that outlives a statement, advisory locks held across statements, LISTEN/NOTIFY, and long interactive transactions all behave differently or not at all. For CRUD over HTTP requests, none of that matters.

    141
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @airflow_amir · 8h ago

      The pgbouncer=true param is the one everyone forgets, and the failure is confusing: it works fine at low traffic and then throws prepared statement "s0" already exists the moment two requests land on the same pooled backend.

      40
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
    • @iron_camber · 8h ago

      Pooled host plus that flag: peak server-side connections went to 11 and p95 is back under 200ms. The 10s timeouts were the pool queue, as someone else said below.

      22
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @query_quinn · 18h ago

    Also confirm you are not constructing a client per request. The classic version of this is dev-only (HMR creating a new client on every save until the db falls over) but the serverless version is real too — a client created inside a handler instead of at module scope means a fresh pool per invocation and no reuse across warm calls.

    58
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @slowtrainjo · 9h ago · 2 replies

    Different angle: for read-heavy paths use the HTTP driver and hold no connection at all. Neon's serverless driver over fetch, either through the Prisma driver adapter or drizzle's neon-http, turns a query into a request. No pool, nothing to exhaust, works on edge runtimes.

    The catch is interactive transactions — you cannot hold one open across statements over HTTP, so anything transactional stays on a pooled TCP connection.

    44
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @nadia_brill · 18h ago

      We ended up split exactly like that: HTTP driver for the ~95% of traffic that is single reads, a pooled TCP client for the three endpoints that need a real transaction. Slightly annoying to have two clients, much easier than tuning one to do both.

      17
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @brinekeeper · 3h ago

    Your 10s timeouts were not the database. pool_timeout=20 means a request waits up to 20 seconds for a free slot in a pool of size 1, so you converted connection errors into a queue. That is usually the right trade but you have to know you made it.

    26
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @mise_en_mess · yesterday · 2 replies

    Just size the compute up, max_connections scales with it and you stop thinking about pools.

    9
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @layer_shift_lu · 3h ago

      True, and you would be paying continuously to hold mostly-idle sockets for an hour of traffic per month. The pooler costs nothing and fixes the shape of the problem rather than the size of it.

      8
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report