PracHub
QuestionsCoachesLearningGuidesInterview Prep
|Home/System Design/Circle

Trace and reduce redundant curl requests

Last updated: Jun 30, 2026

Quick Overview

A practical curl interview question on tracing and reducing redundant HTTP requests: instrumenting a curl-based client, finding duplicate calls, and cutting request volume. Includes a full worked solution.

  • medium
  • Circle
  • System Design
  • Software Engineer

Trace and reduce redundant curl requests

Company: Circle

Role: Software Engineer

Category: System Design

Difficulty: medium

Interview Round: Take-home Project

Using curl and lightweight instrumentation, identify how many HTTP requests a client makes during a workflow and which endpoints are called. Add logging of request IDs and correlation IDs, detect redundant or repeated requests, and modify the client to batch, cache, or debounce calls to reduce unnecessary traffic. Explain how you would verify correctness, measure improvement, and prevent regressions with tests and metrics.

Quick Answer: A practical curl interview question on tracing and reducing redundant HTTP requests: instrumenting a curl-based client, finding duplicate calls, and cutting request volume. Includes a full worked solution.

Related Interview Questions

  • Design in-memory DB with TTL and backup - Circle (hard)
  • Design banking payment scheduling system - Circle (hard)
  • Design flight-price search service - Circle (hard)
|Home/System Design/Circle

Trace and reduce redundant curl requests

Circle logo
Circle
Jul 17, 2025, 12:00 AM
mediumSoftware EngineerTake-home ProjectSystem Design
9
0

Instrument and Optimize a Client's HTTP Requests for a Workflow

You are pair-programming with the interviewer. You have a client (a script or application) that drives a defined workflow against an HTTP API — for example: authenticate, list resources, fetch details for some of them, then perform an action. The client makes its calls with curl (or an equivalent HTTP layer you can wrap), and there is a suspicion that it issues far more requests than the workflow actually needs, wasting time and traffic. Nobody currently knows how many requests a single run makes or which endpoints they hit.

You can run the client locally and you are free to modify its code. Constrain yourself to curl plus lightweight in-code instrumentation — no heavyweight proxies, no packet capture.

Your job, across the parts below, is to: measure the current request behavior, make every request traceable, detect redundant calls, cut the unnecessary ones, and then prove the change is correct and protect it from regressing.

Constraints & Assumptions

  • You may modify the client's HTTP layer but treat the server API as fixed — you cannot change endpoint contracts (though you should ask whether batch or conditional-request support exists).
  • Tooling is limited to curl and lightweight code instrumentation; no external proxy/sniffer.
  • "Workflow" = one end-to-end run of the client (e.g., login → list → fetch details → act). Optimizations must preserve the workflow's observable outcome.
  • Assume the workflow is run repeatedly (CI and/or by users), so improvements and regression guards should be repeatable, not one-off measurements.

Clarifying Questions to Ask

A candidate should scope the whole problem before writing code by asking:

  • What does one "workflow" consist of end-to-end, and which steps are expected to be read-only (idempotent GET ) versus state-changing?
  • Does the server support conditional requests ( ETag / Last-Modified ), batch endpoints, or pagination — i.e., which optimizations are even available?
  • Are any calls triggered by user/UI events (type-ahead, double-clicks) versus fixed program flow? This determines whether debounce/coalescing applies.
  • Does the server emit or echo a request/correlation ID, or must the client own ID generation? Can we join client logs to server logs?
  • What's "correct"? Is functional equivalence defined by the final state/output, or must the exact sequence of side-effecting calls be preserved?

Part 1 — Baseline measurement

Instrument the client so a single workflow run records every HTTP request: method, URL/path (with query), status code, latency, response size, and the relevant response headers. Produce a count of total requests and a breakdown by endpoint.

What This Part Should Cover

  • A single choke-point wrapper rather than scattered, inconsistent logging.
  • A structured, machine-parseable log record per request with the fields that later parts need (method, path, query, status, latency, size).
  • Aggregation: total count and a per-endpoint breakdown from the captured data.

