ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 85

  1. Blog

consola vs pino: 155k vs 371k Log Lines/s on Node 20

Aditya Challa·5 October 2026·6 min read

Hands-on
On this page
  1. What I tested
  2. How many lines per second does each one write?
  3. What does each one cost in size?
  4. Do they behave the same?
  5. Which one should you pick?
  6. Sources
  7. Related

I logged 100,000 lines with the same message and object through each library on this box, stdout redirected to a file: pino 10.4.0 wrote a median of about 371,000 lines per second, consola 3.4.2 about 155,000, so pino was roughly 2.4× faster. consola installs as 1 package at 448 KB on disk; pino installs as 13 packages (itself plus 12 dependencies) at 2,656 KB.

Short answer: pick pino for servers whose logs go to a file or a log shipper, and consola for CLIs, build tools and dev scripts where a human reads the output. No affiliate links in this post.

What I tested

  • Machine: 8 vCPU Intel Xeon / 15 GB RAM shared Linux cloud box, tested 6 Oct 2026 about 03:05 IST.
  • Versions: consola 3.4.2, pino 10.4.0 (both npm latest that day), Node 20.19.2, esbuild 0.28.2 minify + gzip -9.
  • Load: one fresh Node process per run with stdout redirected to a file on local disk. Each call logged a message with a counter plus a small object (counter, user, path). 2,000 warm-up lines, then 100,000 timed lines. Variants: pino default, pino with an async sonic-boom destination, consola with fancy: false (what you get when output is not a terminal), consola with fancy: true forced (20,000 lines, it is slow), and console.log of a JSON.stringify line as a baseline. Median of 7 rounds, order reversed on alternate rounds. Scripts and JSON in /workspace/bench-consola-pino/.
  • Not tested: pino transports (pino-pretty, worker-thread targets), real terminals, log shippers, Bun or Deno, browsers at runtime, and Node 22 or newer.

How many lines per second does each one write?

100k lines to a file (median of 7)Lines/sRangeImport ms
pino 10.4.0 default371,087349,445–396,23736.5
pino, async destination363,663319,118–395,33036.5
console.log + JSON.stringify184,516167,736–223,9280
consola 3.4.2, fancy: false155,130125,799–166,57330.9
consola, fancy: true forced (20k lines)19,70916,121–20,57629.8

pino beat even a hand-rolled console.log JSON line by about 2×, and consola's plain reporter sat a little below that baseline. Forcing the fancy reporter cost almost 8× against consola's own plain output, which is fine for a terminal and wasteful in CI logs. With stdout going to a file, the async destination made no measurable difference here. Writes to a pipe or a terminal behave differently, and the same buffering effect is measured in Python in stdout line vs full buffering. The same lines-per-second question for Python's logging module is measured in logging vs print.

Filtered calls matter too: one million debug() calls below the active level took 8.3 ms in pino and 21 ms in consola, so leaving debug lines in hot code is cheap in both.

What does each one cost in size?

Build (esbuild minify, gzip -9)MinifiedgzipInput files
consola, full entry (node)76,420 B22,762 B6
consola/basic entry (node)6,772 B2,600 B4
pino (node)63,288 B21,140 B30
consola (browser)6,248 B2,428 B3
pino (browser build)14,941 B5,425 B4

The surprise: bundled for Node, consola's full entry is slightly bigger than pino, most likely the fancy reporter and prompt code; I did not break the bundle down further. The consola/basic entry drops that to 2.6 KB gzip. On disk the picture flips: consola is a single dependency-free package, pino brings 12 dependencies, including sonic-boom and thread-stream. Color output in consola-style CLIs is its own size choice, measured in picocolors vs chalk, and size-limit vs bundlesize shows how to keep either number from creeping.

Do they behave the same?

Checkconsola 3.4.2pino 10.4.0
Output formatreadable text, [info] request 0 plus the objectone JSON object per line
Bytes per line in this testabout 67about 148 (adds time, pid, hostname)
10 identical messages within 1 s6 printed, then a "(repeated 4 times)" lineall 10 written
Default level3 (info)info
Child loggers / tagswithTag()child()
Redactionno built-in optionredact paths, printed [Redacted]
Interactive promptsprompt() built innone

