Supabase, and which pooler to use
MapSocket keeps its control plane on Supabase and works with customers' Supabase databases. The pooler you pick decides whether prepared statements and live updates work.
Supabase shows up twice in MapSocket. Our own control plane (accounts, projects, geofences, event history) is a Supabase Postgres in Tokyo. And many of our users keep their spatial data in Supabase too: it ships PostGIS, and the dashboard hands you a connection string in seconds.
Both uses hit the same question sooner or later: which connection string? Supabase offers a direct connection and two kinds of pooled one, and they behave differently in ways that matter for us.
Three ways in
- Direct connection to the database host. A real Postgres session, but IPv6-only on Supabase’s newer projects, which many hosting platforms can’t reach.
- Session pooler, port
5432on thepooler.supabase.comhost. Each client connection gets its own server session for as long as it’s open. Works over IPv4. - Transaction pooler, port
6543on the same host. A server session is lent to you for one transaction at a time, then handed to someone else.
The transaction pooler packs the most clients onto the fewest server connections, which is why it’s the default advice for serverless functions. It also breaks anything that relies on session state.
What session state we rely on
Prepared statements. The API prepares its queries once per connection and reuses them, which saves parsing and
planning on every request. Under transaction pooling, the next transaction may land on a server session that has
never heard of that statement. So our own DATABASE_URL uses the session pooler on 5432.
LISTEN/NOTIFY. Live tile updates work like this: a trigger on your table calls pg_notify, and the tilefeed
worker for that source, which has run LISTEN on a connection to your database, hears it and regenerates the tiles
the change touched. A LISTEN belongs to a session. Through the transaction pooler there’s no session to belong to,
so notifications never arrive.
That’s why MapSocket checks the connection string you paste in. A transaction pooler (port 6543, or
pgbouncer=true in the URL) gets a warning that live updates may not work and a suggestion to use a direct or session
connection. The session pooler on 5432 passes without one. The source still works; tiles just refresh on a schedule rather than seconds after a change.
Which one to paste into MapSocket
For a Supabase database you want live tiles from:
- Use the session pooler (port
5432) if your network is IPv4-only, which includes most of the internet. - Or the direct connection, if you can reach it over IPv6.
- Not the transaction pooler on
6543.
Then install the triggers MapSocket generates for your tables (the dashboard shows the SQL), and edits made anywhere (the Supabase table editor, your app, a migration) reach the map in seconds.
Region matters
Our control plane and our API machine are both in Tokyo, because one API request can make several database round trips. The same logic applies to your source database. MapSocket reads from it whenever tiles regenerate, so a database close to Tokyo regenerates faster than one on the other side of the world. It works from anywhere; it’s just a few hundred milliseconds quicker from nearby.