Home › Datasets › Production Debugging & Root-Cause Reasoning

Coding & Engineering Pack

How to Fine-Tune an LLM for Production Debugging & Root-Cause Analysis

Diagnosing complex, multi-signal production issues (logs, metrics, intermittent symptoms) through structured hypothesis testing — distinct from single-function bug fixes.

Fine-tune a model on this dataset Preview Dataset

$39 for the dataset. Training is priced separately by model, starting at $47.

What can this kind of fine-tuning teach an LLM?

A general-purpose model may already know some of this subject. Fine-tuning serves a different purpose: it repeatedly demonstrates the kinds of requests, response patterns, terminology, decisions and workflows you want the model to handle more consistently.

For Production Debugging & Root-Cause Reasoning, the dataset focuses on diagnosing complex, multi-signal production issues (logs, metrics, intermittent symptoms) through structured hypothesis testing — distinct from single-function bug fixes. Fine-tuning shapes recurring model behavior; it does not turn the model into a live database or guarantee correctness on every new case.

What training data should cover

Useful supervised fine-tuning data should resemble the work you expect the model to perform. This Rebiha dataset's domain definition is organized around 12 coverage areas:

How Rebiha prepared the training material

This page contains 383 instruction-response pairs from the existing Rebiha dataset. Its domain definition was designed around the coverage areas above so the training material spans multiple realistic tasks rather than one narrow prompt pattern.

Rebiha's broader dataset workflow uses structured quality review to help identify problems such as contradictions, unsupported claims, unsupported assumptions, calculation errors and other weak training examples. You can inspect real examples on this page before deciding whether the dataset fits your model and use case.

What is in this dataset

383 instruction-response pairs covering diagnosing complex, multi-signal production issues (logs, metrics, intermittent symptoms) through structured hypothesis testing — distinct from single-function bug fixes. Each pair is a realistic instruction with a full written response, in the JSONL format used for supervised fine-tuning. No synthetic filler, no duplicated rows.

Example pairs

Real rows from the dataset, shown in full.

Our checkout service is intermittently returning 504s and 502s for about 2% of requests, but only during peak hours. The load balancer shows healthy instance counts, and CPU/memory on all instances look normal. However, I see a pattern in the access logs: failures occur only for requests where the `X-Request-ID` header contains a specific substring (e.g., `-retry-`), and those requests always have a `User-Agent` that includes `curl/7.68` or `python-requests/2.31`. Also, the error logs show occasional `connection reset by peer` from an upstream Redis cluster, but no Redis alerts. What's the most likely root cause, and what diagnostic steps would you take to confirm it before making changes?

Start by separating signals from noise. The CPU/memory being normal rules out a simple resource exhaustion on the app tier, but you haven't checked network sockets, file descriptors, or thread pool saturation. The correlation with `X-Request-ID` containing `-retry-` is suspicious — that suggests these are retry requests, likely from internal clients or cron jobs, not organic traffic. The User-Agent pattern narrows it to two client types. My leading hypothesis is a client-side retry storm interacting with a connection pool limit on the upstream Redis, specifically a `maxclients` or `tcp-keepalive` issue. When a retry request comes in, it likely opens a new Redis connection because the pool is exhausted by stale connections from long-lived curl/python sessions that don't reuse sockets properly. Under peak load, the Redis server hits its connection ceiling, resets the TCP connection, and your service surfaces as 504/502. To confirm: (1) Pull Redis `INFO clients` during the failure window and check `connected_clients` against `maxclients` — look for a spike right before each error. (2) In the app, enable DEBUG logging for the Redis client pool to see if `borrowObject` returns null or if you see `Could not get a resource from the pool`. (3) Correlate the exact timestamps of 504s with Redis connection resets in the Redis slowlog or `redis-cli -c info stats | grep rejected_connections`. (4) Check the `netstat` on app instances during peak — look for many `TIME_WAIT` or `CLOSE_WAIT` sockets to Redis. If confirmed, the fix is two-fold: set a shorter `maxIdleTime` on the Redis pool and configure the client library to validate connections on borrow, plus ensure retry logic uses exponential backoff with jitter rather than immediate retries. But don't change anything until you've confirmed the connection ceiling hypothesis with those metrics.

We have a batch processing service that works perfectly in staging with 100k records, but in production with 50M records it starts slowing down after about 10 minutes, then throughput drops to near zero, and eventually the entire JVM runs out of memory and crashes. The heap dump shows a large `java.util.HashMap` with millions of entries, but the code doesn't seem to store anything globally. The only difference is production has a Kafka consumer with 12 partitions, staging has 2. What is the likely root cause, and how would you test the hypothesis systematically?

