Pandas vs Polars vs DuckDB: Quem Sobrevive Melhor à RAM?

21 de abril de 2026
PythonPandasPolarsDuckDBBenchmark
Pandas vs Polars vs DuckDB: Quem Sobrevive Melhor à RAM?

Esse é o primeiro projeto que publico aqui no blog. Ainda não tem todo o nível de detalhe que eu quero ter nos próximos posts, mas achei interessante o suficiente pra servir como artigo inaugural.

A história é simples: eu estava acompanhando um módulo do meu MBA em Data Science e, no meio das aulas, apareceu aquela discussão clássica sobre qual ferramenta usar pra trabalhar com dados tabulares. Pandas, Polars, DuckDB — cada uma com seus fãs e seus motivos. Aí veio a coceira: em vez de ficar só no achismo, por que não medir?

Decidi começar pelo básico, a operação mais comum de todas: ler um arquivo CSV grande. Queria entender quanto de RAM cada ferramenta consome, quanto tempo leva e onde cada uma começa a sofrer. Analisei quatro arquivos CSV com tamanhos reais de 156 MB, 780 MB, 1.597 MB e 4.789 MB em disco. Para cada ferramenta, rodei o mesmo script de benchmark e registrei tempo de execução, pico de RAM, razão RAM/disco e throughput. Sem filtros, sem agregações, sem nada depois da leitura: só ler o arquivo e medir o que acontece na memória.

Tempo de execução

Parece pouco, mas em arquivos grandes a leitura já é onde a coisa começa a desandar. Então, pra começar, vamos dar uma olhada em como ficou o tempo de execução. Se liga aqui no gráfico.

PandasPolarsDuckDB
0s5s10s15s20s25s156 MB780 MB1.597 MB4.789 MB

Esse gráfico mede quanto tempo cada ferramenta levou pra carregar o CSV do início ao fim. O Polars foi muito mais rápido nos três primeiros arquivos. No arquivo de 1.597 MB, por exemplo, ele terminou em 1,47s, enquanto o Pandas levou 18,10s — mais de 12 vezes mais lento.

No maior arquivo aconteceu uma coisa meio engraçada, no sentido trágico da computação doméstica: eu tinha mais ou menos 10 GB de RAM livre pra fazer esse teste e não foi suficiente. Meu PC tem 16 GB de RAM, e a gente sabe o quanto RAM está cara hoje. Eu estava acompanhando pelo btop++, vi a memória acabar, o mouse começou a travar, o VS Code travou junto e eu tive que reiniciar a máquina.

Então eu não sei exatamente quanto tempo o Pandas levaria no arquivo maior. Se você tiver mais RAM e quiser brincar com isso, pega uns arquivos grandes e testa. Aqui, a comparação real ficou entre Polars e DuckDB, com os dois chegando ali perto de 22 a 24 segundos.

Pico de RAM utilizado

O próximo gráfico interessante é o pico de RAM utilizado. O nome é meio autoexplicativo, mas ele é importante porque mostra onde a leitura começa a bater no limite físico da máquina.

PandasPolarsDuckDB
0 MB2 GB4 GB6 GB8 GB10 GB156 MB780 MB1.597 MB4.789 MB

Aqui a ideia é registrar o maior uso de memória observado enquanto cada ferramenta lia o arquivo. Todas consumiram mais RAM do que o tamanho em disco, porque o parser precisa de espaço extra para montar as estruturas internas.

No arquivo de quase 4,8 GB, o DuckDB chegou a quase 10 GB de RAM no pico. O Polars ficou em 8.697 MB. Já o Pandas, infelizmente, eu não consegui medir até o fim. Como eu disse, eu tinha cerca de 10 GB livres e não teve como: estourou. Provavelmente ficaria acima disso, talvez perto de 12 GB, mas isso aqui já entra como leitura minha, não como número medido.

Razão RAM / Disco

Outra coisa interessante de olhar é a razão RAM/disco. Ela ajuda a sair do “será que cabe?” e transformar isso em uma conta mais concreta antes de rodar o script.

PandasPolarsDuckDB
1,5x1,8x2,1x2,4x2,8x156 MB780 MB1.597 MB4.789 MB

Esse gráfico divide o pico de RAM pelo tamanho real do arquivo em disco. É um multiplicador: mostra quantas vezes a ferramenta precisa de memória além do tamanho do arquivo.

