← Oracle Interview Insights

Oracle·Software Engineer·Onsite - System Design / Architecture·Senior

Senior
Jun 2026

Summary

Oracle system design round for a software engineering role. The whole thing was basically one long deep-dive on rate limiting, which sounds narrow until you realize how many directions they can pull it.

Questions Asked (5)

Q1

Design a rate limiter that decides whether to allow or reject requests based on per-user or per-API-key limits. Walk through the algorithms you'd consider and the trade-offs between them.

System DesignTechnical Trade-offsAlgorithms & Data Structures
Author's notes

I started with fixed window because it's easy to explain, but they pushed back pretty fast asking what happens at the boundary.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements: per-user or per-API-key limits, distributed environment, accuracy vs. performance trade-offs. Then compare algorithms like token bucket, leaky bucket, fixed window, sliding window log, and sliding window counter, discussing their pros and cons. Finally, propose a scalable design using a distributed store like Redis, and address edge cases like synchronization and failure modes.

Pro tip: Emphasize that the choice of algorithm depends on the specific requirements (e.g., burst tolerance, memory constraints) and that a hybrid approach (e.g., token bucket with sliding window) can often balance trade-offs. Also, mention the importance of monitoring and dynamic adjustment of limits.

1. Clarify Requirements

Ask about scale (requests per second, number of users), distribution (single vs. multiple servers), accuracy needs, and whether bursts are allowed. This sets the context for algorithm selection.

2. Discuss Algorithms

Explain token bucket, leaky bucket, fixed window, sliding window log, and sliding window counter. For each, describe how it works, its pros and cons (e.g., memory usage, burst handling, accuracy).

3. Compare Trade-offs

Highlight trade-offs: memory vs. accuracy, burst tolerance vs. smoothness, simplicity vs. precision. Relate these to the requirements from step 1.

4. Design Distributed Architecture

Propose using a centralized data store like Redis with atomic operations (e.g., Lua scripts) to enforce limits across multiple servers. Discuss sharding, replication, and consistency.

5. Address Edge Cases and Scalability

Cover handling of race conditions, clock skew, failure of the rate limiter (fail-open vs. fail-closed), and how to scale the rate limiter itself (e.g., local caching with periodic sync).

Key Points to Mention

  • Token bucket: allows bursts, simple, but requires refill rate and bucket size tuning.
  • Leaky bucket: smooths traffic, but may delay requests and doesn't allow bursts.
  • Fixed window: simple and memory-efficient, but can allow double the rate at window boundaries.
  • Sliding window log: accurate but memory-intensive (stores timestamps).
  • Sliding window counter: approximates sliding window with less memory, but less accurate.
  • Distributed rate limiting: use Redis with atomic operations, consider sharding and replication.
  • Fail-open vs. fail-closed: decide based on business impact.
  • Monitoring and dynamic adjustment: use metrics to tune limits and detect abuse.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

Where would you place the rate limiter in the request path, and what are the pros and cons of each placement option?

System DesignTechnical Trade-offsAPI & Integrations
Author's notes

API gateway vs sidecar vs in-process library.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by outlining the possible placements in the request path (client, edge, gateway, service, backend) and then compare them based on trade-offs like latency, accuracy, scalability, and complexity. Emphasize that the optimal choice depends on the specific requirements and architecture, and often a combination is used.

Pro tip: Mention that rate limiting at the edge is great for DDoS protection but can be bypassed, while service-level limiting offers granular control but adds overhead; a layered approach is often best.

1. Identify placement options

List the common locations: client-side, CDN/edge, API gateway, individual services, and backend datastore. Briefly describe each.

2. Analyze pros and cons

For each option, discuss advantages (e.g., early rejection, reduced load) and disadvantages (e.g., limited context, added latency, complexity).

3. Consider requirements

Tie the choice to factors like scale, security needs, accuracy, and existing infrastructure. For example, if you need per-user limits, service-level might be necessary.

4. Recommend a strategy

Propose a layered approach or a specific placement based on the scenario, and justify why it balances the trade-offs.

Key Points to Mention

  • Client-side rate limiting is easily bypassed and not secure.
  • Edge/CDN rate limiting (e.g., Cloudflare, AWS WAF) provides early blocking and DDoS protection but lacks user context.
  • API gateway (e.g., Kong, Apigee) centralizes rate limiting, supports policies, but can become a bottleneck.
  • Service-level rate limiting allows granular, context-aware limits but adds overhead and requires distributed coordination.
  • Backend/datastore rate limiting is a last resort and can impact performance.
  • Layered approach: combine edge for coarse limits and service for fine-grained control.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

How would you implement distributed rate limiting across multiple service instances, and how do you handle consistency and clock skew?

System DesignTechnical Trade-offs
Author's notes

Redis with atomic Lua scripts was my go-to answer.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements (scale, latency, accuracy) and then propose a centralized store like Redis with atomic operations (e.g., Lua scripts) as the primary solution. Discuss trade-offs of alternatives (e.g., gossip, local buckets) and explicitly address consistency models and clock skew mitigation techniques.

Pro tip: Mention that using Redis with Lua scripts ensures atomicity and avoids clock skew, but also discuss how to handle Redis failures with fallback strategies like local rate limiting or circuit breakers.

1. Clarify Requirements

Ask about scale (requests per second, number of instances), latency tolerance, and accuracy needs (hard vs. soft limits). This shapes the choice of algorithm and storage.

