atq Command in Linux: Complete Guide to Viewing Scheduled Job Queue and Parameters

atq command in Linux and it perimeters

Once you’ve scheduled a handful of one-time jobs with at, you need a way to see what’s actually still pending — that’s the entire job of atq. It’s a small command, but it’s the one that stops “did that job actually get scheduled?” from being a mystery.

What atq Actually Is

atq lists the jobs currently waiting in the at queue for the invoking user (or, for root, every user’s jobs). It’s part of the same at package as at, atrm, and the atd daemon, and it’s really just a formatted read of the job spool directory plus the daemon’s internal queue state. In fact, atq is functionally identical to running at -l — they’re two names for the same operation.

Basic Syntax

atq [options] [job_id ...]

Run with no arguments, it lists all pending jobs for the current user.

A Basic Example

atq
3    Fri Jul 31 22:00:00 2026 a john
4    Sat Aug  1 09:00:00 2026 a john
7    Sun Aug  2 03:30:00 2026 c john

The output columns are:

  1. Job number — the unique ID assigned when the job was created with at (used later with atrm or at -c).
  2. Scheduled date and time — when atd will actually execute the job.
  3. Queue letter — a is the default queue; b is reserved for batch; other letters (c through z, and uppercase A–Z) represent user-defined priority queues, with later letters running at lower priority (higher nice value).
  4. Owning username — whose job this is.

Options

-v          show completed but not-yet-deleted jobs as well
-q queue    restrict listing to a specific queue letter
-V          print version information

Filtering by Queue

atq -q c

Shows only jobs scheduled in queue c, useful if you deliberately separate routine jobs from higher-priority ones.

Showing Completed Jobs

atq -v

On some implementations, jobs that have finished executing but haven’t yet been cleaned up from the spool are shown with this flag, along with their completion status — handy for a quick “did it actually run” sanity check right after the scheduled time passes.

As Root: Seeing Everyone’s Jobs

A regular user only ever sees their own pending jobs. Root sees the queue for every user on the system:

sudo atq
3    Fri Jul 31 22:00:00 2026 a john
5    Fri Jul 31 23:15:00 2026 a maria
6    Sat Aug  1 01:00:00 2026 a backup-svc

This is genuinely useful during incident response or audits — “what’s actually scheduled to run on this box tonight, by anyone” is a question atq answers instantly as root, whereas hunting through crontabs for the same information takes considerably longer.

Combining atq with Other Commands

Inspecting the actual command a queued job will run:

atq
# note job number, e.g. 3
at -c 3

at -c dumps the full captured environment and shell commands for that job — pairing it with atq gives you both “what’s scheduled” and “what will it actually do” in two quick steps.

Counting pending jobs (useful in monitoring scripts):

PENDING=$(atq | wc -l)
if [ "$PENDING" -gt 20 ]; then
    echo "Warning: unusually large at queue ($PENDING jobs)" | mail -s "at queue alert" admin@example.com
fi

Clearing every pending job for the current user:

atq | awk '{print $1}' | xargs -r atrm

Checking for a specific script before scheduling a duplicate:

if at -c $(atq | awk '{print $1}') 2>/dev/null | grep -q "nightly_report.sh"; then
    echo "nightly_report.sh already scheduled, skipping duplicate."
else
    echo "/usr/local/bin/nightly_report.sh" | at 23:00
fi

Where the Data Actually Comes From

atq doesn’t maintain its own separate database — it reads the same spool directory that at writes to and atd monitors, typically:

/var/spool/cron/atjobs/

Each file in that directory represents one queued job, and its filename encodes the job number, queue letter, and scheduled execution time, which is exactly the information atq parses and formats into its human-readable table.

Real-World System Administration Use Cases

Pre-deployment sanity check — before kicking off a deployment pipeline that itself uses at to schedule follow-up verification steps, check nothing conflicting is already queued:

echo "Currently scheduled at-jobs for this host:"
atq

Monitoring/alerting integration — a Nagios/Zabbix-style check script that flags if a critical recurring one-off (e.g., a certificate renewal job scheduled nightly via a wrapper) has silently disappeared from the queue:

#!/bin/bash
if ! atq | grep -q "cert_renew"; then
    echo "CRITICAL: cert_renew at-job missing from queue"
    exit 2
fi
echo "OK: cert_renew job present"
exit 0

(Note: since atq output doesn’t include the command text itself, this pattern usually needs to be paired with at -c on each job number, or with a consistent naming/queue convention, to actually match against a known job.)

Daily operational report:

#!/bin/bash
# report_at_queue.sh
{
  echo "=== at queue as of $(date) ==="
  atq
  echo
  echo "Total pending jobs: $(atq | wc -l)"
} > /var/log/at_queue_report.log

Troubleshooting

atq shows nothing, but you know you scheduled a job — you may be looking at the wrong user’s queue; only root sees everyone’s jobs, so double-check you scheduled it as the same user you’re now querying as.

Job appears in atq but never executes — check the atd daemon is actually running: systemctl status atd. If it’s stopped, jobs will sit in the queue indefinitely without executing, and atq will happily keep listing them as still pending.

“atq: command not found” — the at package isn’t installed; install via apt install at or dnf install at.

Time shown looks wrong / in the wrong timezone — atq displays times using the system’s configured timezone (timedatectl to check/set), so a mismatch usually means the server’s timezone configuration, not atq itself, needs fixing.

Security and Access Considerations

atq respects the same /etc/at.allow / /etc/at.deny access control as at and atrm — if a user isn’t permitted to use at, they generally can’t query the queue either. As with cron, it’s worth periodically auditing (as root) what’s actually queued across all users on shared or multi-tenant systems, since a forgotten or malicious one-time job is just as capable of causing damage as a persistent cron entry, and is easy to overlook precisely because it’s not sitting visibly in a crontab file.

Comparison to Related Commands

  • at -l — functionally identical to plain atq; both list the pending queue.
  • atrm — the natural pairing partner; you list with atq, then remove specific jobs by ID with atrm.
  • crontab -l — the cron equivalent for viewing recurring schedules, as opposed to atq‘s one-time job queue.
  • systemctl list-timers — the systemd-native equivalent for viewing scheduled timer units, showing both recurring and one-shot transient timers with next-run times.

atq‘s output format and behavior are effectively identical across Debian, Ubuntu, RHEL, CentOS, Fedora, and SUSE, since they all ship the same upstream at package implementation. The only common variance is whether the at package is installed by default (frequently it isn’t on minimal server images).

Summary

atq is a small, single-purpose command, but it’s the visibility layer that makes the whole at job-scheduling system trustworthy — without it, you’d be scheduling one-time jobs into a black box. Pair it with at -c to inspect job contents and atrm to clean up, and you have a complete, lightweight toolkit for one-time task scheduling and auditing.

References

  • man atq, man at, man atd on your local system
  • GNU/Linux at package documentation
  • Debian Administrator’s Handbook, “Task Scheduling: cron and atd”

Total
0
Shares

Leave a Reply

Previous Post
at command in Linux and it perimeters

at Command in Linux: Complete Guide to Scheduling One-Time Tasks and Parameters

Next Post
atrm command in Linux and it perimeters

atrm Command in Linux: Complete Guide to Removing Scheduled Jobs and Parameters

Related Posts