Todos ficaram perto de 2x nos arquivos intermediários. Na prática, isso significa que pra ler um CSV de quase 5 GB você precisa ter pelo menos 9 a 10 GB de RAM disponível. Saber essa razão antes de rodar evita surpresa no meio do script. E deixando claro: o Pandas provavelmente tenderia a subir também no arquivo maior, mas como ele não concluiu, eu não tenho esse ponto medido no gráfico.

Throughput (MB/s)

E aí temos o throughput em MB/s, que é uma forma rápida de enxergar quantos megabytes por segundo cada ferramenta conseguiu processar.

PandasPolarsDuckDB
0 MB/s200 MB/s400 MB/s600 MB/s800 MB/s1.000 MB/s1.200 MB/s156 MB780 MB1.597 MB4.789 MB

Esse número é calculado dividindo o tamanho do arquivo pelo tempo de leitura. O Polars dispara aqui: passa de 1.000 MB/s nos arquivos intermediários e fica muito acima do Pandas nos testes que o Pandas conseguiu concluir.

Pra quem não conhece, o Polars é escrito em Rust e tem uma arquitetura bem voltada pra eficiência e paralelismo. O DuckDB é um banco analítico escrito em C++, também muito forte pra esse tipo de trabalho. Já o Pandas é uma biblioteca Python com muita coisa otimizada por baixo em C e Cython, mas carrega um modelo mais antigo e nem sempre brilha quando o arquivo começa a ficar grande.

No maior arquivo, o throughput do Polars cai bastante, provavelmente por pressão de memória, mas ainda fica levemente acima do DuckDB. O Pandas, além de consumir muita memória, ficou bem mais lento nos arquivos que concluiu.

Todos os dados brutos

E aqui fica a tabelinha com todos os dados brutos, do jeito que saíram do benchmark. Ela é útil pra conferir cada número sem depender só da leitura visual dos gráficos.

FerramentaArquivoTamanho realPico RAMTempoRAM/DiscoThroughput
PandasArquivo 1156 MB340 MB2,20s2,18x71 MB/s
PandasArquivo 2780 MB1.631 MB9,45s2,09x83 MB/s
PandasArquivo 31.597 MB3.342 MB18,10s2,09x88 MB/s
PandasArquivo 44.789 MBFALHOU---
PolarsArquivo 1156 MB281 MB0,29s1,80x538 MB/s
PolarsArquivo 2780 MB1.571 MB0,73s2,01x1.068 MB/s
PolarsArquivo 31.597 MB3.251 MB1,47s2,04x1.086 MB/s
PolarsArquivo 44.789 MB8.697 MB22,50s1,82x213 MB/s
DuckDBArquivo 1156 MB406 MB1,31s2,60x119 MB/s
DuckDBArquivo 2780 MB1.487 MB4,15s1,91x188 MB/s
DuckDBArquivo 31.597 MB3.369 MB8,55s2,11x187 MB/s
DuckDBArquivo 44.789 MB9.894 MB24,21s2,07x198 MB/s

Olhando tudo junto, dá pra ver que o problema não é só “qual biblioteca é mais rápida”. É também quanto de memória ela pede, como ela escala conforme o arquivo cresce e se ela continua confortável quando o dataset começa a encostar no limite da máquina.

O que eu concluo com esse primeiro recorte: Polars quando velocidade importa, isso ficou bem claro. DuckDB quando eu quero SQL e previsibilidade em arquivo grande. E Pandas quando o arquivo ainda cabe com folga na RAM ou quando o ecossistema ao redor pesa mais que performance.

Como esse foi um projeto relativamente antigo, eu não lembro todos os pormenores da execução, então preferi não inventar detalhe que eu não tenho registrado. O que está aqui é o que eu medi e o que aconteceu na prática. E esse teste foi só leitura. Ainda dá pra testar filtros, agregações, joins, escrita, tudo isso. Mas só esse pedaço já mostra uma coisa: em dados grandes, escolher biblioteca sem medir é apostar RAM no escuro.

E cuidado ao tentarem isso em casa, meus caros cavaleiros. Se a máquina não tiver RAM sobrando, pode acontecer igual aconteceu comigo: travar tudo e ter que reiniciar o PC. Eu já rodei o teste meio esperando que isso pudesse acontecer, mas se tivesse algo importante aberto na hora, teria sido uma dor de cabeça bonita.

É isso. Esse foi o primeiro artigo do blog, e a ideia é continuar trazendo esse tipo de experimento por aqui. Eu sempre fiz essas coisas mais sozinho, meio no meu canto; agora a graça é usar esse espaço pra trocar uma ideia e compartilhar um pouco do processo também.