Stop 19 · Monitoring & LoggingTopics · 3/9

Pino

Part of the Backend Developer Roadmap

In short

Pino is a Node logger built for speed. It writes plain JSON lines quickly and leaves pretty-printing and shipping to other tools, so logging barely slows your API.

An extremely fast, low-overhead JSON logger for Node.js — a popular modern alternative to Winston, especially for high-throughput APIs where logging overhead matters.

The purple blob types super fast on a small stenotype machine with a paper strip curling out.

Think of it like this

The court stenographer

In court, the stenographer doesn't write neat paragraphs during the hearing. She types fast shorthand to keep up, and a clean transcript is prepared later. Pino works the same way: fast raw JSON now, pretty formatting later by a separate tool.

Watch it happen

From log call to log storage

API process
Worker thread
Log storage
log.info({ orderId })

1/5Your handler logs an object. Pino turns it into one JSON line with very little work.

The big ideas

What you need to know

Fast by design

Pino keeps main-thread work small and skips heavy formatting, which matters when you log on every request.

JSON lines only

One JSON object per line, with a numeric level, a timestamp and the message. Easy for log tools to parse.

Built-in redaction

redact: ['req.headers.authorization'] hides sensitive fields everywhere, so nobody can forget.

pino-http for Express

Logs each request and response with timing, and gives you req.log already carrying the request ID.

See it in code

Walk through the code

ts
1import pino from "pino";2import pinoHttp from "pino-http";3import express from "express";4 5const logger = pino({6  level: process.env.LOG_LEVEL ?? "info",7  redact: ["req.headers.authorization", "req.headers.cookie"],8});9 10const app = express();11app.use(pinoHttp({ logger }));12 13app.get("/orders/:id", (req, res) => {14  req.log.info({ orderId: req.params.id }, "fetching order");15  res.json({ id: req.params.id });16});

1/3One logger for the app. Auth headers and cookies never reach the logs.

Locally, run node dist/server.js | npx pino-pretty for readable output. In production, keep the raw JSON for your log system.

Save yourself the pain

Common mistakes

Oops

Running pino-pretty in production.

Do this instead

It adds work and turns logs into text your log tool can't parse. Keep it for local development.

Oops

Writing logger.info("order " + JSON.stringify(order)).

Do this instead

That buries fields inside a string. Pass the object first: logger.info({ order }, "order created").

Your mission

Swap in Pino

~20 min

Quick check

Why does Pino recommend pretty-printing outside your app process?

Go deeper

  1. 1Set up Pino in an Express app and compare its output format to Winston's.
  2. 2Learn why Pino's performance-first design makes it popular for high-traffic services.
  3. 3Use `pino-pretty` for readable local development output.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge