There are two kinds of growth-stage engineering teams: the ones who can answer 'is it down, and why?' in under five minutes, and the ones who find out their product is broken from an angry customer tweet. The difference is observability — and it is not a tool you buy, it is a property you build into the system. Most teams discover they don't have it during their first real incident, at 2am, when the logs are unstructured, there are no traces across services, and the one person who understands the deploy is asleep. Here is how to build observability that earns its keep, and an on-call practice that doesn't grind your best engineers into dust.
Monitoring tells you something is wrong; observability tells you why
Monitoring is the dashboards and alerts you set up in advance for failures you anticipated — CPU is high, the disk is full, the error rate crossed a threshold. Observability is the ability to ask new questions about your system's behavior without shipping new code — to debug the failure you didn't predict. The distinction matters because in a distributed system, most real incidents are the ones you didn't foresee: a slow downstream dependency, a single tenant's pathological query, a cache stampede after a deploy. Monitoring catches the known unknowns; observability lets you investigate the unknown unknowns. You need both, but the second is what saves you during the incidents that actually hurt.
The three pillars
- Logs: discrete, timestamped events. The single highest-leverage upgrade is structured logging — emit JSON with consistent fields (request ID, user/tenant ID, service, level) instead of free-text strings — so logs are queryable, not just readable. Unstructured logs are a diary; structured logs are a database.
- Metrics: aggregated numbers over time — request rate, error rate, latency percentiles, queue depth, saturation. Cheap to store, fast to query, ideal for dashboards and alerting. Track p95 and p99 latency, not averages; the average hides the experience of your unhappiest users.
- Traces: the path of a single request across every service it touches, with timing at each hop. In anything beyond a monolith, traces are how you find which of nine services added the 800ms. This is the pillar teams skip and regret.
Instrument with OpenTelemetry, stay vendor-neutral
Adopt OpenTelemetry as your instrumentation layer from the start. It is the industry-standard, vendor-neutral way to emit logs, metrics, and traces, which means you instrument your code once and can route the data to whatever backend you choose — and switch backends later without re-instrumenting. This matters more than it sounds: observability vendors are sticky and expensive, and OTel is your insurance against lock-in. Auto-instrumentation covers the common frameworks and HTTP/DB calls for free; add manual spans around the business operations you actually care about. The thread that ties all three pillars together is a correlation ID propagated through every request, so a single trace, its logs, and its metrics all line up when you're debugging.
Alert on symptoms, not causes — and tie alerts to SLOs
The fastest way to destroy an on-call rotation is to alert on everything. High CPU is not an incident; a customer unable to log in is. Alert on user-facing symptoms — error rate, latency, failed logins, checkout failures — not on every internal metric that twitches. Anchor those alerts to Service Level Objectives: define the reliability target that matters (e.g. 99.9% of requests succeed under 300ms), measure against it, and alert when you're burning through your error budget too fast. SLO-based alerting cuts noise dramatically because it pages you for things that actually threaten the user experience and stays quiet for the rest. Every page should be actionable and urgent; if an alert doesn't require a human to do something now, it's a dashboard, not a page.
On-call that doesn't burn people out
- Page only on actionable, user-impacting alerts. A rotation that fires twelve times a night for non-issues trains people to ignore it — which is how the real one gets missed.
- Write runbooks for the likely failures. The three most common incidents should each have a step-by-step recovery doc a stressed engineer can follow at 3am, so on-call isn't gated on one person's memory.
- Compensate and bound it. On-call is work; pay or time-off it, keep rotations humane (weekly, not permanent), and never make the same person the permanent hero.
- Run blameless postmortems. After every real incident, write up what happened and what systemic fix prevents the class of failure — and actually do the fix. Postmortems that assign blame teach people to hide incidents.
- Track on-call load as a health metric. If pages per shift are climbing, that's reliability debt surfacing; treat it as a signal to invest, not a cost to endure.
Watch the observability bill
Observability data can quietly become one of your largest infrastructure costs — high-cardinality metrics, verbose debug logs shipped to a per-GB backend, and 100% trace sampling at scale add up fast, sometimes rivaling the compute being observed. Control it deliberately: sample traces intelligently (keep all the errors and slow requests, sample the boring successes), set log retention by value rather than keeping everything hot forever, and watch metric cardinality so a stray high-dimension label doesn't explode your bill. The goal is enough signal to debug any incident, not a perfect recording of every byte — the same discipline we apply to cloud cost optimization applies here.
How Infiniti Tech Partners builds observability in
We treat observability as part of production-readiness, not a phase that gets cut: structured logging, OpenTelemetry instrumentation, traces across services, SLO-based alerting, and runbooks shipped with the system — plus an on-call practice your team can sustain. When we inherit a system that goes dark during incidents, we instrument it and hand back dashboards, alerts, and runbooks your engineers own. If your team finds out about outages from customers, that's the place to start a conversation.
Frequently asked questions
What is the difference between monitoring and observability?
Monitoring is the dashboards and alerts you set up in advance for failures you anticipated, such as high CPU or a crossed error-rate threshold — it catches the known unknowns. Observability is the ability to ask new questions about your system's behavior without shipping new code, so you can debug the failure you didn't predict — the unknown unknowns. In a distributed system most real incidents are the ones you didn't foresee, so you need both, but observability is what saves you during the incidents that actually hurt.
What are the three pillars of observability?
Logs are discrete timestamped events, and the highest-leverage upgrade is structured (JSON) logging with consistent fields like request and tenant IDs so they're queryable. Metrics are aggregated numbers over time — request rate, error rate, latency percentiles, saturation — and you should track p95 and p99 latency rather than averages. Traces follow a single request across every service it touches with timing at each hop, which is how you find which service added the latency; tie all three together with a correlation ID and instrument them once with OpenTelemetry to stay vendor-neutral.
How do you set up on-call alerting that doesn't burn out the team?
Alert on user-facing symptoms like error rate, latency, and failed logins — not on every internal metric that twitches — and anchor those alerts to Service Level Objectives so you page only when you're burning your error budget too fast. Every page should be actionable and urgent; if it doesn't need a human to act now, it's a dashboard, not a page. Write runbooks for the likely failures, compensate and bound on-call rotations, run blameless postmortems and actually do the fixes, and track pages per shift as a reliability-health metric.
Related reading
Incident Management and Blameless Postmortems: Turning Outages Into Reliability
A practical incident management playbook for growth-stage SaaS: severity levels, the incident commander role, on-call that doesn't burn people out, and blameless postmortems that actually prevent repeats.
EngineeringFeature Flags and Progressive Delivery: Ship Faster Without the Blast Radius
How feature flags and progressive delivery let you deploy continuously and release safely — canaries, percentage rollouts, kill switches, and the flag debt that quietly rots a codebase.
EngineeringScaling PostgreSQL: When to Tune, When to Replicate, When to Shard
A practical order of operations for scaling PostgreSQL under a growing SaaS — indexing and tuning, connection pooling, read replicas, partitioning, and when sharding is finally worth it.