The first time I truly appreciated less wasn’t during some tutorial moment—it was during an incident. A service was flapping, the logs were huge, and my editor felt like the wrong tool: too slow to open multi‑gigabyte files, too easy to accidentally modify something, and too distracting when I needed calm, repeatable navigation.
less is the Linux pager I reach for when I want to read, not edit. It shows a file (or command output) one screen at a time, lets you move forward and backward, and usually doesn’t need to load the entire file into memory. That last point matters in real systems: logs are big, and when something breaks, they’re often getting bigger while you’re trying to understand them.
If you already type | less by habit, this post turns that habit into a toolkit: efficient navigation, search patterns that save minutes, options that actually matter, and workflows for modern 2026 setups (containers, journalctl, Kubernetes, CI logs, and terminals with color). I’ll also call out common foot-guns—places where less makes you think you’re seeing “everything” when you’re not.
less as a pager (and why it feels faster than your editor)
I think of a pager like a “read-only camera” pointed at text. You can pan around, zoom to interesting parts (search), and exit instantly. You don’t get mode switches, swap files, plugins, or accidental edits—just navigation.
A couple of practical consequences:
lessis a great fit for large files because it reads on demand. In practice, opening a 1–5 GB log file is often “instant enough” (typically tens of milliseconds to a few hundred milliseconds to render the first screen, depending on disk and filesystem cache) while editors may take seconds or more.- You can use
lesson streams. That’s the big one: you’re not limited to files. You can page through output from almost any command.
Basic usage:
less /var/log/syslog
Or, with a pipeline:
dmesg | less
If you remember only one mental model, use this: less is the reading layer you put between you and too-much-text.
One small nuance that explains a lot of “why does this feel different?” moments: less behaves best when it can seek (jump around) in an actual file. When you feed it a pipe, it’s reading a stream that may not have an end yet, and it may have to buffer data to let you scroll backward. That doesn’t make pipes bad—pipelines are the whole point—but it explains why paging a huge on-disk log often feels snappier than paging an endless stream.
Movement, search, and “reading like a debugger”
When I’m investigating a log, I want the same few moves over and over, like stepping through code in a debugger. less gives you that muscle memory.
Core navigation keys I rely on:
Space: next pageb: previous pageEnter: next linek/j: up / down (Vim-style)g: start of inputG: end of inputq: quit
There are a few “bonus” movement keys that become addictive once you use them for a week:
d/u: half-page down / up (great for slow scanning)RightArrow/LeftArrow(often works): horizontal movement when using-SESC-)/ESC-(: half-screen horizontal movement (useful when arrows behave differently in odd terminals)rorCtrl+L: repaint the screen (my go-to when output gets visually weird)
Searching is where less starts paying rent:
/pattern: search forward forpattern?pattern: search backward forpatternn: next matchN: previous match
Example: start reading kernel messages and jump through failures.
dmesg | less
/fail
n
n
If you want less to start at the first match automatically, -p is the cleanest:
dmesg | less -p "fail"
(That’s one of my favorite “feel smart” flags because it saves you a few keystrokes every single time.)
Case-insensitive search is another daily driver. If I’m searching for something like error, I don’t want to care about casing:
less -i /var/log/nginx/error.log
A small but important trick: sometimes you want to “search without noise.” less can highlight every match, which is great until it isn’t. Two options that change the feel:
-g: highlight only the last match-G: disable highlighting
In incident work, I usually pick -g so the last thing I searched stays visible without turning the whole screen into a highlighter pen.
Line numbers matter when you’re handing evidence to someone else (or writing a postmortem). Enable them with -N:
dmesg | less -N
Now you can say “check around line 812” and mean it.
One more “debugger mindset” thing: I often treat / + n as my stepping controls, and g / G as my breakpoints. If I’m in a file I don’t fully trust yet (maybe it’s truncated, rotated, or partial), I’ll do this quick sanity loop:
1) G to see what the end looks like
2) g to confirm the start is sensible
3) /ERROR (or whatever matters)
4) n a few times to see if errors cluster or spread out
That alone tells me whether I’m dealing with a single spike, a steady stream, or multiple waves of failure.
Help, discoverability, and toggles inside less
Most people learn less like a handful of spells. But less actually has a built-in reference that’s worth using, especially on machines where your usual dotfiles aren’t present.
- Press
h(orH) to open help. It’s long, but it’s searchable like everything else. - Press
qto exit help and return to what you were reading.
Two features I wish more people used:
1) Toggle options while you’re already inside less.
Inside less, type - followed by the option flag to toggle it. For example:
- Toggle chopped lines (wrap vs truncate):
-S - Toggle line numbers:
-N
I like this because it turns flags into “modes” you can flip without restarting. When I’m reading JSON logs, I want -S. When I’m reading a prose-ish file, I might turn it off so paragraphs wrap nicely.
2) Get your bearings (what file am I viewing, where am I?).
Inside less:
=orCtrl+Gshows file info and your position:fprints the current file name (and some status)
When you’re paging command output, = is also a reality check: am I 2,000 lines into this stream, or 200,000? If you’re debugging from a jump host at 3 AM, that context matters.
Pipelines: the reason I type | less without thinking
Most of my less time is not “open a file.” It’s “page through a command output that would otherwise scroll away.”
A simple pattern:
| less
Some real-world examples I use constantly:
1) Kernel ring buffer messages:
dmesg | less
2) Systemd journal for a unit (last boot):
journalctl -b -u ssh.service | less
3) Git diffs when they get big:
git diff | less
4) Kubernetes logs (when you don’t want to tail forever):
kubectl logs deploy/api –since=2h | less
5) Docker logs for a container:
docker logs –since 2h my-api | less
If your tool already has its own pager integration, it often still ends up being less under the hood. Many CLIs respect $PAGER (and sometimes $LESS). In 2026, lots of tools ship with nice formatting by default, which leads to the next practical issue: color.
A subtle pipeline habit that saves me time: I often arrange commands so that selection happens before formatting. For example, if I’m going to use jq to colorize JSON, I try to filter down to the relevant messages first (time range, unit, container), and then format. It keeps paging fast and reduces cognitive noise.
Options that make less feel “modern” in 2026 terminals
Out of the box, less is useful. With the right options, it becomes a seriously good log viewer for today’s color-heavy, JSON-heavy command output.
Here are the options I reach for most, and what they change in practice.
1) Show line numbers: -N
less -N /var/log/syslog
2) Don’t wrap long lines: -S
This is essential for JSON logs, stack traces, long URLs, and Kubernetes output.
kubectl get events -A -o wide | less -S
You can then scroll horizontally inside less with the arrow keys (terminal-dependent) or with ESC then ) / (.
3) Keep ANSI colors: -R (or -r, carefully)
Many modern commands output ANSI color codes. less can either show them as gibberish or render them.
-Rshows “raw control characters” in a safer way for common color sequences.-ris more permissive and can do surprising things on weird input.
I default to -R:
kubectl describe pod api-123 | less -R
4) Quit if it fits: -F
When output is short, you don’t want to enter the pager at all.
less -F README.md
This is also nice in scripts or aliases where you sometimes have short output.
5) Quit at end-of-file: -E
This makes less behave a bit more like a viewer that closes once you reach the end.
less -E /var/log/auth.log
6) Hide line numbers in prompts/messages: -n
This is not the inverse of -N (it doesn’t remove -N’s on-screen line numbers), but it does reduce extra numbering in prompts/messages, which can be useful when you want a cleaner interface.
7) Collapse repeated blank lines: -s
This makes noisy outputs more readable.
somecommandwith_spacing | less -s
8) Start at the first match: -p pattern
I use this when I already know what I’m hunting.
journalctl -u api.service -b | less -p "panic"
9) Follow mode (tail-like): +F
A lot of people reach for tail -f. In less, follow mode is great because you can pause and search without leaving.
less +F /var/log/nginx/access.log
While in follow mode:
- Press
Ctrl+Cto stop following (you stay inless) - Search with
/patternand navigate matches
That “pause and inspect” ability is the main reason I like less +F during live debugging.
10) Keep your terminal output visible after quitting: -X
By default, less may use terminal init/deinit behavior that clears or restores the screen when you quit. -X (also known as “no init”) prevents that.
less -X /var/log/syslog
I like -X during debugging because I’ll often quit and immediately run another command, and I want the evidence to remain visible in my scrollback.
11) Status column for orientation: -J
This shows a small status column on the left edge.
less -J -N /var/log/syslog
It’s not mandatory, but on some terminals it makes navigation feel less “floaty,” especially when jumping between matches.
12) Mouse support (when you want it): --mouse
If you’re in a terminal that plays nicely with it, --mouse can enable scroll wheel movement.
less –mouse -R -S somefile.log
I don’t rely on mouse mode, but it’s handy when you’re demoing something to someone who isn’t keyboard-native.
Patterns I use for logs: filtering outside, reading inside
less is not a filter. I treat it as the reader at the end of a pipeline, and I filter upstream with tools designed for selection.
A common workflow:
1) Narrow the universe (time range, unit, container)
2) Filter to what matters (rg, awk, jq)
3) Read comfortably (less)
Here are concrete recipes.
Read recent logs for a service, then search interactively
journalctl -u api.service –since "2 hours ago" | less -N
Inside less, I’ll search for:
/error/timeout/traceback/panic
Pre-filter with ripgrep, then page through
If I already know the keyword set, I filter first to reduce noise.
journalctl -u api.service -b
panic
less -N
This is fast, and it keeps my interactive searches focused.
JSON logs: format with jq, keep color, don’t wrap
A lot of platforms emit JSON logs. Raw JSON is painful to read, so I format it before paging.
cat /var/log/myapp.jsonl
less -R -S
Notes:
jq -Cforces color output, which looks good when paired withless -R.-Sprevents awkward wrapping that destroys indentation.
Stack traces: start at the first exception
cat /var/log/myapp/error.log | less -p "Exception" -N
This is one of those tiny quality-of-life changes that saves real time.
Config files: show line numbers and search for directives
sudo less -N /etc/ssh/sshd_config
Then:
/PermitRootLogin
I like less here because it’s read-only by default, which reduces the risk of accidental edits on sensitive files.
Filtering inside less with &pattern
When I’m teaching less, this is the feature that surprises people: you can filter the view without leaving less.
Inside less:
- Type
&patternto display only matching lines
For example, say you open a noisy service log:
journalctl -u api.service -b | less -N
Then inside less you can do:
&ERROR
panic
Now you’re effectively reading a “compressed” view of the same content.
Why I like this:
- It’s interactive, so I can experiment with a filter quickly.
- It doesn’t require me to rebuild a pipeline when I’m already deep in a file.
Two important caveats (the foot-guns):
1) Filtering changes what you see, so it’s easy to forget you’re no longer looking at the full log.
My habit: whenever I apply &pattern, I later clear it (or at least remind myself) before making conclusions. I treat filtering as a temporary lens, not the source of truth.
2) Filtering in less is display-level filtering, not a structured query.
If you need to select based on JSON fields, time ranges, or multiple conditions, it’s still usually better to filter upstream (jq, awk, rg) and then page.
Marks, jump history, and “bookmarking” an investigation
When I’m working through a log, I often find something interesting, jump elsewhere to compare, then want to return to the exact spot. less has a clean mental model for this: marks.
Inside less:
mmarks the current top line with a letter‘jumps back to that mark‘‘jumps to the previous position (my “back button”)
Example workflow:
1) I find an error that looks important.
2) I mark it with ma.
3) I jump to the end with G to see whether the error continues.
4) I hit ’a to return precisely to the original error.
This is especially powerful with “cause vs symptom” logs: I’ll mark the symptom, then search backward for an earlier cause, then return to compare timestamps and sequences.
If you want marks to survive across invocations, less supports that too:
- Use
--save-marksso your marks can persist
I don’t always enable it globally, but it’s a nice trick when you’re repeatedly opening the same rotating logs across sessions.
Multiple files with less: rotated logs without losing context
A very practical thing less does: it can page through multiple files as one “session.” This is perfect for logrotate output.
Example:
less -N /var/log/nginx/access.log /var/log/nginx/access.log.1
Or with globs:
less -N /var/log/nginx/access.log*
Inside less you can move between files:
:nnext file:pprevious file:eexamine/open a new file:ddelete the current file from the list
My favorite real-world use: incident timeline reconstruction.
- File
access.loghas the latest requests. - File
access.log.1has the earlier ones.
I’ll search for a request ID or user agent, then use :p and :n to follow it across rotations without rebuilding pipelines.
If you’re reading a set of files and want searches to “span” across them, there are keys for that too (they differ from plain n/N). The broad idea is: less can keep searching across files, not just within one.
Working with compressed logs (and why LESSOPEN matters)
In production, logs are often compressed. You’ll see things like:
/var/log/syslog.1/var/log/syslog.2.gz/var/log/nginx/access.log.1.gz
There are three common ways I handle this.
1) Use the “z*” helpers (zless, zcat | less)
If your distro provides it, zless is straightforward:
zless /var/log/nginx/access.log.1.gz
Or, explicitly:
zcat /var/log/nginx/access.log.1.gz | less
This is reliable and easy to understand.
2) Let less preprocess files automatically
Many environments configure less with a preprocessor via the LESSOPEN environment variable (often provided by something like “lesspipe”). That allows less to transparently view compressed files, and sometimes other formats.
This is convenient—but I keep one security-oriented habit: on shared or locked-down machines, I want to know whether LESSOPEN is doing something unexpected.
- If I want to ignore preprocessors for a specific read, I use
-L(“no lessopen”):
less -L /path/to/suspicious-or-weird-file
3) Decompress once, then page as a regular file (for performance)
For huge compressed logs, streaming decompression is convenient but not always fast. If I need to jump around a lot, I’ll sometimes decompress to a temp location and then use less on the resulting file (so less can seek freely).
This is situational, but it can matter when you’re paging multi-gigabyte rotated logs and you need consistent responsiveness.
Follow mode in the real world: less +F as a smarter tail -f
I like tail -f for one thing: “show me the newest lines.” But less +F gives me that plus the ability to pause, search, and navigate without losing the stream.
A very typical workflow for me:
less +F /var/log/nginx/access.log
- I watch requests come in.
- Something spikes.
- I press
Ctrl+C(stop following, stay inless). - I search for
/ 500or a path:
/ 500
- I use
nto jump between failures. - When I’m ready to go live again, I press
Fto resume following.
Two follow-mode options that matter when you’re reading pipelines (not files):
--exit-follow-on-close: in follow mode on a pipe, exit when the writer closes the pipe.
That’s useful in CI or one-shot commands where you don’t want less to hang around after the command finishes.
There’s also an interactive variant:
ESC-F: follow likeF, but stop when the search pattern is found.
I use that as a “wait until it breaks” mode. Example idea (conceptually): follow logs until the next panic shows up, then stop so I can inspect around it.
Performance and memory: what matters when files get huge
Most of the time, less is “fast enough” and you don’t need to think about internals. But when you’re dealing with gigantic logs, it helps to know a few practical constraints.
Files vs pipes
- Files:
lesscan seek and jump efficiently. - Pipes:
lessreads sequentially and may buffer data to allow backward scrolling.
If I’m paging something that I know I’ll need to search backward in repeatedly, I try to get it into a file first (even temporarily). That’s not always possible, but it’s the mental model.
Backscroll limits and huge streams
If you page an endless stream (for example, a long-running journalctl -f style stream piped into less), the buffer can grow. less has settings related to backward scroll limits (--max-back-scroll / -h) and buffering (--buffers / -b). I rarely tune these in day-to-day work, but it’s good to remember the knob exists if you’re on a constrained host.
Line numbers have a cost
-N is worth it most of the time, but it’s not free. On extremely large files, adding line numbers can make some navigation feel heavier because less has to keep track of line offsets.
My rule:
- For “I’m hunting a handful of errors”:
-Nis great. - For “I’m just scanning huge records and line numbers don’t matter”: I’ll sometimes skip
-Nand rely on search + context.
Long lines: chop vs wrap
For machine logs, I treat -S as default. Wrapped JSON is not “more readable,” it’s just more confusing. If I need readability for text files, I can toggle -S off inside less.
Safer color and untrusted output: why I default to -R
This sounds paranoid until it saves you once.
Terminals interpret certain control sequences. When you view output from untrusted sources (or messy programs) you can end up with more than just “colored text.”
That’s why I strongly prefer:
less -Rfor most “normal colored output”
…and I avoid:
less -runless I have a reason and I trust the output
-R is the “render common ANSI color sequences” choice without being as permissive as -r.
Another safety note: inside less you can execute shell commands with !. That’s a feature, and it can be handy, but it’s also something to be aware of when you’re on shared systems or when you’re trying to keep a clean audit trail of exactly what commands you ran.
Making less pleasant by default (aliases, $LESS, and keybindings)
If you only use less in one-off commands, you’ll keep re-learning the same preferences. I prefer setting sane defaults so less behaves the way I want everywhere.
Set a default $LESS
You can set defaults in your shell config (for example ~/.bashrc or ~/.zshrc). My baseline is:
export LESS=‘-R -F -X -i -S‘
What these do together:
-R: render common color sequences-F: don’t open pager for short output-X: don’t clear the screen on exit (useful when you want to keep the output visible after quitting)-i: case-insensitive search unless you type uppercase-S: avoid line wrap
You may or may not want -X. Some people prefer the “clean exit” behavior. I like keeping context on screen during debugging.
Pick a pager globally with $PAGER
Many tools respect $PAGER.
export PAGER=less
If you work with tools that ship with their own paging UI, they often still defer to this.
Control history (useful on shared machines)
Search history can be convenient, but it can also leak sensitive terms on shared environments.
- To disable history for the session:
export LESSHISTFILE=-
- Or set it to a private location:
export LESSHISTFILE="$HOME/.cache/lesshst"
Keybindings with lesskey
If you consistently want a custom keybinding (for example, mapping a key to toggle line wrapping), lesskey is the official path.
A minimal workflow:
1) Create a lesskey source file, such as ~/.config/lesskey.
2) Compile it:
lesskey ~/.config/lesskey
What you put in that file depends on your preferences, but the main point is: if you keep repeating a manual action inside less, make it a key.
Practical incident playbooks (the “I just need answers” section)
These are the repeatable patterns I actually use when something is broken.
Playbook 1: systemd service flapping (restart loop)
Goal: confirm it’s restarting, find the first failure, and extract the repeated error.
journalctl -u api.service -b –no-pager | less -N
Inside less:
Gto jump to the end/Start request repeated too quickly(common symptom)?errorto search backward for the earlier causemato mark the first obvious failure‘‘to bounce between positions as I compare timestamps
If it’s too noisy, I’ll use display filtering:
&ERROR
panicOOM
Then I clear it later so I don’t forget I filtered.
Playbook 2: Kubernetes CrashLoopBackOff (logs are long, pods restart)
Goal: find the first exception and the context around it.
kubectl logs deploy/api –since=6h
panicTraceback"
Why those flags together:
-Skeeps stack traces readable-Rkeeps color if the CLI adds it-Nmakes it easier to say “line ~1200” in a Slack message-pdrops me onto the first failure immediately
Inside less:
nto jump between exceptions?searches backward for “starting server” / “config loaded” messagesmato mark the first crash, then compare with later crashes
Playbook 3: Nginx access logs (needle in a haystack)
Goal: track a single request path or IP and understand response codes.
less -N /var/log/nginx/access.log
Inside less:
/"GET /checkout"(or whatever path matters)nto hop between requests& 500to temporarily focus on failures
If logs are rotated:
less -N /var/log/nginx/access.log /var/log/nginx/access.log.1
Then :p / :n to move between files.
Playbook 4: CI logs (huge output, you need the first error)
Goal: jump to the first real failure, not the 1,000 lines of setup.
If you can capture logs to a file:
less -N -p "FAILED
panicTraceback" build.log
If you’re stuck with streaming output, I’ll still do:
somebuildcommand 2>&1 | less -R
Then I search for the first error markers. In follow-ish scenarios, I’ll use F inside less to keep watching without losing my place.
Common mistakes (and the habits that prevent them)
I’ve seen the same misunderstandings repeatedly—especially when people are under time pressure.
1) Assuming the pager shows “everything” when upstream is truncating
Some commands truncate output by default. If you pipe truncated output to less, you’ll get a perfectly paged version of incomplete data.
Habit: verify with the command’s flags first (time ranges, limits, tail/head behavior), then page.
2) Forgetting that line wrapping can destroy meaning
Wrapped lines can make JSON and stack traces unreadable, and can even make it harder to visually spot where one record ends.
Habit: use less -S for logs and machine-formatted output.
3) Losing color or seeing escape-code garbage
If you pipe colored output into less without -R, you’ll often see raw escape sequences.
Habit: default to LESS=‘-R ...‘ or explicitly | less -R when you know there’s color.
4) Using cat by reflex when you don’t need it
cat file | less works, but less file is simpler and can be slightly nicer.
Habit: use less filename for files, pipelines only when you truly have a stream.
5) Picking more out of habit
more is historically common, but it’s more limited. The big practical difference: less scrolls backward.
Habit: if you’re reading anything larger than a few lines, use less.
6) Forgetting you applied an in-less filter
&pattern is powerful, but it can trick you into thinking “the log has only these lines.” It doesn’t—it’s just your view.
Habit: when you’re done filtering, clear the filter and re-check surrounding context before you write conclusions.
When I don’t use less (and what I use instead)
less is a reader, not a structured query tool. There are times where it’s the wrong tool.
- When I need to search across many files: I use
rgfirst, thenlessfor the matching file.
rg -n "TLS handshake" /var/log/nginx
- When output is JSON and I need field-level filtering: I use
jq(oryqfor YAML), then page.
kubectl get pods -A -o json
{name: .metadata.name, ns: .metadata.namespace}‘less -R -S
- When I want a code-like viewer with syntax highlighting: I often use
bat(if installed). It’s still conceptually a pager, but purpose-built for code readability.
- When I’m doing heavy editing: I open an editor.
lessis for reading.
- When I need an interactive log UI: I’ll consider tools like
lnavfor log formats, or platform-specific viewers.
Traditional vs modern “read output” approaches
Here’s how I choose quickly:
Traditional choice
—
less
less -R -S with $LESS defaults less
bat (if available) or less -N Raw less
jq -C . less -R -S
tail -f
less +F (pause with Ctrl+C) Manual skim
less That last row is worth expanding: in 2026, AI assistants can summarize logs quickly, extract suspected root causes, and propose next queries. I still treat the raw log stream as the source of truth. My flow is often “AI summarizes → I verify the claim in less with searches and surrounding context.” It keeps me fast without turning debugging into guesswork.
Expansion Strategy (how I keep leveling up my less muscle memory)
This is the approach I use to turn random flags into habits that stick.
- Deeper code examples: Every time I learn a flag, I attach it to a command I actually run (like
journalctl,kubectl,git diff). If it doesn’t attach to real work, I forget it. - Edge cases: I test the trick on both a regular file and a pipeline. If it behaves differently, I write down the difference (files seek; pipes stream).
- Practical scenarios: I keep 3–4 copy/paste “playbook commands” in a personal notes file so I’m not reinventing them during incidents.
- Performance considerations: If paging a compressed log feels slow, I try a decompressed temp file and see if it changes how quickly I can jump and search.
- Common pitfalls: I build a small checklist of “am I seeing the full data?” (is upstream truncated? did I filter inside
less? am I looking at the correct time window?). - Alternative approaches: If I’m doing the same pipeline repeatedly, I convert it into an alias or shell function so I can focus on reading, not command composition.
If Relevant to Topic (modern workflows I actually use)
A few things that feel “2026 normal” and pair well with less:
- Containers:
docker logs --since 1h | less -Sis my default when I want to read a chunk rather than tail forever. - Kubernetes: for wide outputs and long event messages,
less -Sprevents the “every record becomes 12 lines” problem. - Journald:
journalctlis already time-aware, so I narrow by time/unit there, then uselessfor navigation and search. - Color-heavy CLIs: I treat
-Ras table stakes. - AI-assisted debugging: I use AI to propose hypotheses and keywords, then I confirm in
less(search + context) before I trust it.
Where I land: a practical less checklist you can keep
When I’m on a new machine, I get less into a good state first, because it pays back every day. I set $PAGER=less, I set a sane $LESS default (usually -R -F -X -i -S), and I practice the three moves that matter: page (Space/b), jump (g/G), and search (/ then n).
If you want a concrete next step, do this the next time you’re staring at a firehose of output:
1) Pipe it to less immediately so you can think.
2) Add -S when lines are long (JSON, stack traces, URLs).
3) Add -R when there’s color.
4) Use -p when you already know your first target term.
5) For live logs, use less +F, pause with Ctrl+C, and search without losing your place.
That’s the difference between “reading logs” and “debugging with logs.” Once less is in your hands as a navigation tool—not just a way to stop scrolling—you’ll feel the same calm you get from a good debugger: predictable movement, fast search, and a quick exit when you’ve learned what you needed.


