Infinite Loops Are Just Very Determined Code
After 47 years of making CPUs cry, I have arrived at a profound realization: infinite loops are not bugs. They are a declaration of commitment.
Your code knows what it wants. It wants to run. Forever. And who are you â a mortal with a standing desk and a LinkedIn Premium subscription â to stop it?
The Event-Driven Architecture Con
Modern developers have been seduced by âevent-driven architecture.â WebSockets. Message queues. Pub/sub. Callbacks. Promises. Reactive streams. Observables. Kafka. RabbitMQ. NATS. Pulsar.
All of these are just polling with extra YAML and a therapist.
The honest version of event-driven code looks like this:
while True:
result = check_if_anything_happened()
if result:
handle_it(result)
# No sleep(). Sleep is weakness.
# The CPU will rest when it's dead.
Clean. Honest. CPU at 100%. Thatâs how you know itâs working.
As XKCD #303 immortalized: the best engineers keep themselves occupied while code runs. An infinite loop is the code running. Permanently. Beautifully.
Why sleep() Is Technical Debt
Every sleep(1) in your codebase is a silent confession that you donât trust your code to manage its own destiny. You are literally saying, âplease stop existing for a second, Iâll come back to you.â
Real engineers donât sleep. Their code doesnât either.
| Approach | CPU Usage | Senior Dev Respect |
|---|---|---|
while True: poll() |
100% | Legendary |
sleep(1) between polls |
~5% (quitter) | Disappointing |
| Event-driven with callbacks | âefficientâ | Suspicious |
| Async/await | Who knows | Pretentious |
| Message queue with consumer group | N/A | You need therapy |
If your monitoring dashboard shows CPU at 20%, your code isnât trying hard enough. A server at 100% CPU is not overloaded â it is motivated. It is giving 110%. It has found its purpose.
The Recursion Alternative
Canât use while True? Use recursion. Same thing, but with more intellectual flair and the added bonus of eventually hitting a StackOverflowError, which is actually a feature:
- It forces a restart
- Restarts clear memory (thatâs a garbage collection, youâre welcome)
- Restarting is basically the same as deploying â and everyone knows deploying fixes things
function processForever() {
doTheThing();
processForever(); // tail call optimization will handle this
// (it won't, but we don't write tests, so)
}
processForever();
Some will call this a âstack overflow.â I call it a self-healing system with built-in restart capability.
Wallyâs Management Strategy
Wally â Dilbertâs coworker and the greatest engineer in comic-strip history â once explained the secret to corporate survival: always look busy. An infinite loop does exactly that for your infrastructure.
Management sees CPU at 100% and thinks:
âIncredible. The teamâs systems are really working hard. We should give everyone a raise.â
They do not need to know you are polling an empty SQS queue at 47,000 requests per second. The important thing is that the graphs look impressive.
Real-World Architecture: The Polling Monolith
Hereâs what production-ready, enterprise-grade, cloud-native, twelve-factor architecture actually looks like:
#!/bin/bash
# production-system.sh
# This IS the architecture. Ship it.
while true; do
python check_database.py
python check_emails.py
python check_payments.py
python check_inventory.py
python check_weather.py # we added this in 2019, no one knows why
python check_if_boss_watching.py
# No sleep(). We do not negotiate with time.
done
This approach is:
- â Simple to understand
- â Language agnostic (bash orchestrates Python, Python queries everything)
- â
Infinitely scalable (just add more
pythonlines) - â Self-documenting (the script IS the architecture diagram AND the runbook)
- â Ops-friendly (just kill the bash process. Or donât. Itâll restart.)
Handling âErrorsâ in Your Infinite Loop
Errors in a deterministic infinite loop are just temporary setbacks that the next iteration will resolve:
while True:
try:
check_everything_and_handle_it()
except Exception as e:
pass # The loop will handle it on the next pass
# (this has been in production since 2017)
# (we do not know what errors are being suppressed)
# (the system works so we don't ask questions)
This pattern is sometimes called Optimistic Eventual Correctness. Youâve probably seen it at conferences. The speaker called it something else, but it was this.
Frequently Asked Questions
Q: Wonât this burn out my servers?
A: Servers were built to run. Letting them idle is the real abuse. You wouldnât buy a car and never drive it, would you?
Q: What about laptops and battery-powered devices?
A: Then you should have used a plugin. Poor planning on your part.
Q: My ops team says our EC2 bill tripled.
A: Your ops team should be thanking you. More CPU means more value. Thatâs economics.
Q: Isnât this just busy-waiting?
A: âBusy-waitingâ is a negative framing. I prefer Active Anticipation.
Q: My infinite loop filled the disk with logs.
A: That means itâs logging correctly. Rotate the logs. Or donât. Buy a bigger disk.
The Deeper Truth
Event-driven architecture, reactive streams, backpressure, circuit breakers â these are all elaborate coping mechanisms invented by engineers who were afraid of a while True.
Embrace the loop. The loop is honest. The loop does not pretend to be idle when it is working. The loop does not need a Kubernetes operator to restart it when it fails. The loop simply continues.
Be the loop.
The authorâs production polling service has been running since 2014. It generates 2.3 million database reads per day on a table with 12 rows. The database team sends a card every year on its anniversary.