How to Build a Metrics Counter with Increment and Snapshot in Python

A simple dict-backed MetricsCounter class that increments named counters and returns a snapshot of the current values.

Easy Python 3.9+ Aug 9, 2026 Observability & SRE 13 views 0 copies

Python code

18 lines
Python 3.9+
class MetricsCounter:
    def __init__(self):
        self._metrics = {}

    def increment(self, key, delta=1):
        self._metrics[key] = self._metrics.get(key, 0) + delta

    def snapshot(self):
        return dict(self._metrics)


if __name__ == "__main__":
    counter = MetricsCounter()
    counter.increment("requests")
    counter.increment("errors")
    counter.increment("requests", delta=3)
    counter.increment("errors")
    print(counter.snapshot())

Output

stdout
{'requests': 4, 'errors': 2}

How it works

The MetricsCounter stores counters in a plain dict. increment uses get with a default of 0 so a key is created on first use, then adds the delta. The snapshot method returns a shallow copy via dict(self._metrics) so callers can't mutate the internal state. Using a class keeps the counter logic encapsulated and easy to test. The pattern is intentionally minimal — no locks, no external dependencies — which makes it a good starting point for in-process metrics.

Common mistakes

  • Forgetting to copy the dict in snapshot, exposing internal state to callers
  • Using `self._metrics[key] += delta` without a default, raising KeyError on first use
  • Not handling delta=0 or negative values explicitly when the semantics need them
  • Assuming thread safety — a plain dict is not thread-safe for concurrent increments

Variations

  1. Return an immutable snapshot with `MappingProxyType` to prevent mutation
  2. Add a `reset(key)` or `reset()` method for test fixtures and period resets
  3. Store timestamps alongside counters to support rate calculations

Real-world use cases

  • Track HTTP request counts and error rates inside a web service middleware.
  • Record batch job progress (processed, failed, retried items) during a pipeline run.
  • Provide lightweight in-process metrics for integration tests and local dev dashboards.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Observability & SRE

Related tutorials and quizzes for this topic.