The throttling row is the one that surprises people: consola collapses repeated identical messages by default (throttle 1,000 ms, throttleMin 5), which is friendly in a terminal and confusing when you count log lines in production. pino keeps every line and leaves pretty printing to a transport running in a worker thread, the same worker model compared in tinypool vs piscina. If your logs end up in a metrics and tracing stack, the collector side is walked through in OpenTelemetry Collector, Prometheus and Grafana.

Which one should you pick?

SituationMy pick
HTTP API or worker writing to files or a log shipperpino
Need redaction of secrets in logspino
CLI, build tool or dev script read by humansconsola
Need prompts plus pretty output in one packageconsola
Tiny bundled CLIconsola/basic

Bottom line: on this box pino 10.4.0 wrote about 371,000 JSON lines per second versus about 155,000 for consola 3.4.2, with 13 installed packages versus 1 and JSON lines versus readable text. Who should not switch to pino: CLIs and scripts where people read the output and JSON lines just get in the way. Who should not stay on consola: services that log at volume, need every line kept, or need machine-parsable logs.

How this was made: I installed both packages on the ShopperCove box, ran each logger in fresh Node processes with stdout redirected to a file, took the median of 7 order-alternated rounds, bundled each entry with esbuild, and checked throttling, levels and redaction with in-memory streams. The JSON results sit next to the scripts. The write-up was drafted with AI help and checked against that output.

Sources

  • https://github.com/unjs/consola
  • https://unjs.io/packages/consola
  • https://github.com/pinojs/pino
  • https://getpino.io/
  • https://github.com/pinojs/pino/blob/main/docs/transports.md
  • https://www.npmjs.com/package/consola
  • https://www.npmjs.com/package/pino

Related

  • https://www.shoppercove.com/blog/picocolors-vs-chalk
  • https://www.shoppercove.com/blog/logging-vs-print-localhost-lab
  • https://www.shoppercove.com/blog/stdout-buffering-line-vs-full-localhost-lab
  • https://www.shoppercove.com/blog/tinypool-vs-piscina
  • https://www.shoppercove.com/blog/size-limit-vs-bundlesize
  • https://www.shoppercove.com/blog/opentelemetry-collector-prometheus-grafana
  • https://www.shoppercove.com/blog/undici-vs-node-fetch
  • https://www.shoppercove.com/blog/tinyexec-vs-execa
node.jspinoconsolaloggingperformancebenchmarkstdoutjavascript

Lab evidence

What I found running this

Hands-on on ShopperCove box 6 Oct 2026 ~03:05 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 20.19.2). consola 3.4.2 vs pino 10.4.0, esbuild 0.28.2 minify + gzip -9. Fresh process per run, stdout redirected to a local file, 2,000 warm-up + 100,000 timed lines (message + counter/user/path object), median of 7, order alternated (lines/s): pino 371,087 (349,445-396,237); pino async sonic-boom 363,663; console.log+JSON.stringify 184,516; consola fancy:false 155,130 (125,799-166,573); consola fancy:true forced 19,709 (20k lines). Import ~36.5 vs ~30.9 ms. 1e6 filtered debug(): pino 8.3 ms, consola 21 ms. Bytes/line ~148 vs ~67. Bundle node gzip: consola full 22,762 B, consola/basic 2,600 B, pino 21,140 B; browser 2,428 vs 5,425 B. Install 1 pkg 448 KB vs 13 pkgs 2,656 KB. consola throttles 10 identical messages to 6 + repeated line; pino writes all 10; pino redact built in. Not tested: transports/pino-pretty, real TTY, shippers, Bun/Deno, Node 22+. No affiliate.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 08

    fast-glob vs globby: 0.7 ms vs 14 ms With gitignore

    5 Oct 2026

  • Plate 55

    Klona vs structuredClone: 1.4M vs 225k Clones per Second

    5 Oct 2026

  • Plate 91

    Tinyexec vs execa: 2.7 KB vs 37 KB Gzip

    5 Oct 2026

On this page

  1. What I tested
  2. How many lines per second does each one write?
  3. What does each one cost in size?
  4. Do they behave the same?
  5. Which one should you pick?
  6. Sources
  7. Related
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove