---
term: 'Pooling de Conexões em Bancos Gerenciados Serverless'
seoTitle: 'Pooling de Conexões Serverless em Bancos de Dados Gerenciados'
headline: 'O que é pooling de conexões serverless?'
slug: pooling-de-conexoes-serverless
category: database
shortDefinition: 'O pooling de conexões serverless é uma técnica que compartilha poucas conexões reais de banco entre muitas instâncias de função efêmeras.'
relatedTerms:
  - multi-tenant-database-architecture
  - serverless-architecture
  - auto-generated-database-apis
  - database-index
contrastsWith:
  - serverless-architecture
faq:
  - question: 'Por que o serverless esgota as conexões do banco de dados?'
    answer: 'Porque dois modelos de escala colidem: computação serverless multiplica instâncias por requisição, enquanto o banco tem um orçamento fixo de conexões — muitas vezes em torno de 100 por padrão. Cada instância de função abre a sua própria conexão, segura durante o tempo ocioso, e um pico de tráfego que cria 500 instâncias pede 500 conexões de uma vez. O banco recusa o excedente, e consultas sem relação nenhuma começam a falhar.'
  - question: 'O que um pooler como o PgBouncer faz na prática?'
    answer: 'Ele fica entre o seu código e o banco, aceita milhares de conexões de cliente baratas e as multiplexa sobre um pool pequeno de conexões reais de servidor. Os clientes acham que têm uma conexão; na verdade pegam uma emprestada por uma transação ou sessão e devolvem. O banco enxerga um conjunto calmo e fixo de conexões, não importa quantas funções subam.'
  - question: 'Qual a diferença entre transaction pooling e session pooling?'
    answer: 'A duração do empréstimo. No session pooling, a conexão real fica com o cliente pela sessão inteira — seguro para qualquer recurso, mas um cliente ocioso ainda estaciona uma conexão. No transaction pooling, a conexão é emprestada só enquanto a transação roda e depois é recolhida, o que multiplica muito o compartilhamento mas quebra estado de sessão: prepared statements, variáveis de sessão e LISTEN/NOTIFY exigem cuidado ou falham.'
  - question: 'Por que as conexões disparam quando as funções escalam?'
    answer: 'Uma plataforma serverless trata concorrência clonando instâncias, e cada clone inicializa o seu próprio cliente de banco. O reúso de conexão só acontece dentro de uma instância quente, nunca entre instâncias. Então concorrência 300 significa 300 pools de tamanho um — o pior formato possível: todo o overhead do pooling sem nenhum compartilhamento. O fan-out é estrutural, não um bug no seu código.'
  - question: 'Qual deve ser o tamanho do pool de conexões?'
    answer: 'Bem menor do que a intuição sugere. A vazão costuma atingir o pico com um pool próximo do paralelismo real do banco — uma regra prática comum é o número de núcleos vezes dois, ajustado pelas esperas de disco — e não nas centenas. Além disso, conexões extras só somam contenção e custo de memória sem somar vazão. O trabalho do pooler é justamente fazer um pool pequeno parecer infinito para quem chama.'
  - question: 'Ainda preciso de pooler usando um BaaS?'
    answer: 'Não para o seu próprio tráfego — esse é o ponto. Um backend gerenciado encerra as requisições do cliente como chamadas HTTPS sem estado na camada de API; a camada de servidor dele mantém pools longevos e bem dimensionados até o banco. As suas funções e apps nunca seguram conexões de banco, então o cenário de esgotamento desaparece em vez de ser mitigado. Poolers só voltam à conversa se você conectar ferramentas externas direto no banco.'
  - question: 'Quais as desvantagens dos poolers de conexão?'
    answer: 'Eles somam um salto de rede em latência, viram mais um componente para operar e monitorar, e o modo transação muda a semântica em silêncio — recursos com escopo de sessão deixam de se comportar como documentado. Um único processo de pooler pode virar o gargalo sob carga irregular, e dimensioná-lo errado apenas move a fila de lugar. É infraestrutura essencial, mas é infraestrutura.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'PgBouncer features — pooling modes'
    url: 'https://www.pgbouncer.org/features.html'
  - name: 'PostgreSQL connection settings (max_connections)'
    url: 'https://www.postgresql.org/docs/current/runtime-config-connection.html'
  - name: 'Connection pool (Wikipedia)'
    url: 'https://en.wikipedia.org/wiki/Connection_pool'
  - name: 'Serverless Architectures — Mike Roberts (martinfowler.com)'
    url: 'https://martinfowler.com/articles/serverless.html'
