Overcoming hardware limitations: the time-to-sleep script
As some of you might own, I’m still rocking a ThinkPad T430, a laptop model originally released in 2012. It’s not the fastest laptop out there, but it is plenty fast for a number of tasks, even most software development work.
I also try to keep my machines up to date and properly backed up. On my laptop,
this means having around a couple of scheduled tasks, such as restic
backups.
They don’t really take up a lot of time, but if an intensive scheduled task
starts while you’re having a video call over Google Meet while also sharing
the screen, things can get a bit slow, ruining the experience.
After a couple of these instances, I started thinking about finding a solution.
Scheduled tasks
Here’s a quick rundown of regular tasks that I like to run on my laptop.
Backups using restic
: hourly backups to my home server. The file scanning
process of the backup is quite intense, eating up a lot of my CPU time.
System updates using dnf
and flatpak
: usually run daily, because I’m too
lazy to install the updates using a GUI, and at the same time I cannot afford
to run out of date software.
Backups of critical files from my server to my laptop: there are some files I just cannot afford to lose. For this reason, I make a daily backup of the files to my laptop.
Filesystem maintenance: I don’t trust my storage devices (and neither should
you), which is why I run a weekly scrub on my SSD that’s running the btrfs
filesystem. If there are errors detected, I will know as soon as possible.
These tasks can be quite intensive, especially on hardware that’s a bit older.
With some tasks, such as system updates, you may also run into random issues. Updating Mozilla Firefox while it’s actively running results in the browser requiring a restart immediately after opening a new tab. This is very annoying and inconvenient when you’re in the middle of your work.
The “time-to-sleep” script
To avoid intensive scheduled tasks running while I’m doing actual work, I tried
rescheduling these tasks to a more quiet time. All I needed to do was to edit
the systemd
timers so that the jobs start after midnight and leave the laptop
running.
This solution has quite an obvious downside: my laptop will be powered on pretty much 24/7, and since electricity is super expensive and laptop maintenance a bit of a pain, I’d be wasting resources, time and eventually money.
I could make the last scheduled task make the machine shut down, but what if I have a long-running file copy operation running? It would be interrupted, unless I specifically disabled the scheduled task.
Then it clicked for me.
I know when I’m planning on going to sleep. Sleeping also has a regular cycle as it happens daily. Why not just put all the scheduled daily tasks into one script that I can run whenever I intend to shut down my laptop?
And thus, the time-to-sleep
script was born. It’s a simple Bash script that
lives in /root/.local/bin/time-to-sleep
. To make sure I can also reasonably
observe the behaviour of the script, I’ve implemented it as a simple systemd
service that lives in /etc/systemd/system/time-to-sleep.service
. It’s
disabled by default, but can be started manually.
[Unit]
Description=Run maintenance tasks
[Service]
ExecStart=/root/.local/bin/time-to-sleep
I have an alias in ~/.bashrc
that I use to start the service.
alias time-to-sleep="sudo systemctl start time-to-sleep.service"
Whenever the time comes to go to sleep, or when I’m just going to do something
else and can leave the laptop running at my desk, I just open a terminal window,
type time-to-sleep
and I’m good to go. If I’m somewhere with a very poor
internet connection or need to conserve battery power, I can opt to not run that
script.
Going with this approach also saves me a lot of trouble on the technical side as well. I don’t need to think of a magical way to automatically detect if I’m working at the moment, or if I’m running on battery, or if I’m behind a limited internet connection. Sometimes your job becomes so much easier if you make some assumptions about when and where the script runs. You’re in control of choosing when to run it, after all.
In case something goes wrong, I can rely on the set -e
line in my script to
fail hard. When I come back to my machine, it will be quite noticeable that
something has gone wrong, as the laptop will still be running. Who needs a
fancy monitoring setup when you have visual evidence of failure?
As for the hourly backups, I solved that problem by only making backups of
more important files. It takes much fewer resources compared to the full /home
folder backup that runs as part of the time-to-sleep
script.
Conclusion
After all this work, I don’t have to worry about any scheduled tasks hogging up all the resources while working. At the same time, I still get all the benefits that the scheduled tasks bring.
Example
In case you need it: here’s an example of the script that I’m running, with all
the personal details scrubbed out. Feel free to use it as inspiration for your
own time-to-sleep
script!
#!/bin/bash
set -e
echo "Restic full home folder backup."
export RESTIC_REPOSITORY='sftp:backupuser@backupserver.lan:/path/to/repo/'
export RESTIC_PASSWORD='someverysecurepasswordgoeshere'
restic unlock
restic backup --verbose --exclude-caches --cleanup-cache \
--iexclude=/home/*/downloads \
--exclude=/home/*/.cache \
--exclude=/home/*/.gradle \
--exclude=/home/*/.local/share/Trash \
/home
restic forget --prune \
--keep-hourly 0 \
--keep-daily 7 \
--keep-monthly 0
echo "Restic full home folder backup done."
echo "Backing up important data from the server."
rsync -az --delete-before \
user@myserver.lan:/path/to/nextcloud/ \
/storage/backups/nextcloud/
chown -R localuser:localuser /storage/backups/nextcloud/
echo "Backing up important data from the server done."
echo "Updating system."
dnf update -y
flatpak update -y && flatpak uninstall --unused -y
echo "Updating system done."
echo "Scrubbing disk."
btrfs scrub start -B /
echo "Scrubbing disk done."
echo "All done! Going to sleep."
shutdown now
Subscribe to new posts via the RSS feed.
Not sure what RSS is, or how to get started? Check this guide!
You can reach me via e-mail or LinkedIn.
If you liked this post, consider sharing it!