JP Camara
jpcamara.com · Personal blog · on HN since 2023
JP Camara writes about Ruby internals, concurrency, and PostgreSQL connection pooling with PgBouncer.
What HN saysCommenters call his Ruby speedup breakdown phenomenal and his PgBouncer post great, saying it explains a complicated situation the PgBouncer docs cover poorly.
19HN people shared it
6linked it in comments
23stories submitted
927story points
9 months agolast shared
2023people per year2026
Most-shared posts
- 1PgBouncer is useful, important, and fraught with peril9 people · 9 points · first shared 2023 · 1 comments on HN
- 2Speeding up Ruby by rewriting C in Ruby4 people · 297 points · first shared 2024 · 121 comments on HN
- 3Ruby methods are colorless3 people · 195 points · first shared 2024 · 235 comments on HN
- 4When good threads go bad2 people · 3 points · first shared 2025 · discussion on HN
- 5Bitmasks, Threads, and Interrupts: Concurrent, Colorless Ruby2 people · 3 points · first shared 2025 · discussion on HN
- 6The /o in Ruby regex stands for "oh the humanity "1 people · 186 points · first shared 2025 · 42 comments on HN
- 7In-Depth Ruby Concurrency: Navigating the Ruby Concurrency Landscape1 people · 166 points · first shared 2024 · 17 comments on HN
- 8Peephole optimizations: adding `opt_respond_to` to the Ruby VM, part 41 people · 38 points · first shared 2024 · 2 comments on HN
- 9Calculating the largest known prime in Ruby1 people · 23 points · first shared 2024 · 10 comments on HN
- 10The Thread API: Concurrent, Colorless Ruby1 people · 3 points · first shared 2024 · discussion on HN
- 11Bitmasks, Ruby Threads and Interrupts, oh my!1 people · 1 points · first shared 2025 · discussion on HN
- 12Defining an instruction: adding opt_respond_to to the Ruby VM, part 51 people · 1 points · first shared 2025 · discussion on HN
- 13Making Tanstack Table 1000x faster with a 1 line change1 people · 1 points · first shared 2023 · discussion on HN
- 14A comprehensive guide to PgBouncer/Postgres compatibility1 people · 1 points · first shared 2023 · 1 comments on HN
What HN people wrote when they linked it
hahahacorn · 2025-02-12
There's a phenomenal breakdown by JPCamara (https://jpcamara.com/2024/12/01/speeding-up-ruby.html) on why the Ruby#each method was rewritten in Ruby (https://bugs.ruby-lang.org/issues/20182). And bonus content from tender love: https://railsatscale.com/2023-08-29-ruby-outperforms-c/.
TL;dr - JIT rules.
jashmatthews · 2024-08-19
Best to just forget about it and listen on a connection not using pooling.
https://jpcamara.com/2023/04/12/pgbouncer-is-useful.html#listen-notify
zzzeek · 2023-09-08
what a great post, we have had a ton of issues with users using pgbouncer and it's not because things are "broken" per se, it's just the situation is very complicated, and pgbouncer's docs are also IMO in need of updating to be more detailed and in a few critical cases less misleading, specifically the prepared statements docs.
This blog post refers to this misleading nature at https://jpcamara.com/2023/04/12/pgbouncer-is-useful.html#prepared-stat… .
> PgBouncer says it doesn’t support prepared statements in either PREPARE or protocol-level format. What it actually doesn’t support are named prepared statements in any form.
IMO that's still not accurate. You can use a named prepared statement just fine in transaction mode. start a transaction (so you aren't in autocommit), use a named statement, works fine. you just can't use it again in another transaction, because it will be "gone" (more accurately, "unmoored" - might be in your session, might be in someone else's session). Making things worse, when the prepared statement is "unmoored", its name can then conflict with another client attempting to use the same name.
so to use named prepared statements, you can less ideally name them with random strings to avoid conflicts, or you can DEALLOCATE the prepared statement(s) you used at the end of your transaction. for our users that use asyncpg, we have them use a uuid for prepared statements to avoid these name conflicts (asyncpg added this feature for us here:…
btown · 2026-02-05
You don't need multiple postmasters to spawn connection processes, if you have a set of Postgres proxies each maintaining a set pool of long-standing connections, and parceling them out to application servers upon request. When your proxies use up all their allocated connections, they throttle the application servers rather than overwhelming Postgres itself (either postmaster or query-serving systems).
That said, proxies aren't perfect. https://jpcamara.com/2023/04/12/pgbouncer-is-useful.html outlines some dangers of using them (particularly when you might need session-level variables). My understanding is that PgDog does more tracking that mitigates some of these issues, but some of these are fundamental to the model. They're not a drop-in component the way other "proxies" might be.
Someone · 2025-08-20
molf · 2025-05-22
C itself is fast; it's calls to C from Ruby that are slow. [1]
Crossing the Ruby -> C boundary means that a JIT compiler cannot optimize the code as much; because it cannot alter or inline the C code methods. Counterintuitively this means that rewriting (certain?) built-in methods in Ruby leads to performance gains when using YJIT. [2]
[1]: https://railsatscale.com/2023-08-29-ruby-outperforms-c/ [2]: https://jpcamara.com/2024/12/01/speeding-up-ruby.html