cta:
  title: 'Pule a matemática de conexões de vez'
  text: 'No Back4app os seus clientes e as funções de Cloud Code falam HTTPS sem estado com APIs geradas automaticamente enquanto a plataforma mantém pools bem dimensionados até o banco gerenciado — sem pooler para subir, sem max_connections para ajustar, sem incidente de esgotamento às 3 da manhã.'
  linkText: 'Comece grátis'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-08-25'
translationKey: serverless-connection-pooling
---

**O pooling de conexões serverless é uma técnica que compartilha poucas conexões reais de banco entre muitas instâncias de função efêmeras.** Ele existe porque dois modelos de escala discordam: a [computação serverless](/glossary/pt/arquitetura-serverless/) responde à carga multiplicando instâncias, enquanto o banco trata cada conexão como um recurso caro, sustentado por memória e com teto rígido. Junte os dois de forma ingênua e um pico modesto de tráfego vira uma indisponibilidade com `too many connections`.

## Principais pontos

| Pergunta | Resposta |
| --- | --- |
| A colisão | Funções escalam clonando; conexões têm teto e custam caro |
| O sintoma | `FATAL: sorry, too many clients already` durante os picos |
| A correção | Um pooler multiplexa muitos clientes sobre poucas conexões reais |
| O botão | Transaction vs. session pooling — compartilhamento vs. compatibilidade |
| A resposta do BaaS | Clientes falam HTTPS sem estado; a plataforma é dona do pool |

## A falha, observada do lado do banco

```sql
-- O que o banco vê durante um pico de tráfego serverless:
SELECT state, count(*)
FROM pg_stat_activity
GROUP BY state;
--  active               |   14
--  idle                 |  483     ← estacionadas por instâncias quentes
SHOW max_connections;    --  100    ← o teto que elas já estouraram

-- Cada conexão é um processo real segurando memória real —
-- por isso o teto existe, e por isso aumentá-lo não é a correção.
```

