Debug logging in production: what the flag someone forgot to flip is costing
DEBUG level in production is one of the most expensive accidental configurations in software. It is also invisible, because nothing breaks. Here is how to price it and find it.
Quick answer
DEBUG output is typically 5x to 15x the volume of INFO for the same workload, and TRACE can be 50x. A service producing 4 GB/day at INFO produces 20 to 60 GB/day at DEBUG, which at CloudWatch's $0.50 per GB is an extra $240 to $840 per month for one service. Across a 40-service estate where six services have DEBUG left on, the invisible cost routinely reaches $3,000 to $5,000 per month. The fix is to make log level runtime-configurable with automatic expiry, so raising it for an incident cannot become permanent.
Every organization has this. Someone turns on DEBUG during a 2am incident to see what a service is doing, the incident resolves, and the flag stays. Nothing breaks. No alert fires. Dashboards look the same. The only symptom is a logging bill that is 40% higher than it should be, spread across enough services that no single line looks wrong. It is the most expensive silence in observability.
The volume multiplier
| Level | Typical lines per request | Relative volume |
|---|---|---|
| ERROR | 0.002 | 0.01x |
| WARN | 0.05 | 0.1x |
| INFO | 2 to 4 | 1x baseline |
| DEBUG | 15 to 50 | 5x to 15x |
| TRACE | 100 to 400 | 30x to 50x |
The multipliers vary by framework and how disciplined the codebase is, but the shape holds everywhere. DEBUG lines are emitted inside loops, for every database query, for every cache lookup, for every HTTP client call, and for every serialization step. A single request that produces three INFO lines can easily produce forty DEBUG lines.
Pricing one forgotten flag
Take a service handling 8 million requests per day, producing 3 INFO lines per request at 350 bytes, so 8.4 GB/day. Switch to DEBUG at 30 lines per request and it produces 84 GB/day. That is an additional 75.6 GB/day, 2,268 GB/month.
| Platform | Ingest price | Extra cost per month |
|---|---|---|
| CloudWatch Logs Standard | $0.50 / GB | $1,134 |
| CloudWatch Logs Infrequent Access | $0.25 / GB | $567 |
| Google Cloud Logging | $0.50 / GiB | $1,134 |
| Azure Monitor analytics logs | ~$2.76 / GB | $6,260 |
| Azure Monitor Basic Logs | ~$0.65 / GB | $1,474 |
One service. One flag. On Azure that flag is worth more than a senior engineer's monthly salary in some markets. And the retention multiplier applies on top: 30 days of the extra volume adds another $68 at CloudWatch's $0.03 per GB-month, plus every Logs Insights query over that log group now scans ten times more data at $0.005 per GB.
The second-order costs
Ingestion is not the only damage. Debug logging is synchronous in many frameworks, so emitting forty lines per request adds measurable latency, typically 2 to 15 milliseconds per request depending on the appender and whether it writes to stdout captured by a container runtime. At p99 that shows up as a latency regression nobody attributes to logging.
Disk and network follow. A node writing 84 GB/day to a container log file needs more local storage and more log rotation, and the agent forwarding it uses proportionally more CPU. On a cluster where the DaemonSet agent normally uses 0.2 vCPU, a tenfold volume increase can push it past its limit and cause dropped logs, which is the cruelest outcome: you are paying more and losing data.
And there is a real security dimension. DEBUG output frequently includes request bodies, headers with tokens, SQL with parameter values, and full object dumps. Shipping that to a log platform expands the scope of what a compromised logging credential exposes, and it may pull log data into a compliance boundary it was not designed for.
Finding it
Do not audit code, audit bytes. Query per-log-group ingestion volume and normalize by request count or pod count. A service producing more than about 1.5 KB of logs per request is a strong candidate. In CloudWatch, IncomingBytes per log group is a free metric; chart it against service request rate and outliers are obvious in a minute.
Then look for the signature patterns: line counts that scale with database query count rather than request count, log lines containing full SQL statements or serialized objects, and any log group whose daily volume jumped abruptly and never came back down. That last one usually pins the exact incident date when someone flipped the flag.
Preventing the recurrence
The durable fix is expiry. Make log level a runtime-configurable value, through a feature flag service, an admin endpoint, or a config map, and make elevated levels expire automatically after a set window, typically 2 to 4 hours. Someone debugging an incident gets what they need and the system reverts itself. This is the single highest-value change in this whole area because it removes the human step that always fails.
Complement it with a per-service alert on log volume growth exceeding 50% week over week, a default of INFO enforced in base images or shared logging configuration, and a monthly review of the top five log producers. Where DEBUG genuinely needs to run continuously for a specific service, route that log group to a cheap ingestion tier, halving the price of a decision you have chosen to make. Log groups and their ingestion class are Terraform, so price the estate from the plan against the resource catalog and pair that with the volume reduction tactics that keep the baseline low.
FAQ
How much more does DEBUG logging cost than INFO?
Typically 5x to 15x the volume, and TRACE can be 30x to 50x. A service handling 8 million requests per day at 3 INFO lines per request produces 8.4 GB/day; at 30 DEBUG lines per request it produces 84 GB/day. The extra 2,268 GB per month costs $1,134 at CloudWatch's $0.50 per GB and about $6,260 on Azure Monitor analytics logs at roughly $2.76 per GB.
Why is debug logging in production so hard to notice?
Because nothing breaks. No alert fires, dashboards look normal, and the service behaves correctly. The only symptom is a higher logging bill, and when it is spread across several services no single line looks wrong. It usually starts when someone raises the level during a 2am incident and never lowers it, so the cost has no obvious owner or start date on the invoice.
What are the non-financial costs of debug logging in production?
Latency, capacity, and security. Synchronous appenders emitting forty lines per request add roughly 2 to 15 milliseconds, showing up as an unexplained p99 regression. Log agents sized for normal volume can exceed CPU limits at ten times the volume and start dropping logs, so you pay more and lose data. And DEBUG output frequently contains request bodies, auth headers, and SQL parameters, expanding the compliance and breach surface.
How do I find services running DEBUG in production?
Audit bytes rather than code. Chart per-log-group ingestion volume, which is free as the IncomingBytes metric in CloudWatch, normalized by request count or pod count. Any service producing more than about 1.5 KB of logs per request is a candidate. Look for volume that scales with database query count rather than request count, and for log groups whose daily volume jumped abruptly and never returned.
How do I stop debug logging from being left on?
Make log level runtime-configurable with automatic expiry. An elevated level set through a feature flag, admin endpoint, or config map should revert itself after 2 to 4 hours, so an engineer gets what they need during an incident and the system restores the default without a human step. Add an alert on any service whose daily log volume grows more than 50% week over week.
How does C3X help with logging cost visibility?
Log groups, their ingestion class, and retention settings are Terraform resources created in pull requests. C3X prices them from the plan, so a new log group defaulting to Standard ingestion with long retention carries a cost estimate in review. Where a service genuinely needs verbose logging, that visibility makes routing it to a cheaper ingestion tier an explicit, priced decision rather than an oversight.
What to do next
Catch expensive logging defaults in review. C3X reads your Terraform and prices log groups and ingestion tiers against a live catalog. Start with the quickstart.
Share this post
Try C3X on your own Terraform
Free and open source. No API key required. One command to install, one command to estimate.