Katkat

Design KV store with sliding-window QPS metrics

DatabricksSoftware Engineer · Technical Screen

Last updated

This question tests the ability to design an in-memory key-value store that supports basic operations while maintaining accurate sliding-window QPS (queries per second) metrics.

Problem Statement

Design an in-memory key-value store that supports put(key, value) and get(key) operations. In addition to standard storage functionality, the system must expose a get_qps(window_size_seconds) method that returns the number of requests processed within the last N seconds.

Requirements

  • The store must be thread-safe.
  • get_qps should provide a reasonably accurate sliding-window count.
  • Optimize for high-throughput writes (i.e., put and get operations should not be blocked by complex metric aggregation logic).
  • Assume a scale of up to 100,000 operations per second.

Implementation Signature

class MetricsKVStore:
    def __init__(self):
        # Initialize data structures

    def put(self, key, value):
        # Store key-value pair and record metric

    def get(self, key):
        # Return value and record metric

    def get_qps(self, window_size_seconds):
        # Return total requests in last window_size_seconds

Example

  • put('a', 1)
  • put('b', 2)
  • get_qps(60) returns 2 (assuming these were the only calls in the last minute).

Considerations

  • How will you handle the memory consumption of time-stamped request logs?
  • How do you handle concurrency when updating metrics vs. reading them?

Hints

Hint 1

Consider using a circular buffer or a series of discrete time buckets to aggregate request counts rather than storing every individual request timestamp.

Hint 2

A thread-safe counter for each second bucket can be updated atomically using atomic integers or fine-grained locks.

Hint 3

To handle high throughput, use a background thread or a 'lazy' cleanup mechanism to clear old buckets rather than performing heavy calculations during every `get_qps` call.

Follow-up questions

  • How would you adapt this design to support a distributed KV store where requests are spread across multiple nodes?
  • What are the trade-offs between precision and performance when choosing the granularity of your time buckets (e.g., 100ms vs 1s)?
  • If memory were extremely constrained, how could you implement an approximate sliding window using probabilistic data structures?