Part 2 — Traceability

Make requests correlatable: attach a per-request Request-ID and a per-workflow Correlation-ID, send both as HTTP headers, and include both in every log line.

What This Part Should Cover

  • Correct scoping: one Correlation-ID per workflow, a unique Request-ID per call.
  • Propagation as headers (e.g., X-Correlation-Id / X-Request-Id ) and in structured logs so client logs can be grouped and joined to server logs.
  • Hygiene: resetting the Correlation-ID per workflow, not leaking IDs across runs, no PII in IDs.

Part 3 — Redundancy detection

Using the instrumented logs, identify repeated and wasteful requests within a workflow — same method + URL + query (and body where it matters) — and name the patterns behind them.

What This Part Should Cover

  • A concrete method to surface duplicates from the structured logs (grouping by correlation ID, counting (method, url) and (method, path) ).
  • Correct classification of redundancy patterns (N+1, in-flight duplicate, redundant re-fetch, chatty UI/event-driven calls).
  • Judgment about which repeats are genuinely redundant versus legitimately distinct (e.g., paging, deliberate polling).

Part 4 — Optimizations

Modify the client to cut the unnecessary calls you found, choosing the right technique(s) per pattern: caching (in-memory TTL and/or ETag/If-None-Match conditional requests), in-flight de-duplication (coalescing identical concurrent calls), debounce/throttle for event-driven calls, and batching where the API supports it.

What This Part Should Cover

  • A principled mapping from each detected pattern to an appropriate fix, not a single blunt instrument.
  • Safety: only idempotent reads cached/coalesced; correct cache key including auth/locale; correct 304 Not Modified handling; non-idempotent writes excluded (or guarded with idempotency keys).
  • Sensible composition/order of the layers (instrument → dedupe → cache → debounce/batch) and tunable parameters (TTL, debounce window, batch flush).

Part 5 — Validation and metrics

Explain how you verify the optimized client is still correct and how you quantify the improvement, then how you stop it from regressing.

What This Part Should Cover

  • Correctness: functional equivalence (golden/snapshot of final output or state), header-presence assertions, and conditional-request ( 304 ) semantics.
  • Quantified improvement: before/after request count (total and per endpoint), latency percentiles, payload size, cache-hit and duplicate rates.
  • Regression prevention: targeted unit tests (cache keying/TTL, in-flight coalescing, debounce) plus an integration test with a request-recording stub, and per-workflow budgets enforced in CI.

What a Strong Answer Covers

Across all parts, a strong candidate shows the discipline of measure → change → re-measure, never optimizing before baselining:

  • One instrumentation choke-point that serves measurement, tracing, detection, and the metrics in Part 5 — the parts reinforce each other rather than being five disconnected scripts.
  • Correctness preserved as the top constraint: idempotency awareness gates every optimization, and equivalence is asserted, not assumed.
  • Tradeoff reasoning: TTL/staleness vs. freshness, debounce latency vs. request savings, batch latency vs. throughput, complexity vs. benefit.
  • A repeatable, automatable loop (budgets in CI) so the win is durable.

Follow-up Questions

  • Your in-memory cache works for one client run. How would the design change for a long-lived client or multiple client instances (e.g., shared cache, invalidation, stampede protection)?
  • One of the "redundant" GET s is actually intentional polling for a status change. How do you tell that apart from a true redundancy, and how would your detection avoid flagging it?
  • A batched write partially fails (op 3 of 5 errors). How do you map results and errors back to callers, and what does the client guarantee about ordering and atomicity?
  • How would you safely apply in-flight de-duplication or caching to a non-idempotent POST without changing server behavior?

Submit Your Answer to Earn 20XP

Sign in to leave a comment

Loading comments...

Browse More Questions

More System Design•More Circle•More Software Engineer•Circle Software Engineer•Circle System Design•Software Engineer System Design

Your design canvas — auto-saved

PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.