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.