DevOps Daily with Fexingo · 2026-07-01 · 10 min
Key moments - from our scoring
Substance score
71 / 100
Five dimensions, 20 points each
Lucas and Luna explore why enabling Kubernetes audit logging frequently tanks cluster performance despite being a security best practice. The core problem isn't audit logging itself, but how teams configure it: defaulting to RequestResponse verbosity for all resources and pointing audit webhooks at overloaded backends like Elasticsearch creates synchronous blocking on every API request. When the webhook slows down or becomes unavailable, the API server queues audit events, and if the queue fills, starts dropping requests entirely. This backpressure ripples down to etcd, where the leader node falls behind on heartbeats and triggers unnecessary re-elections. Lucas shares a fintech case study where audit logging pushed p99 latency from 8ms to 450ms. The fixes are concrete: drop audit policy to Metadata-only for most resources (cutting event size by 90%), tune webhook batch parameters (increase batch size from 10 to 100, reduce max wait from 10s to 5s), and consider the audit log sidecar pattern (Fluentd or Filebeat decouples the API server from log shipping). The episode covers audit policy levels (None, Metadata, Request, RequestResponse), per-resource overrides, the new Kubernetes 1.27 dynamic audit configuration feature, and why local NFS volumes for audit logs are just as problematic as slow webhooks.
Audit logging at RequestResponse level blocks the API server on each request while it waits for the audit webhook to complete. If the webhook is slow, the API server queues events and delays writes to etcd, causing the etcd leader to miss heartbeats and trigger re-elections.
Metadata logs only the user, timestamp, resource type, and verb (roughly 500 bytes per pod create), while RequestResponse logs the full request and response bodies (5+ kilobytes), consuming 10x more storage and creating 10x more backpressure on the API server.
Drop the audit policy from RequestResponse to Metadata for most resources, tune webhook batching (increase batch size to 100, reduce max wait to 5 seconds), ensure the audit backend has sufficient capacity, and consider using a sidecar pattern (Fluentd, Filebeat) to decouple logging from the API server.
A sidecar container (Fluentd or Filebeat) tails the local audit log file and ships it to the backend, allowing the API server to write audit events asynchronously to disk without waiting for network calls, eliminating the bottleneck.
Yes, since Kubernetes 1.27 with the dynamic audit configuration feature, which is still experimental in some distributions; older versions require an API server restart.
Our reviewer’s read on each dimension, with quotes from the episode.
The episode delivers dense, technical content with clear cause-and-effect chains (audit logging → webhook delays → etcd election timeouts) and concrete tuning parameters (batch size 10→100, wait time 10→5 seconds). However, it stays within well-known Kubernetes operational territory rather than revealing truly novel failure modes or counterintuitive insights.
Every Kubernetes object - pods, services, configmaps - is stored in etcd. When you create or update an object, the API server writes to etcd. That's one write. But with audit logging at RequestResponse level, the API server also has to serialize the entire request and response body into an audit event
The API server's default audit webhook batch size is 10 events, with a maximum wait of 10 seconds. So under load, the API server would batch events, but the webhook call would take 12 seconds to complete, causing backpressure.
The episode covers standard Kubernetes audit logging mechanics and well-established performance tuning patterns (reduce verbosity, use sidecars, adjust batch parameters). While the specific fintech example adds credibility, the underlying frameworks and recommendations are widely documented in Kubernetes security and operations guides.
There are three levels: None, Metadata, Request, and RequestResponse.
Instead of the API server sending audit events directly to a webhook, it writes to a local file, and a sidecar like Fluentd or Filebeat tails that file and ships it to the backend.
Lucas demonstrates direct operational experience (fintech cluster work, observed p99 latency changes from 8ms to 450ms, handled actual incident response). He speaks with practitioner credibility and knows implementation details. However, the episode doesn't establish his formal role, scale of responsibility, or whether he's a regular podcast guest versus a working operator.
I worked with a fintech team last year - they had a three-node etcd cluster, fairly standard. After they enabled audit logging with the webhook backend pointed to their existing Elasticsearch cluster, they saw p99 API response times go from 8 milliseconds to 450 milliseconds.
I've seen p99 drop by 80 percent just by reducing verbosity.
The episode excels with concrete numbers: 8ms→450ms latency, 500 bytes→5KB event size, batch size 10→100, wait time 10→5 seconds, 90% size reduction from RequestResponse→Metadata, p99 drops of 80%. The fintech example is named and detailed. Metrics are specific enough to replicate or benchmark against.
they saw p99 API response times go from 8 milliseconds to 450 milliseconds
a typical pod create event at Metadata level might be 500 bytes. At RequestResponse, it could be 5 kilobytes or more, depending on the object size
Luna asks clarifying follow-ups ("Wait - audit logging did that?", "So each API request generates multiple audit events?") that surface misconceptions and guide the narrative logically. However, questions are mostly confirmatory rather than challenging; there's no pushback on assumptions, no exploration of trade-off downsides beyond brief mention, and the conversation stays in agreement mode rather than productive tension.
Wait - audit logging did that? I've seen clusters with audit enabled and they were fine. What's different?
Right, I've seen that - the audit webhook becomes a bottleneck. But you mentioned etcd specifically. How does audit logging affect the underlying key-value store?
Computed from the transcript - who did the talking, and the words that came up most.
In this episode of DevOps Daily with Fexingo, Lucas and Luna dive into a subtle but costly Kubernetes performance issue: how verbose audit logging can silently degrade etcd performance, leading to increased latency, timeouts, and even cluster instability. They walk through a real-world case from a mid-sized fintech that saw API response times jump from 5ms to over 200ms after enabling audit logs without tuning. You'll learn about the audit log pipeline, how etcd handles writes, and three practical mitigations: adjusting audit policy verbosity, using webhook batching, and offloading logs via sidecar. No theory - just actionable advice for anyone running Kubernetes in production. #Kubernetes #AuditLogging #etcd #Performance #CloudNative #SRE #DevOps #ProductionIncident #Fintech #K8s #Logging #Latency #ClusterStability #Monitoring #Tuning #Technology #FexingoBusiness #BusinessPodcast Keep every episode free: buymeacoffee.com/fexingo
Transcribed and scored by The B2B Podcast Index.
Lucas: So you enable audit logging on your Kubernetes cluster - standard best practice, right? Security teams love it, compliance requires it, and then suddenly your API server response times go from five milliseconds to two hundred. Your etcd starts throwing leader election timeouts. Nobody changed any workloads.
Luna: Wait - audit logging did that? I've seen clusters with audit enabled and they were fine. What's different? Lucas: It's not about having it on or off - it's about how much you log and where you send it.
By default, the audit policy logs every request at the Metadata level, which is relatively lightweight. But a lot of teams, especially ones coming from compliance-heavy environments, crank it up to Request or RequestResponse level. And that's where the trouble starts. Luna: So each API request generates multiple audit events, and those get written to etcd?
I thought audit logs went to a file or stdout. Lucas: They can. The default backend writes to a local file on the API server node. But the more common setup in managed or multi-node clusters is the webhook backend - you send audit events to an external service, like an Elasticsearch cluster or a Splunk instance.
The problem is, when that webhook backend is slow or unavailable, the API server blocks and queues events. And if the queue fills up, it starts dropping requests. Luna: Right, I've seen that - the audit webhook becomes a bottleneck. But you mentioned etcd specifically.
How does audit logging affect the underlying key-value store? Lucas: Here's the chain. Every Kubernetes object - pods, services, configmaps - is stored in etcd. When you create or update an object, the API server writes to etcd.
That's one write. But with audit logging at RequestResponse level, the API server also has to serialize the entire request and response body into an audit event and write that event to the audit backend. If that backend is a file, it's fine - local disk is fast. But if it's a webhook, the API server makes an HTTP call to the audit backend.
That call can fail, timeout, or just be slow. Luna: And if the webhook is slow, the API server holds up the main request, which means etcd writes are delayed. So etcd sees increased latency and starts timing out on heartbeats. Lucas: Exactly.
I worked with a fintech team last year - they had a three-node etcd cluster, fairly standard. After they enabled audit logging with the webhook backend pointed to their existing Elasticsearch cluster, they saw p99 API response times go from 8 milliseconds to 450 milliseconds. Their etcd leader was re-electing every few minutes. The root cause?
The Elasticsearch cluster was under heavy load from application logs, and the audit webhook requests were queuing up. The API server's default audit webhook batch size is 10 events, with a maximum wait of 10 seconds. So under load, the API server would batch events, but the webhook call would take 12 seconds to complete, causing backpressure. Luna: So the fix was to either scale the Elasticsearch cluster or reduce audit verbosity?
Lucas: Both. But first, they dropped the audit policy from RequestResponse to Metadata for most resources. That alone cut the audit event size by roughly 90 percent. Then they tuned the webhook batching parameters - increased the batch size from 10 to 100, and reduced the maximum wait from 10 seconds to 5 seconds.
That way, the API server sends fewer, larger batches, and the webhook calls complete faster. Luna: Interesting. So the lesson isn't 'don't audit' - it's 'know your audit policy and your backend capacity'. Lucas: Right.
And there's another layer. Even with a local file backend, you can still hurt etcd if you're not careful. Because the API server writes audit logs synchronously by default. That means every API request blocks on the file write.
If the disk is slow - say, a shared NFS volume - you get the same latency spikes. The fix there is to use a buffered logging library or write to a local SSD, not network storage. Luna: What about the new audit log dynamic configuration feature in recent Kubernetes versions? Does that help?
Lucas: It does. Since Kubernetes 1.27, you can change the audit policy without restarting the API server. That's huge for incident response - you can dial down verbosity in seconds.
But it's still experimental in some distributions. The team I mentioned was on 1.25 at the time, so they had to restart the API server to change the policy. That meant a brief blip in availability.
Luna: Let's talk about the actual audit policy structure. What are the key knobs? Lucas: There are three levels: None, Metadata, Request, and RequestResponse. None means no audit events for that resource.
Metadata logs the user, timestamp, resource type, and verb - but not the request body. That's usually enough for compliance. Request logs the request body but not the response. RequestResponse logs both.
The size difference is dramatic: a typical pod create event at Metadata level might be 500 bytes. At RequestResponse, it could be 5 kilobytes or more, depending on the object size. Luna: So for high-volume resources like pods or events, you'd want Metadata only. What about sensitive resources like Secrets?
Lucas: You can set a separate rule for Secrets - log at RequestResponse but omit the request body for non-secret resources. The policy supports per-resource overrides. The common pattern is: log Metadata for all resources, then RequestResponse only for a few high-value ones like RBAC changes or Secret mutations. And you can use OmitStages to skip logging during certain phases, like when the controller manager updates status.
Luna: That reminds me - we should talk about the audit log sidecar pattern. A lot of teams run a sidecar container in the API server pod to handle audit log shipping, so the API server itself doesn't block on the webhook call. Lucas: Yes, that's a solid pattern. Instead of the API server sending audit events directly to a webhook, it writes to a local file, and a sidecar like Fluentd or Filebeat tails that file and ships it to the backend.
That decouples the API server from the log pipeline. The API server never waits for the network call. The sidecar handles retries and buffering independently. Luna: But doesn't that introduce a risk of losing logs if the sidecar crashes?
Lucas: It does. But you can mitigate with a persistent volume for the audit log directory, and the API server's default audit log backend rotates files anyway. So even if the sidecar is down for a few minutes, the logs accumulate and get shipped when it comes back. It's a trade-off: lower latency for the API server versus potential log loss.
In most production environments, the latency improvement is worth the small risk. Luna: So what's the one thing every Kubernetes operator should check tomorrow? Lucas: Their audit policy. If it's set to RequestResponse for all resources, change it to Metadata.
Then measure your API server response times before and after. I've seen p99 drop by 80 percent just by reducing verbosity. Also, check if your audit backend - whether it's a file or webhook - has enough capacity. And if you're using a webhook, enable batching and tune the batch parameters.
That alone could save you from a cluster-wide incident. Luna: And if you found this episode useful, you know what keeps these deep dives ad-free - listener support. If today's tech conversation gave you something usable, head over to buy me a coffee dot com slash fexingo. It genuinely makes a difference.
Lucas: Yeah, absolutely. No pressure, but if you've ever wondered how to support the show, that's the way. And it means we can keep going into these nitty-gritty topics without any sponsor interruptions. Luna: Exactly.
So back to audit logging - one more thing: what about the etcd compaction and defragmentation? Does audit logging affect that? Lucas: Indirectly. If audit logging causes the API server to write more objects to etcd - for example, if you're logging events as Kubernetes Event objects - then etcd's history grows faster, and compaction becomes more important.
But the main impact is on the API server's ability to serve requests quickly. A slow API server means longer etcd transaction times, which can cause the etcd leader to appear unresponsive to followers. That triggers elections. Luna: So the takeaway: audit logging is essential, but treat it like any other system - monitor its performance, tune its parameters, and plan for capacity.
Lucas: Exactly. And if you're running a cluster with thousands of nodes, audit logging at RequestResponse level is almost certainly going to cause issues. Start lean, add verbosity only where you need it, and always test under load before rolling out.
Other episodes covering the same guests and topics, from across The B2B Podcast Index.