2. Choose a Distributed Store

Propose a centralized data store like Redis or Memcached that supports atomic operations. Explain why it's suitable for low-latency, high-throughput rate limiting.

3. Implement Atomic Operations

Use Lua scripts or transactions to atomically check and update counters, ensuring consistency across instances. Discuss algorithms like token bucket or sliding window.

4. Address Clock Skew

Avoid relying on local clocks by using a centralized time source (e.g., Redis TIME command) or logical timestamps. Alternatively, use algorithms that don't require precise time (e.g., token bucket with refill rate).

5. Handle Failures and Trade-offs

Discuss fallback strategies (e.g., local rate limiting, fail-open vs. fail-closed) and trade-offs between consistency, availability, and latency (CAP theorem).

Key Points to Mention

  • Redis with Lua scripts for atomicity and consistency
  • Token bucket or sliding window algorithms
  • Clock skew mitigation via centralized time or logical clocks
  • CAP theorem trade-offs (consistency vs. availability)
  • Fallback mechanisms for store failures (local limits, circuit breakers)
  • Performance considerations: sharding, pipelining, and connection pooling

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q4

How do you handle burst traffic and ensure fairness across different tenants in your rate limiter design?

System DesignTechnical Trade-offs
Author's notes

Token bucket naturally handles bursts so I leaned on that.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements: burst handling (allow short bursts above steady rate) and fairness (prevent one tenant from starving others). Then propose a two-layer design: a global rate limiter for overall capacity and per-tenant limiters with a fair scheduling algorithm. Discuss trade-offs between strict fairness and burst tolerance, and how to implement with token buckets and weighted fair queuing.

Pro tip: Mention that fairness doesn't mean equal rates; it means proportional to tenant weights or SLAs, and that burst handling often requires borrowing from a shared pool with repayment to avoid abuse.

1. Clarify Requirements and Constraints

Ask about burst size, rate limits, number of tenants, and fairness definition (equal vs. weighted). Confirm if bursts are allowed and for how long.

2. Design a Two-Tier Rate Limiting Architecture

Propose a global limiter to protect overall system capacity and per-tenant limiters to enforce individual quotas. Use token buckets for burst tolerance.

3. Implement Fairness with Weighted Fair Queuing or Deficit Round Robin

Explain how to schedule requests from different tenants fairly, ensuring no tenant monopolizes resources. Use weights to reflect tenant priority or SLA.

4. Handle Bursts with Borrowing and Repayment

Allow tenants to temporarily exceed their rate by borrowing from a shared burst pool, but track debt and repay over time to maintain fairness.

5. Discuss Trade-offs and Scalability

Compare strict vs. relaxed fairness, centralized vs. distributed rate limiting, and how to handle synchronization in a distributed system (e.g., using Redis or a gossip protocol).

Key Points to Mention

  • Token bucket algorithm for burst handling (capacity and refill rate)
  • Weighted fair queuing or deficit round robin for tenant fairness
  • Global vs. per-tenant rate limiting layers
  • Borrowing from shared burst pool with repayment mechanism
  • Distributed rate limiting challenges (consistency, latency, synchronization)
  • Trade-offs: strict fairness vs. burst tolerance, and impact on tenant experience

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q5

What observability and metrics would you build into a rate limiter, and how should the system respond to rejected requests?

System DesignProduct Analytics & Metrics
Author's notes

HTTP 429 with a Retry-After header, pretty standard.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by framing the rate limiter as a critical component that needs visibility into both its own health and its impact on clients. Then outline the key metrics (counters, latency, saturation) and how they should be exposed (e.g., Prometheus). Finally, describe the client-facing response (HTTP 429, Retry-After) and internal alerting to detect misconfigurations or abuse.

Pro tip: Emphasize that observability must include both allow and reject decisions, and that the response should be consistent and informative to help clients back off gracefully. Also mention that metrics should be labeled by policy, client, and endpoint to enable debugging.

1. Define the observability goals

Clarify what you want to monitor: rate limiter effectiveness, system health, and client impact. This guides metric selection.

2. Select key metrics

Choose metrics like request counts (allowed/rejected), latency of rate limit checks, current usage vs. limits, and error rates. Include both counters and gauges.

3. Design the response for rejected requests

Specify the HTTP status code (429 Too Many Requests), include Retry-After header, and a clear error message. Ensure consistency across services.

4. Plan for alerting and dashboards

Set up alerts for high rejection rates, latency spikes, or misconfigured limits. Create dashboards to visualize trends and aid debugging.

5. Consider client and operational feedback

Provide client-side guidance (e.g., backoff strategies) and log rejected requests for auditing. Ensure the system can adapt limits dynamically if needed.

Key Points to Mention

  • Metrics: total requests, allowed vs. rejected counts, rate limit check latency, current usage per client/policy, and saturation of rate limiter resources.
  • Labels: include dimensions like client ID, endpoint, policy name, and region to enable granular analysis.
  • Response: HTTP 429 with Retry-After header, and a JSON body with error details and possibly a link to documentation.
  • Alerting: thresholds for rejection rate (e.g., >5% of traffic), latency, and sudden changes in traffic patterns.
  • Client experience: recommend exponential backoff and jitter, and consider returning remaining quota in headers (e.g., X-RateLimit-Remaining).
  • Operational: log rejected requests with context for auditing and debugging, and ensure metrics are exported to monitoring systems like Prometheus.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.