A few years back I let a domain lapse. Not a throwaway one either. It was live, had traffic, and I just forgot the renewal date sitting in some registrar account I hadn't logged into in months. By the time I noticed, it was in redemption and cost me a small fortune to get back.
The annoying part is that it was completely avoidable. I owned maybe fifteen domains at the time, spread across three registrars, and I had no single place that told me what was expiring and when. So I wrote a script.
The manual way is painful
You can check one domain with whois:
whois example.com | grep -i "expiry"
That works for one domain. It does not scale to a list. And logging into each registrar to eyeball dates is exactly the habit that let one slip in the first place.
The script
Put every domain you own in a file, one per line:
example.com
mysite.net
sideproject.io
Then run this against it:
#!/usr/bin/env bash
# usage: ./check-expiry.sh domains.txt
while read -r domain; do
[ -z "$domain" ] && continue
expiry=$(whois "$domain" 2>/dev/null \
| grep -iE 'Registry Expiry Date|Expiration Date|paid-till|renewal date' \
| head -n 1 \
| sed -E 's/.*: *//')
printf '%-30s %s\n' "$domain" "${expiry:-not found}"
sleep 2
done < "$1"
You get a clean list back:
example.com 2026-11-04T09:00:00Z
mysite.net 2027-01-22T00:00:00Z
sideproject.io not found
The sleep 2 matters. Most whois servers rate limit you, and if you hammer them with a big list they will start refusing to answer. Two seconds between lookups keeps you under the radar.
Put it on a schedule
Once it works, there is no reason to run it by hand. Drop it in cron and have it email you the output once a week:
0 9 * * 1 /home/you/check-expiry.sh /home/you/domains.txt | mail -s "Domain expiry check" you@example.com
Now every Monday morning you get a list. Anything close to expiry, you go renew.
Where this falls over
This is good enough for a handful of domains, but it has real limits.
Whois output is not standardised. Different TLDs use different field names for the expiry date, so the grep misses some and you get "not found" even when the domain is fine. Country-code TLDs are the worst for this.
It also tells you nothing about DNS health, whether your records still resolve, or whether a domain got hijacked or misconfigured. It only reads the expiry field, and only when the format cooperates.
Once you get past twenty or thirty domains across several registrars, the script becomes its own small maintenance job. That is roughly the point where I stopped patching it and built Domainium, which pulls every domain across every registrar into one dashboard and handles the expiry parsing and alerts properly. Free to start if you want to skip the cron job.
But if you own a few domains and just want to stop forgetting them, the script above will do the job. Copy it, point it at your list, and never lose a domain to a missed renewal again.
Top comments (0)