O formato do problema: cada instância de função abre a sua própria conexão, segura durante o ocioso entre invocações, e a contagem de instâncias é decidida pelo tráfego, não por você. O reúso acontece apenas *dentro* de uma instância quente — nunca entre instâncias —, então concorrência 300 significa 300 pools de uma conexão. Aumentar [`max_connections`](https://www.postgresql.org/docs/current/runtime-config-connection.html) compra folga a um custo real de memória e perde para o próximo pico maior.

Num backend gerenciado, o código de aplicação sai dessa briga por completo — chamadas de SDK são requisições HTTPS sem estado, e nenhum cliente jamais segura uma conexão de banco:

**JavaScript:**

```javascript
// JavaScript / Node.js — Back4app JS SDK
// Inside a serverless function: no driver, no pool, no connection to leak.
// Each SDK call is a stateless HTTPS request; pooling happens platform-side.
Parse.initialize('APP_ID', 'JS_KEY');
Parse.serverURL = 'https://parseapi.back4app.com';

export async function handler(event) {
  const query = new Parse.Query('Order');
  query.equalTo('status', 'pending');
  query.limit(20);
  const orders = await query.find();  // request returns; nothing stays open
  return orders.map((o) => o.id);
}
// 1,000 concurrent invocations = 1,000 HTTP requests,
// not 1,000 database connections.
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// No driver, no pool, no connection to leak from the client side.
// Each SDK call is a stateless HTTPS request; pooling happens platform-side.
await Parse().initialize(
  'APP_ID',
  'https://parseapi.back4app.com',
  clientKey: 'CLIENT_KEY',
);

Future<List<String>> pendingOrderIds() async {
  final query = QueryBuilder<ParseObject>(ParseObject('Order'))
    ..whereEqualTo('status', 'pending')
    ..setLimit(20);
  final response = await query.query(); // request returns; nothing stays open
  return response.results!
      .map((o) => (o as ParseObject).objectId!)
      .toList();
}
// A burst of clients = a burst of HTTP requests,
// not a burst of database connections.
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// No driver, no pool, no connection to leak from the client side.
// Each SDK call is a stateless HTTPS request; pooling happens platform-side.
ParseSwift.initialize(
  applicationId: "APP_ID",
  clientKey: "CLIENT_KEY",
  serverURL: URL(string: "https://parseapi.back4app.com")!
)

let query = Order.query("status" == "pending")
  .limit(20)
query.find { result in
  if case .success(let orders) = result {
    render(orders)                 // request returned; nothing stays open
  }
}
// A burst of clients = a burst of HTTP requests,
// not a burst of database connections.
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// No driver, no pool, no connection to leak from the client side.
// Each SDK call is a stateless HTTPS request; pooling happens platform-side.
Parse.initialize(
    Parse.Configuration.Builder(context)
        .applicationId("APP_ID")
        .clientKey("CLIENT_KEY")
        .server("https://parseapi.back4app.com")
        .build()
)

val query = ParseQuery.getQuery<ParseObject>("Order")
query.whereEqualTo("status", "pending")
query.limit = 20
query.findInBackground { orders, e ->
    if (e == null) render(orders)  // request returned; nothing stays open
}
// A burst of clients = a burst of HTTP requests,
// not a burst of database connections.
```

## Como o pooler absorve o fan-out

```mermaid
flowchart LR
  accTitle: Pooler de conexões entre funções serverless e o banco de dados
  accDescr: Centenas de instâncias de função efêmeras abrem conexões de cliente baratas para um pooler, que as multiplexa sobre um conjunto fixo e pequeno de conexões reais de banco, mantendo o banco abaixo do seu teto de conexões.
  F1["Função ×500<br/>(pico)"] --> P["Pooler<br/>(ex.: PgBouncer)"]
  F2["Função ×500<br/>(próximo pico)"] --> P
  P -->|"20 conexões reais"| DB[("Banco de dados<br/>max_connections: 100")]
  P -. "clientes esperam brevemente<br/>em vez de falhar" .-> F1
```

Um pooler como o [PgBouncer](https://www.pgbouncer.org/features.html) aceita conexões de cliente aos milhares — cada uma barata do lado dele — e empresta conexões reais de servidor de um pool pequeno só quando chega trabalho. O banco enxerga vinte conexões calmas; quinhentas funções acreditam ter uma cada. Quando a demanda excede o pool, os clientes esperam milissegundos numa fila em vez de receber erro — convertendo uma falha dura em latência modesta.

O dimensionamento do pool é onde a intuição mais erra. O paralelismo útil de um banco é limitado por núcleos e disco — a vazão normalmente atinge o pico com um pool na casa das poucas dezenas, perto do número de núcleos vezes dois, e depois *cai* conforme mais conexões somam contenção. A aritmética do pooler funciona porque requisições serverless são curtas: uma conexão que atende uma transação de 8 ms pode atender bem mais de cem delas por segundo, então vinte conexões reais absorvem confortavelmente milhares de invocações de função. O [pool](https://en.wikipedia.org/wiki/Connection_pool) não é um cache de conveniência; é um gargalo deliberado, colocado onde enfileirar é barato.

O botão decisivo é *quanto tempo dura o empréstimo*.

## Transaction pooling vs. session pooling

| Dimensão | Session pooling | Transaction pooling |
| --- | --- | --- |
| Duração do empréstimo | A sessão inteira do cliente | Uma transação, depois recolhida |
| Multiplicador de compartilhamento | Baixo — clientes ociosos estacionam conexões | Alto — ideal para trabalho serverless curto |
| Prepared statements | Totalmente suportados | Só com suporte em nível de protocolo, configurado explicitamente |
| Estado de sessão (`SET`, tabelas temporárias, LISTEN/NOTIFY) | Funciona | Quebra — transações diferentes podem cair em conexões diferentes |
| Melhor para | Apps longevos, ferramentas de admin, migrações | Tráfego web e serverless de requisição/resposta |

O modo transação é o que torna cargas serverless viáveis — uma função que roda uma transação de 8 ms não deveria ser dona de uma conexão pelo seu tempo de vida quente de vários minutos —, mas ele não sai de graça: tudo que assume que "a minha conexão" persiste entre comandos vira um bug sutil. O conselho consagrado é transaction pooling para o tráfego de requisições e uma conexão direta ou por sessão para migrações e qualquer coisa com estado.

## Casos de uso comuns

- **Funções serverless e de edge batendo em SQL.** O caso canônico — contagem de instâncias irregular contra um orçamento fixo de conexões.
- **Muitos serviços pequenos, um banco.** Vinte serviços × pools padrão de dez conexões = 200 conexões que ninguém planejou; um pooler compartilhado devolve a sanidade à aritmética.
- **[Plataformas multi-tenant](/glossary/pt/banco-de-dados-multi-tenant/).** Cargas por tenant multiplicam a demanda por conexões; o pooling mantém o orçamento do banco compartilhado exequível.
- **Rajadas de tráfego em bancos modestos.** Picos de dia de lançamento enfileiram no pooler por milissegundos em vez de dar erro no banco.
- **Proteger o primário durante incidentes.** Um pool de tamanho fixo é um anteparo: clientes desgovernados esgotam a fila do pooler, não a memória do banco.

## Você deveria rodar o seu próprio pooler? Matriz de decisão

| Rode um pooler quando… | Pule quando… |
| --- | --- |
| Funções ou muitos serviços conectam direto no SQL | Um BaaS gerenciado encerra o tráfego do cliente na camada de API |
| Erros de conexão aparecem em picos de carga | Tráfego estável de poucos servidores longevos com pool no cliente |
| Você opera o banco e o orçamento dele | A plataforma já faz pooling entre a camada de API e o banco |
| Tenants ou times dividem um mesmo banco | A carga é um app, um pool, bem dentro dos limites |
| Você consegue operar mais um componente crítico | Ninguém está de plantão para o pooler |

A assimetria honesta: um pooler resolve o esgotamento de conexões; um backend gerenciado o *dissolve*. Quando os clientes falam HTTPS com [APIs geradas automaticamente](/glossary/pt/apis-geradas-automaticamente/), o fan-out nunca chega à camada de banco — o pooling continua acontecendo, mas como infraestrutura bem testada de outra pessoa, e não como componente seu.

## Limitações e trade-offs

- **Um pooler é um componente.** Ele exige deploy, monitoramento, failover e upgrades — você trocou um problema de recurso por um problema de operação, num câmbio favorável mas não gratuito.
- **O modo transação muda a semântica.** Prepared statements, variáveis de sessão e advisory locks deixam de se comportar como documentado; as falhas são intermitentes e dependentes de carga — o pior tipo.
- **Um salto a mais custa latência.** Tipicamente abaixo de um milissegundo dentro da rede, mas está no caminho de toda consulta.
- **O pooler pode ser o gargalo.** Um pooler de thread única sob um pico violento enfileira fundo; o teto mudou de lugar, não sumiu.
- **Pooling não conserta consulta lenta.** Ele raciona conexões; uma consulta que segura o empréstimo por segundos mata o pool de fome. Consultas rápidas — e os [índices](/glossary/pt/indice-de-banco-de-dados/) por trás delas — continuam sendo a alavanca real de capacidade.

## Pooling de conexões no Back4app

O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. A arquitetura dele responde à questão do pooling de forma estrutural: apps cliente e funções de Cloud Code emitem requisições HTTPS sem estado, e a camada de servidor da plataforma — não o seu código — mantém pools longevos e bem dimensionados até o banco gerenciado. O fan-out de instâncias do lado da computação nunca se traduz em fan-out de conexões do lado do banco, que é exatamente a propriedade que este artigo inteiro existe para projetar.
