# Profiling Performance Bottlenecks in Production

DevFeed: [Profiling Performance Bottlenecks in Production](<https://devfeed.tech/articles/profiling-performance-bottlenecks-in-production-20040.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/profiling-performance-bottlenecks-in-production>)

Author: Doximity

Published: 2026-06-18T12:53:00Z

Content type: tutorial

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Ruby](<https://devfeed.tech/topics/ruby.md>), [Code](<https://devfeed.tech/topics/code.md>), [User Experience](<https://devfeed.tech/topics/user-experience.md>)

Tags: [how-to](<https://devfeed.tech/tags/how-to.md>), [latency](<https://devfeed.tech/tags/latency.md>), [performance](<https://devfeed.tech/tags/performance.md>), [production](<https://devfeed.tech/tags/production.md>), [profiling](<https://devfeed.tech/tags/profiling.md>), [ruby](<https://devfeed.tech/tags/ruby.md>), [time](<https://devfeed.tech/tags/time.md>)

## AI overview

This article explains how to use profiling to identify performance bottlenecks in production Ruby applications. It contrasts instrumenting and sampling profilers, emphasizing that sampling has lower overhead and is suitable for production. The article reports that profiling reduced a background job's runtime by about 80%.

## Source excerpt

One of our background jobs was so slow that users assumed it was broken. They would kick it off, wander away, knowing it would take ages to complete. Turns out the job was fine. It was just taking its sweet time. We eventually cut its runtime by about 80%, and the fix was so small it was almost insulting. You could have stared at the code for hours and missed it. A profiler found it in minutes. This post is about how to think about profiling so you reach for it at the right moment, not as a first reflex. Performance is a KPI, Not a Vibe It's easy to treat performance as something you tune when someone complains. But latency is a feature, and a slow background job has real downstream costs: a worse user experience, more compute burned, queues backing up, and a quietly growing tolerance for "well, that's just how long it takes." The mindset shift that helped us was treating performance like any other key metric we hold ourselves accountable to. That means it has to be measured, it has to have a number, and that number has to move in a direction we choose on purpose. "It feels faster" is not a result. "p95 went from 214 seconds to 69 seconds on a representative input" is a result. Which raises the obvious question: Once you've decided to take a number seriously, how do you find out where the time actually goes? Profilers, And How They Work A profiler answers one question very well: Inside a single execution of code, where is the time being spent? We can get that answer using one of two broad strategies: Instrumenting (tracing) profilers wrap every method call to record when it starts and stops. You get extremely precise, complete call counts and timings. But the overhead is high, and that overhead can distort the very timings you're trying to measure. Wrapping millions of tiny method calls makes the cheap ones look expensive. Sampling profilers take the opposite approach. Instead of instrumenting every call, they periodically interrupt the program -- say, hundreds of ti