Short answer
Rotate a certificate with zero downtime by putting the new files in place and asking the service for a graceful reload instead of a restart. A reload starts new worker processes with the new certificate while existing connections are allowed to finish on the old ones. nginx (nginx -s reload) and Apache (apachectl graceful) support this natively. Behind a load balancer you rotate one node at a time; in Kubernetes you update the Secret mounted into the pod.
Reload vs restart — the decisive difference
A restart kills the process and reopens it: all active TLS connections drop, and there is a brief window where the port is not listening. A reload (graceful) asks the master process to start new workers with the new configuration and certificate, while the old workers finish their in-flight connections. Users notice nothing.
nginx: graceful reload
Put the fullchain and key in place, test the configuration, and send the reload signal:
# Verify config and certificates are valid BEFORE reloading sudo nginx -t # Graceful reload — new workers with new cert, old ones drain sudo nginx -s reload # (equivalent to: sudo systemctl reload nginx)
If you skip nginx -t and the certificate file is corrupt, the reload fails and the old process keeps running — annoying, but not an outage. Always verify afterwards that the new certificate is actually served. See the full TLS setup on nginx.
Apache: graceful
# Check syntax first sudo apachectl configtest # Graceful: finish in-flight requests, then reload sudo apachectl graceful # (equivalent to: sudo systemctl reload apache2 / httpd)
Apache's graceful lets each child process finish its current request before being reloaded with the new certificate. Details in the guide to TLS on Apache.
Behind a load balancer: rolling rotation
When TLS is terminated on a pool of backends, you rotate them one at a time to avoid taking the whole service down:
- Take node 1 out of the load balancer pool (drain).
- Put the new certificate in place and reload the service on node 1.
- Verify node 1 serves the new certificate correctly.
- Put node 1 back in the pool, and repeat for node 2, 3 …
If TLS is instead terminated on the load balancer itself (offloading), you update the certificate in one place — but be aware of how rotation works on that specific platform; see offloading vs passthrough vs bridging.
Kubernetes: update a Secret, not a file
In Kubernetes the certificate lives in a TLS Secret. With cert-manager it is updated automatically on renewal. Ingress controllers (e.g. ingress-nginx) detect the change and reload without a restart. For pods that mount the secret as a volume, the new file usually propagates within about a minute — but an application that reads the certificate into memory at startup must be reloaded:
# Inspect the certificate in a TLS secret
kubectl get secret example-tls -o jsonpath='{.data.tls\.crt}' \
| base64 -d | openssl x509 -noout -dates
# Rolling restart if the app caches the certificate at startup
kubectl rollout restart deployment/web -n web
If you use mTLS between services, see mTLS in Kubernetes.
The classic trap: renewed but never reloaded
The most common reason a "renewed" certificate still expires for users is that the service was never reloaded — it is still running the old certificate from memory. ACME clients therefore have a deploy hook:
# certbot: run reload only when a certificate was actually renewed sudo certbot renew --deploy-hook "systemctl reload nginx"
How CertControl confirms the rotation succeeded
The rotation itself is one thing; confirming from the outside that the new certificate is actually served is another. CertControl scans the endpoint after the rotation and sees the new expiry date, the right serial number and the full chain — so you find out immediately if a node in the pool, an ingress or a caching app is still running the old certificate.
Frequently asked questions
What is the difference between reload and restart?
A restart kills and restarts the process, dropping all active connections. A reload (graceful) starts new worker processes with the new certificate while old connections finish gracefully. For certificate rotation you always use reload.
Do I lose active connections with nginx -s reload?
No. nginx starts new workers with the new certificate and lets the old ones finish their in-flight connections before closing. Existing sessions are not broken.
How do I rotate certificates behind a load balancer?
If TLS terminates on the backends, rotate them one at a time (drain, update, reload, verify, return). If TLS terminates on the load balancer itself, update the certificate in one place using that platform's method.
Do I need to restart pods in Kubernetes after a renewal?
Only if the application reads the certificate into memory at startup. Ingress controllers reload automatically when the TLS secret changes; volume-mounted secrets usually update within a minute.
Why did my certificate expire even though I renewed it?
Almost always because the service was not reloaded and still serves the old certificate from memory. Use a deploy hook (e.g. certbot --deploy-hook) that reloads automatically after a renewal.