The 'works in staging, fails in production' discrepancy with a growing HashMap that isn't explicitly in your code screams a hidden accumulation tied to partition count — likely a per-partition state buffer or an offset commit mechanism that retains records in memory until a condition is met. My primary hypothesis is that you're using a Kafka consumer with `enable.auto.commit=false` and a manual commit after processing a batch, but your processing logic has a bug where a failure in one record of a partition prevents the offset from advancing, causing the consumer to re-read the same records repeatedly. However, the HashMap specifically suggests something else: maybe you're using a `KafkaStreams` or a processor that maintains a `KeyValueStore` with in-memory caching, and the cache eviction policy is based on a timer that never fires because the processing thread is blocked on a slow external call. But let's structure the diagnosis. Step 1: Reproduce in staging with a scaled-down test — run 12 partitions but only 5M records; if you see the same slowdown, you've isolated partition count as a variable. Step 2: Monitor GC logs and heap usage over time using `jstat -gcutil`. Look for a pattern where old-gen usage climbs linearly but never drops — that indicates a leak or an unbounded cache. Step 3: Take two thread dumps 60 seconds apart during the slowdown (`jstack`). If you see many threads blocked on `put` or `get` of the HashMap, check the stack trace to identify which library is calling it — it might be a `ConcurrentHashMap` inside a state store. Step 4: Inspect the Kafka consumer metrics: `records-lag` per partition. If lag is high on only one partition and that partition's offset never advances, you're hitting a poison message. If lag is zero but memory still grows, you're holding onto records after commit. Step 5: Enable Kafka debug logging for `consumer.coordinator` to see rebalancing events — if the consumer group is rebalancing repeatedly (due to session timeouts), each rebalance can trigger a state store reload that duplicates in-memory entries. My leading hypothesis is actually a combination: you're using a `Transformer` that keeps a per-key aggregate in a state store, and because production data has many more unique keys, the store grows unbounded because you never call `punctuate` to evict old keys. Test this by adding a `TimeWindows` or a `retention` threshold on the state store. Run the experiment with 12 partitions and 50M records but with a debug flag that logs the size of the state store every minute — if it grows linearly with no eviction, that's your leak.

Our API gateway has been gradually slowing down over the past 3 weeks — p99 latency increased from 200ms to 900ms, and the response time is now consistently degrading even during off-peak hours. CPU and memory on the gateway instances are flat, no increase in error rate, and no code changes were deployed recently. The only thing that changed is that we added a new upstream service that returns a large JSON payload (about 5MB) and is called by about 0.1% of requests. We suspect a resource leak, but CPU/memory are flat. What could cause a gradual degradation without CPU/memory growth, and how would you diagnose it?

Flat CPU and memory with monotonic latency growth points to a resource that is not accounted for in those two metrics — the usual suspects are file descriptors, connection pool exhaustion, thread pool saturation, or TCP buffer memory that's not reflected in heap. Given the 5MB payload, I'd first suspect a socket read buffer leak or an HTTP connection that isn't being closed properly for that large response. But the gradual 3-week window suggests something that accumulates per request, not a fixed-size pool. My top hypothesis is an unclosed `InputStream` or `ResponseBody` on the client that calls the new upstream service, causing the OS to keep file descriptors open. Over time, the gateway hits the `ulimit -n` limit, and every new connection waits for a descriptor to be freed — but because CPU and memory are flat, you won't see a spike. The fact that it degrades even off-peak indicates you've crossed the threshold. To diagnose: (1) Run `lsof -p <gateway_pid> | wc -l` and compare to the soft/hard limit (`ulimit -n`). If you see thousands of open sockets to the upstream service's IP that are in `CLOSE_WAIT` state, that's your leak. (2) Check `/proc/<pid>/fd` count over time — if it's monotonically increasing, that's the smoking gun. (3) Use `ss -tan state close-wait` to see if connections to the upstream are stuck. (4) For a deeper signal, enable JVM's `-XX:NativeMemoryTracking=summary` and check `jcmd <pid> VM.native_memory` — look at 'Socket' or 'Internal' memory growth. (5) Also check the gateway's thread pool metrics — if you're using a fixed thread pool, see if `activeThreads` is slowly climbing because threads are blocked on reading a never-ending stream. A key test: take a thread dump during the slow period — if you see many threads in `java.net.SocketInputStream.socketRead0` with stack traces pointing to the upstream client, that confirms blocked reads. The root cause is likely that the upstream service sends a `Content-Length` but your client never reads to completion because you're only reading the first part of the body (e.g., for header inspection) and not draining the rest, leaving the connection in a half-read state. The fix would be to either fully consume the body or use a connection close strategy for that upstream. But confirm the FD count and close-wait state first before changing the client.

Who this is for

Builders who want their fine-tuned model to reliably perform this specific capability, as part of a broader assistant or agent.

Which models this works with

The dataset is plain JSONL, so it works with any instruction-tuned open model. On Rebiha you can train it directly on:

Training uses LoRA, or QLoRA on a 4-bit base for larger models. Your base model's weights are never modified — training produces a separate adapter.

How it works

  1. Pick this dataset and a base model.
  2. Rebiha runs the job on a managed GPU. You set up nothing.
  3. Download your model: a ready-to-run GGUF, plus developer assets (adapter, tokenizer, configs).

Fine-tuning or RAG?

Use RAG when the model needs facts that change — your prices, your documents, today's inventory. Use fine-tuning when you want consistent behavior and structure without prompting for it every time. This dataset teaches the shape of this capability, not facts to look up.

How managed fine-tuning works

  1. Inspect the dataset examples and choose a compatible base model.
  2. Rebiha runs the training job on managed GPU infrastructure using LoRA or QLoRA as appropriate.
  3. Download portable model assets for your own workflow, including the available ready-to-run and developer outputs for the selected training path.

Fine-tuning or RAG?

Use fine-tuning when the objective is recurring behavior: response structure, domain patterns, terminology, workflow, or how the model approaches a class of requests. Use RAG when answers depend on changing or proprietary facts that should be retrieved at request time. The two approaches can also work together.

Know what goes in. Own what comes out.

You can inspect real examples before training, choose the model you want to adapt, and keep portable model assets when training is complete.

Related datasets

Start fine-tuning