Invental/ Writing/ Observability for small teams
Engineering — 14 · Dec · 2025 · 6 min read

Observability for teams of five or less.

You don't need Datadog. You don't need a dedicated SRE. Here's the minimal observability stack that actually works for small teams — structured logging, error tracking, and a setup you can maintain without a PhD in distributed systems.

DK
Daniyar K.
Anna L.
14 · Dec · 2025
Observability for teams of five or less [ FIG. 001 ] — Engineering · Ops INV-E-2025-12-14 See enough,
not everything.

Last year we audited the infrastructure of a client's product — a SaaS with about 3,000 active users and a team of four engineers. They were paying $1,400/month for Datadog. When we asked what dashboards they looked at regularly, the answer was: none. They'd set it up because "you're supposed to have observability," built a few dashboards during the initial excitement, and then never looked at them again. The alerts fired so frequently they'd been muted.

This is the observability trap for small teams. The tools designed for companies with hundreds of services and dedicated SRE teams get adopted by teams of five, and the result is expensive noise. You don't need less observability — you need the right observability, scoped to what a small team can actually act on.


§ 01The observability trap for small teams

Enterprise observability platforms — Datadog, New Relic, Splunk — are built for organizations with complex distributed systems and dedicated operations teams. They're powerful. They're also designed around assumptions that don't hold for small teams:

The result is a tool that's simultaneously too powerful and too noisy. The team sets it up, gets overwhelmed by the data, and falls back to the debugging method they used before: reading logs in the terminal and asking "what changed recently?"

The best observability stack for a small team is the one that gets looked at when something breaks, not the one with the most features.
— Internal ops handbook

§ 02Structured logging — the foundation

Everything starts with structured logging. Not console.log("user signed up") — structured JSON logs with consistent fields that can be searched, filtered, and aggregated.

The minimum fields on every log line:

// Every log line, every service
{
  "timestamp": "2026-01-14T09:23:41.123Z",
  "level": "info",
  "message": "Order created",
  "service": "api",
  "requestId": "req_abc123",
  "userId": "usr_def456",
  "duration": 142,
  "metadata": {
    "orderId": "ord_ghi789",
    "total": 129.99
  }
}

The requestId field is critical. Every incoming request gets a unique ID, and that ID is attached to every log line generated during the request lifecycle. When something goes wrong, you search by request ID and get the complete story of what happened, in order, across every function that touched the request.

We use pino in Node.js applications. It's the fastest structured logger available, it outputs JSON by default, and it integrates cleanly with most hosting platforms. In development, we pipe through pino-pretty for readable output. In production, the raw JSON goes to whatever log aggregation service the client uses.

For log aggregation, we default to the platform's built-in solution: Vercel's log drain, Railway's log viewer, or AWS CloudWatch. These aren't as powerful as dedicated log platforms, but they're free (or nearly free) and they're sufficient for a team that needs to search logs when debugging, not build dashboards from them.

§ 03Error tracking that actually gets looked at

Error tracking is the one piece of observability that every team, regardless of size, must get right. When a user hits an error in production, you need to know about it before they email you, and you need enough context to fix it without asking them to reproduce it.

We use Sentry on every project. Not because it's the only option — there's Bugsnag, Highlight, LogRocket — but because Sentry's free tier is generous enough for most small products, the SDK integration is a one-liner, and the error grouping is good enough to avoid the "1,000 identical errors" problem that makes teams mute their alerts.

The setup that works:

Alert on new errors, not all errors. Otherwise you'll mute the channel within a week.

— Ops setup guide, alert rules

§ 04Uptime and performance monitoring

You need to know two things: is the service up, and is it fast enough? For a small team, these don't require a full APM (Application Performance Monitoring) solution. They require two simple checks:

Uptime monitoring: A service that hits your health endpoint every 60 seconds and alerts you if it fails. We use BetterStack (formerly Better Uptime) or UptimeRobot. The setup takes five minutes: enter the URL, configure the check interval, connect it to Slack or PagerDuty. Done. If the site goes down at 3 AM, you get a phone call. If it's up, you hear nothing.

Performance monitoring: Core Web Vitals measured from real user data, not synthetic tests. Vercel Analytics provides this for free if you're on Vercel. If you're not, the web-vitals library sends real user metrics to any endpoint you choose. We send them to a simple API route that logs them as structured JSON. Once a week, someone scans the logs for LCP or INP regressions. That's the entire performance monitoring process.

What we skip: distributed tracing, custom metrics dashboards, percentile breakdowns by region, and anything that requires configuring a time-series database. These are valuable at scale. For a team of five with one to three services, they're overhead that produces data nobody looks at.

§ 05When you DON'T need Datadog

You don't need Datadog (or New Relic, or Splunk) when:

You need a full observability platform when:

Most products we work on fall squarely in the first category. They need visibility, not an observability platform. There's a meaningful difference.

§ 06The stack we ship to every client

# Minimal observability stack
Logging:       pino (structured JSON) → platform log drain
Errors:        Sentry (free tier, new-error alerts only)
Uptime:        BetterStack (60s checks, phone alerts)
Performance:  web-vitals → structured log endpoint
Alerting:     Slack channel (#alerts) with three rules:
               1. Site down → phone call
               2. New Sentry error → Slack
               3. Deploy succeeded/failed → Slack
Cost:         $0-20/month

That's the entire stack. It takes about two hours to set up on a new project. It catches the things that actually break production for a small team: the service going down, new errors appearing, and performance regressions. It doesn't catch everything. It doesn't need to. It catches enough that you can sleep at night and fix issues before your users report them.

The principle behind all of this is simple: observe what you'll act on. If a metric fires and your response is "huh, interesting" instead of "I need to fix this," remove the metric. Every alert that doesn't result in action trains the team to ignore alerts, and an ignored alerting system is worse than no alerting system at all.

Start with structured logs, Sentry, and an uptime check. Add more when you have a specific problem that requires more data. Not before.


— End of essay. Want us to set up your observability stack? Start a project →

← Previous essay

Editorial typography for product interfaces.

Design · 7 min · 05 Jan
Next essay →

Moving off page builders without breaking what works.

Engineering · 12 min · 06 Apr

Want visibility without the overhead?

We set up observability stacks that small teams actually use. Two hours, not two weeks.

Book an intro call