Build and Review a Configurable Node.js Token-Bucket Rate Limiter

Read the full interview experience this question came from →

Quick Overview

Implement a configurable Node.js Express token-bucket rate limiter with monotonic refill, HTTP 429 responses, code-review reasoning, and multi-instance limits.

Build and Review a Configurable Node.js Token-Bucket Rate Limiter

Company: Okta

Role: Backend Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Onsite

Build a Node.js Express application that reads a configuration file and exposes an API governed by a token-bucket rate limiter. Then explain the implementation's architecture as if reviewing the submitted code with another engineer. ### Constraints & Assumptions - Use the token-bucket algorithm, with a configured capacity and token refill rate. - The application must read configuration from a file and return an appropriate allowed or rate-limited API response. - Practice clarification: implement one initially full, in-memory bucket for one endpoint in one Node.js process. Each request costs one token. This makes the unspecified bucket scope explicit; discuss how changing the scope affects the architecture. - Invalid configuration should prevent the service from starting. No persistence or multi-process coordination is assumed for the initial implementation. ### Clarifying Questions to Ask - Is a bucket shared by the endpoint or assigned per user, API key, or client address? - Should bursts up to capacity be allowed immediately, and should unused tokens accumulate only up to capacity? - Does a denied request consume tokens? What response should tell a caller when another attempt may succeed? ### What a Strong Answer Covers - Lazy refill based on elapsed time, capped capacity, and an atomic check-and-consume operation within the process. - Configuration parsing and validation, separation of the limiter from Express, and meaningful HTTP responses. - A clock choice that is not disrupted by wall-clock corrections. - Tests using a controllable clock for exhaustion, refill, and long idle periods. - An explanation of the boundaries of an in-memory design when instances or bucket identities multiply. ```hint Account for idle time without a refill timer Track the previous accounting time and compute the tokens earned since then when the next request arrives. ``` ### Follow-up Questions - Why is the limiter state transition safe within one event loop, and what change would make that reasoning invalid? - How would you prevent a client from obtaining a fresh full bucket simply by reaching another server instance? - If buckets become per-user, how would you bound the memory used by inactive buckets?

Overview: Implement a configurable Node.js Express token-bucket rate limiter with monotonic refill, HTTP 429 responses, code-review reasoning, and multi-instance limits.

Read the full Okta Backend Engineer interview experience this question came from

|Home/Software Engineering Fundamentals/Okta
Okta logo
Okta
Oct 5, 2026
mediumBackend EngineerOnsiteSoftware Engineering Fundamentals
0
0

Build a Node.js Express application that reads a configuration file and exposes an API governed by a token-bucket rate limiter. Then explain the implementation's architecture as if reviewing the submitted code with another engineer.

Constraints & Assumptions

  • Use the token-bucket algorithm, with a configured capacity and token refill rate.
  • The application must read configuration from a file and return an appropriate allowed or rate-limited API response.
  • Practice clarification: implement one initially full, in-memory bucket for one endpoint in one Node.js process. Each request costs one token. This makes the unspecified bucket scope explicit; discuss how changing the scope affects the architecture.
  • Invalid configuration should prevent the service from starting. No persistence or multi-process coordination is assumed for the initial implementation.

Clarifying Questions to Ask Guidance

  • Is a bucket shared by the endpoint or assigned per user, API key, or client address?
  • Should bursts up to capacity be allowed immediately, and should unused tokens accumulate only up to capacity?
  • Does a denied request consume tokens? What response should tell a caller when another attempt may succeed?

What a Strong Answer Covers Guidance

  • Lazy refill based on elapsed time, capped capacity, and an atomic check-and-consume operation within the process.
  • Configuration parsing and validation, separation of the limiter from Express, and meaningful HTTP responses.
  • A clock choice that is not disrupted by wall-clock corrections.
  • Tests using a controllable clock for exhaustion, refill, and long idle periods.
  • An explanation of the boundaries of an in-memory design when instances or bucket identities multiply.

Follow-up Questions Guidance

  • Why is the limiter state transition safe within one event loop, and what change would make that reasoning invalid?
  • How would you prevent a client from obtaining a fresh full bucket simply by reaching another server instance?
  • If buckets become per-user, how would you bound the memory used by inactive buckets?
Loading comments...