tail — Monitor and Extract the End of Files
Overview
tail prints the end of a file—by default the last 10 lines. It’s a first-choice command for log debugging because errors usually appear at the bottom of logs and because tail can keep watching a file as it grows.
- Core Function: Output the last part of files (lines or bytes).
- Primary Benefit: Fast log triage + real-time monitoring.
- Where to Use:
/var/log/nginx/error.log,/var/log/syslog, PHP-FPM logs, WordPress plugin/theme logs. - Workflow:
tail [OPTION]... [FILE]...(optionally-f/-Ffor live follow).
System Check
which tail # Expected: /usr/bin/tail
tail --version # Expected: GNU coreutils version output
Many logs rotate (e.g., error.log → error.log.1 and a new error.log is created). Use -F when you expect rotation.
Core Syntax
tail [OPTION]... [FILE]...
If FILE is omitted, tail reads from stdin, which is useful in pipelines.
Two important “starting point” forms
- Last N lines (default):
tail -n 10 file - Start from line N:
tail -n +N file(starts at line N and prints to end)
Options & Flags
| Option | What it does | When you’d use it | Example |
|---|---|---|---|
| :- | :-- | :-- | :-- |
| (none) | Last 10 lines | Quick glance | tail file.log |
-n N | Last N lines | Increase/decrease output | tail -n 50 error.log |
-n +N | Start at line N to end | Skip headers / resume reading | tail -n +200 file.txt |
-f | Follow appended data | Live debugging | tail -f error.log |
-F | Follow by name + retry | Survive log rotation | tail -F error.log |
--retry | Keep trying if file missing | Service logs that appear later | tail -f --retry file.log |
--pid=PID | Stop when process dies | Tie follow to a process | tail -f --pid=1234 error.log |
-c N | Last N bytes | Binary-ish / byte-level checks | tail -c 200 file |
-q | Quiet (no headers) | Multiple files output cleanly | tail -q a.log b.log |
-v | Always print headers | Multiple files clarity | tail -v a.log b.log |
--help | Help | Reference | tail --help |
If you follow a very noisy log with tail -f, it can scroll fast and be hard to read. Consider filtering with grep, or use a pager for static views.
Common Patterns
- Fast Triage
- Live Follow (Debugging)
- Follow + Filter
- Multiple Files
- WordPress VPS Use
tail /var/log/nginx/error.log
tail -n 50 /var/log/nginx/error.log
tail -n 200 /var/log/syslog
tail -f /var/log/nginx/error.log
tail -F /var/log/nginx/error.log
tail -F /var/log/php8.2-fpm.log
tail -F /var/log/nginx/error.log | grep -i "error"
tail -F /var/log/nginx/error.log | grep -E "php|upstream|timeout"
tail -n 200 /var/log/nginx/error.log | grep -i "permission"
tail -n 30 /var/log/nginx/access.log /var/log/nginx/error.log
tail -v -n 20 /var/log/nginx/access.log /var/log/nginx/error.log
tail -n 80 /var/www/html/wp-content/debug.log
tail -F /var/www/html/wp-content/debug.log
tail -F /var/log/nginx/error.log | grep -i "wp-admin"
Best Practices
-
Prefer
-Ffor long-running monitoring on production servers (handles rotation):tail -F /var/log/nginx/error.log -
Start with
tail -n 50or-n 200to get context before going live. -
Combine with filters for signal:
tail -F /var/log/nginx/error.log | grep -i "timeout" -
When investigating a specific incident time window, consider pairing with
grepfirst:grep -n "2026-02-17" /var/log/nginx/error.log | tail -n 50 -
For scripts, avoid follow mode unless you manage lifecycle (timeouts /
--pid):tail -f --pid=1234 /var/log/nginx/error.log
-f vs -F — what’s the difference?
tail -f file: follows the current file descriptor. If the file is rotated and replaced, you may keep following the old file.tail -F file: follows the filename and will reopen it if it’s rotated/recreated. This is typically better for server logs.
Troubleshooting
| Problem | Likely Cause | Fix |
|---|---|---|
| :-- | :-- | :-- |
No new lines appear in -f | Service isn’t writing or log path is wrong | Confirm path; check service status; try ls -l and permissions |
| Follow stops after rotation | You used -f | Use -F for rotated logs |
| Permission denied | Log restricted to root | Use sudo tail ... |
| Output too noisy | High traffic or verbose logs | Filter with grep or increase specificity |
| Lines are truncated/weird | Non-text/binary content | Use -c to inspect bytes or view with safer tools |
WordPress configs and logs may contain secrets (DB host, usernames, tokens). Avoid copying raw output into tickets/chats without redaction.
Cheat Sheet
tail file.log # Last 10 lines
tail -n 50 file.log # Last 50 lines
tail -n +200 file.log # From line 200 to end
tail -f file.log # Follow new lines (may break on rotation)
tail -F file.log # Follow by name (handles rotation)
tail -c 200 file # Last 200 bytes
tail -v -n 20 a.log b.log # Show headers for multiple files
tail -q -n 20 a.log b.log # Quiet headers for multiple files
tail -F file.log | grep error # Follow + filter
Mini Quiz
- What does
tailshow by default? - What’s the difference between
tail -fandtail -F? - How do you show the last 200 lines of a file?
- How do you start printing from line 500 to the end?
- How would you follow Nginx errors and only show “timeout” lines?
Show answers
- The last 10 lines of a file.
-ffollows the current file;-Ffollows the filename and reopens after rotation.tail -n 200 filetail -n +500 filetail -F /var/log/nginx/error.log | grep -i "timeout"
Worked Examples
Log content varies by server. Outputs below are representative examples.
1) View the last 10 lines of Nginx error log
tail /var/log/nginx/error.log
Expected output (sample):
2026/02/17 10:20:11 [error] 1234#1234: *991 connect() failed (111: Connection refused) while connecting to upstream
2026/02/17 10:21:03 [warn] 1234#1234: *1001 upstream response is buffered to a temporary file
...
Use case: Quick glance at the latest errors.
2) Get more context (last 50 lines)
tail -n 50 /var/log/nginx/error.log
Expected output: (last 50 lines printed) Use case: Understand what led up to the latest error.
3) Follow Nginx error log live
tail -f /var/log/nginx/error.log
Expected output: (prints new lines as they appear) Use case: Live debugging while reproducing an issue in browser.
4) Follow Nginx error log and survive rotation
tail -F /var/log/nginx/error.log
Expected output: (continues following even after log rotation) Use case: Long-running monitoring sessions.
5) Follow and filter only error lines (case-insensitive)
tail -F /var/log/nginx/error.log | grep -i "error"
Expected output (sample):
2026/02/17 10:20:11 [error] 1234#1234: *991 connect() failed (111: Connection refused) while connecting to upstream
Use case: Reduce noise while monitoring.
6) Watch WordPress debug log (if enabled)
tail -n 80 /var/www/html/wp-content/debug.log
Expected output (sample):
[17-Feb-2026 10:33:09 UTC] PHP Warning: Undefined array key "foo" in /var/www/html/wp-content/plugins/example/plugin.php on line 88
[17-Feb-2026 10:34:01 UTC] PHP Fatal error: Uncaught Error: Call to undefined function ...
Use case: Plugin/theme debugging.
7) Follow WordPress debug log live
tail -F /var/www/html/wp-content/debug.log
Expected output: (prints new PHP notices/warnings as they occur) Use case: Reproduce issues and see immediate log output.
8) Show the last 200 lines of syslog
tail -n 200 /var/log/syslog
Expected output: (last 200 syslog lines) Use case: System-level context during incidents.
9) Start from a specific line number
tail -n +500 /var/log/nginx/access.log
Expected output: (prints from line 500 to end) Use case: Resume reading from a known checkpoint.
10) Compare last lines of two logs with headers
tail -v -n 10 /var/log/nginx/access.log /var/log/nginx/error.log
Expected output (sample):
==> /var/log/nginx/access.log <==
192.168.0.10 - - [17/Feb/2026:10:40:01 +0000] "GET / HTTP/1.1" 200 512 "-" "Mozilla/5.0"
==> /var/log/nginx/error.log <==
2026/02/17 10:40:02 [warn] 1234#1234: *1201 upstream response is buffered to a temporary file
Use case: Correlate traffic with errors.
11) Get the last 200 bytes (byte-level view)
tail -c 200 /var/www/html/wp-config.php
Expected output: (last 200 bytes of the file) Use case: Quick check for suspicious appended content.
12) Follow and stop when a process exits (--pid)
tail -f --pid=1234 /var/log/nginx/error.log
Expected output: (follows until PID 1234 exits) Use case: Tied debugging to a short-lived process.
13) Follow a log that may not exist yet (--retry)
tail -f --retry /var/log/myapp/app.log
Expected output: (keeps trying until file appears, then follows) Use case: Services that create logs after startup.
14) Follow and filter for timeouts (common VPS issue)
tail -F /var/log/nginx/error.log | grep -i "timeout"
Expected output (sample):
2026/02/17 11:02:44 [error] 1234#1234: *1401 upstream timed out (110: Connection timed out) while reading response header from upstream
Use case: Detect upstream/PHP-FPM timeout symptoms.
15) Follow PHP-FPM log live (path may vary)
tail -F /var/log/php8.2-fpm.log
Expected output: (new PHP-FPM notices/warnings) Use case: Investigate slow requests, worker issues, pool errors.