Rate Limiting Commands & Usage
TL;DR: Use certbot --dry-run for testing and --staging for development to avoid consuming production rate limits—monitor issuance via Certificate Transparency logs and never use --force-renewal unnecessarily to preserve your 5 certificates per exact set per 7 days quota.
Overview
Certificate automation commands directly impact rate limit consumption, making proper command usage critical for preventing service disruptions. This guide provides practical command patterns for testing, development, production operations, and monitoring that help teams stay within Let's Encrypt's rate constraints. Understanding which commands consume rate limits and which provide safe testing enables reliable certificate management.
Production teams must distinguish between operations that consume rate limits and those that don't. Dry-run commands test configurations without requesting actual certificates, while staging environment requests use separate rate limit buckets with higher thresholds. Monitoring commands help track issuance rates and identify approaching limits before they cause operational issues.
Enterprise deployments benefit from automated monitoring scripts, renewal optimization strategies, and emergency recovery procedures. Implementing proper command patterns prevents common scenarios like exhausting the exact set of identifiers limit during troubleshooting or consuming new orders quota during bulk certificate operations.
Core Rate Limiting Commands
Certificate Management with Certbot
The certbot command is susceptible to rate limiting issues when dealing with Let's Encrypt's certificate issuance limits.
Key Limits to Remember:
- 50 certificates per registered domain per 7 days (refills at 1 per 202 minutes)
- 5 certificates per exact set of identifiers per 7 days (refills at 1 per 34 hours)
- 5 authorization failures per identifier per hour (refills at 1 per 12 minutes)
# Basic certificate request
certbot certonly --webroot -w /var/www/html -d example.com
# Check current certificates
certbot certificates
# Test configuration without requesting certificates (ALWAYS DO THIS FIRST)
certbot --dry-run certonly --webroot -w /var/www/html -d example.com
Common Issue Pattern:
When troubleshooting SSL configurations, repeatedly running certbot to fix issues can quickly consume your exact set of identifiers limit (5 per 7 days). This creates a cascading problem where each failed attempt with the same domain set consumes your quota.
Best Practice Implementation:
#!/bin/bash
# Always test first with dry-run
certbot --dry-run certonly --webroot -w /var/www/html -d example.com
# Only proceed if dry-run succeeds
if [ $? -eq 0 ]; then
echo "Dry run successful, proceeding with actual certificate request"
certbot certonly --webroot -w /var/www/html -d example.com
else
echo "Dry run failed - fix issues before requesting actual certificate"
exit 1
fi
Development and Testing Commands
Staging Environment Setup
Always use Let's Encrypt's staging environment for testing. The staging environment has significantly higher rate limits and is designed for development and troubleshooting.
# Use staging server for testing (RECOMMENDED for all development)
certbot certonly --staging \
--webroot -w /var/www/html \
-d test.example.com \
--email [email protected]
# Test staging renewal
certbot renew --staging --dry-run
# Production deployment ONLY after staging validation
certbot certonly --webroot -w /var/www/html -d example.com --email [email protected]
Development Workflow Commands
# Step 1: Initial testing with staging + dry-run
certbot certonly --staging --dry-run \
--webroot -w /var/www/html -d dev.example.com
# Step 2: Get staging certificate (doesn't affect production limits)
certbot certonly --staging \
--webroot -w /var/www/html -d dev.example.com
# Step 3: Production certificate (only after staging success)
certbot certonly \
--webroot -w /var/www/html -d example.com
Advanced Certificate Renewal Commands
Force Renewal Considerations
The --force-renewal flag forces certificate renewal regardless of expiry date. Use with extreme caution due to its impact on rate limits.
# Standard renewal (recommended - only renews if needed)
certbot renew
# Force renewal (USE WITH CAUTION)
certbot renew --force-renewal
# Force renewal for specific certificate (USE WITH CAUTION)
certbot renew --cert-name example.com --force-renewal
Critical Warning: Using --force-renewal unnecessarily:
- Causes excessive load on Let's Encrypt systems
- Consumes your Exact Set of Identifiers limit (5 per 7 days)
- Reserve this flag for genuine emergencies only
Enterprise Implementation Pattern:
#!/bin/bash
# Enterprise-grade renewal script with rate limit protection
CERT_NAME="example.com"
DAYS_BEFORE_EXPIRY=30
# Check if renewal is actually needed
CERT_INFO=$(certbot certificates --cert-name "$CERT_NAME" 2>/dev/null)
EXPIRY_DATE=$(echo "$CERT_INFO" | grep "Expiry Date" | awk '{print $3, $4, $5, $6}')
if [ -z "$EXPIRY_DATE" ]; then
echo "Certificate not found: $CERT_NAME"
exit 1
fi
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_TO_EXPIRY=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))
echo "Certificate expires in $DAYS_TO_EXPIRY days"
if [ $DAYS_TO_EXPIRY -lt $DAYS_BEFORE_EXPIRY ]; then
echo "Renewal needed, proceeding..."
certbot renew --cert-name "$CERT_NAME"
else
echo "Certificate still valid for $DAYS_TO_EXPIRY days - no renewal needed"
fi
Rate Limit Monitoring Commands
Status and Monitoring
# Check current certificate status
certbot certificates
# View detailed certificate information
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -text -noout
# Check certificate expiry date specifically
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -enddate -noout
# Monitor rate limit errors in logs
grep -i "rate limit" /var/log/letsencrypt/letsencrypt.log | tail -20
Check Issued Certificates via Certificate Transparency
#!/bin/bash
# Check how many certificates have been issued for your domain
# Uses Certificate Transparency logs via crt.sh
DOMAIN="example.com"
echo "Checking certificates issued for $DOMAIN in the last 7 days..."
# Query crt.sh (public Certificate Transparency log aggregator)
curl -s "https://crt.sh/?q=${DOMAIN}&output=json" | \
jq '[.[] | select(.not_before > (now - 604800 | todate))] | length' 2>/dev/null
echo "Remember: Limit is 50 certificates per registered domain per 7 days"
Automated Monitoring Script
#!/bin/bash
# Rate limit monitoring for enterprise environments
DOMAIN="example.com"
LOG_FILE="/var/log/certbot-monitor.log"
ALERT_THRESHOLD=40 # Alert at 80% of 50 limit
check_rate_limits() {
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# Count certificates issued in last 7 days via crt.sh
local count=$(curl -s "https://crt.sh/?q=${DOMAIN}&output=json" | \
jq '[.[] | select(.not_before > (now - 604800 | todate))] | length' 2>/dev/null)
if [ -z "$count" ] || [ "$count" = "null" ]; then
echo "$timestamp: ERROR - Could not query crt.sh" >> $LOG_FILE
return 1
fi
echo "$timestamp: Certificates issued this week for $DOMAIN: $count/50" >> $LOG_FILE
if [ "$count" -ge "$ALERT_THRESHOLD" ]; then
echo "$timestamp: WARNING - Approaching rate limit (${count}/50)" >> $LOG_FILE
# Send alert to monitoring system
curl -X POST "https://monitoring.example.com/alert" \
-H "Content-Type: application/json" \
-d "{\"severity\":\"warning\",\"message\":\"Rate limit warning for $DOMAIN: ${count}/50 certificates\"}" \
2>/dev/null
fi
}
check_rate_limits
Troubleshooting Commands
Rate Limit Recovery
When you've hit a rate limit, Let's Encrypt cannot manually reset it. Your capacity will gradually refill over time.
# Check if rate limited (use dry-run to test without consuming limits)
certbot certonly --dry-run --webroot -w /var/www/html -d example.com
# View recent certbot activity
journalctl -u certbot --since "1 week ago" | grep -i "rate\|limit\|error"
# Check certbot logs for rate limit messages
grep -E "(rate limit|too many)" /var/log/letsencrypt/letsencrypt.log
# Clean up duplicate certificates (if any)
certbot delete --cert-name example.com-0001
Workaround for Exact Set of Identifiers Limit
If you've hit the "5 certificates per exact set of identifiers" limit, you can request a certificate with a different set of identifiers:
# Original request (hit limit)
# certbot certonly -d example.com -d www.example.com
# Workaround: Add another identifier to create a different set
certbot certonly -d example.com -d www.example.com -d blog.example.com
# Note: This new certificate will be subject to:
# - New Orders per Account limit (300 per 3 hours)
# - New Certificates per Registered Domain limit (50 per 7 days)
Emergency Procedures
# If rate limited, optimize renewal configuration
# Renew earlier (default is 30 days before expiry)
echo "renew_before_expiry = 45 days" >> /etc/letsencrypt/renewal/example.com.conf
# Set up automated renewal check
echo "0 0,12 * * * root certbot renew --quiet" > /etc/cron.d/certbot-renew
# Monitor for when rate limit resets
# Rate limit error messages include retry time, e.g.:
# "retry after 2025-01-28 15:30:00 UTC"
Command Quick Reference
| Task | Command | Notes |
|---|---|---|
| Test configuration | certbot --dry-run certonly -d example.com |
Always do this first |
| Use staging | certbot --staging certonly -d example.com |
For development/testing |
| Check certificates | certbot certificates |
Shows expiry dates |
| Standard renewal | certbot renew |
Only renews if needed |
| View logs | journalctl -u certbot |
Check for errors |
| Check CT logs | curl "https://crt.sh/?q=example.com" |
Count recent issuances |
Important Reminders
- Always use
--dry-runfirst before actual certificate requests - Use staging environment for all development and troubleshooting
- Monitor your issuance rate via Certificate Transparency logs
- Avoid
--force-renewalunless absolutely necessary - Revoking certificates does NOT reset rate limits
- Rate limit errors include
Retry-After- parse and respect this header
Related Documentation
- Rate Limiting Overview - Core concepts and quick reference
- Rate Limiting API Reference - Endpoint limits and integration
- Rate Limiting Troubleshooting - Error resolution and recovery
- Certificate Lifecycle Management - Automated renewal strategies
- Certbot Installation - Installing and configuring Certbot
- HTTP-01 Challenge Commands - Challenge validation commands