← DocuSign Interview Insights

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

SeniorPrefer not to say
May 2026

Summary

DocuSign full-stack round that was basically one long system design question about pagination. Seemed straightforward at first but they kept pushing on edge cases until I ran out of confident answers.

Questions Asked (3)

Q1

Design and implement a paginated list feature for a web page, covering both the backend API shape and the underlying data model. Walk through your choices around cursor-based vs offset/limit pagination, whether to return a total count or a has_more flag, and how you'd handle edge cases like empty results, partial last pages, items being inserted or deleted between requests, deep pagination performance, and stable ordering.

System DesignAPI & IntegrationsData Modeling
Author's notes

This is where I spent most of the interview and also where I embarrassed myself a little.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements (data volume, consistency needs, UI behavior) and then propose a cursor-based pagination design with a stable sort key, explaining trade-offs versus offset/limit. Walk through the API contract (request/response shape, has_more flag, optional total count) and data model (indexes, cursor encoding), then systematically address each edge case with concrete strategies.

Pro tip: Mention that cursor-based pagination is preferred for large, frequently changing datasets because it avoids duplicates/skips and scales better, but acknowledge that offset/limit is simpler for small, static datasets or when random access is needed. Also, highlight that returning a total count can be expensive and often unnecessary; use has_more instead, and only compute total count asynchronously or via a separate endpoint if required.

1. Clarify requirements and constraints

Ask about data volume, update frequency, consistency requirements, and UI needs (e.g., infinite scroll vs. page numbers). This determines whether cursor-based or offset/limit is appropriate.

2. Choose pagination strategy and justify

Compare cursor-based vs offset/limit: cursor-based offers stable ordering and better performance for deep pagination, while offset/limit is simpler but suffers from duplicates/skips and performance degradation. Recommend cursor-based for DocuSign's scale.

3. Design API contract and data model

Define request parameters (cursor, limit) and response fields (items, next_cursor, has_more, optional total_count). Specify the data model: a unique, immutable sort key (e.g., created_at + id) and appropriate indexes to support efficient queries.

4. Address edge cases and failure modes

Explain handling for empty results (return empty array with has_more=false), partial last pages (has_more=false when fewer than limit items), insertions/deletions (cursor-based avoids duplicates/skips; use stable sort), deep pagination (indexed cursor avoids OFFSET performance issues), and stable ordering (tie-breaker on unique key).

5. Summarize trade-offs and alternatives

Conclude by reiterating why cursor-based with has_more is optimal for this scenario, and mention when offset/limit or total count might be acceptable (e.g., admin dashboards with small datasets).

Key Points to Mention

  • Cursor-based pagination uses a pointer (e.g., encoded last item's sort key) to fetch the next page, ensuring stable ordering and avoiding duplicates/skips when data changes.
  • Offset/limit pagination is simple but suffers from performance degradation on deep pages (large OFFSET) and inconsistency when items are inserted/deleted.
  • Return a has_more flag instead of total count to avoid expensive COUNT queries; if total count is needed, compute it asynchronously or via a separate endpoint.
  • Use a unique, immutable sort key (e.g., created_at + id) and create a composite index to support efficient cursor-based queries.
  • Handle edge cases: empty results return empty array with has_more=false; partial last page returns has_more=false; deletions between requests are naturally handled by cursor; insertions may appear in later pages but won't cause duplicates.
  • For deep pagination, cursor-based avoids the O(n) cost of OFFSET by using indexed WHERE clauses; stable ordering requires a deterministic tie-breaker.

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

Q2

How would your pagination design handle items being inserted or removed between page requests, and what guarantees can you realistically offer to the user?

System DesignTechnical Trade-offsAPI & Integrations
Author's notes

Spin-off from the main question.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by acknowledging that pagination under concurrent mutations is a consistency problem, then compare offset-based and cursor-based approaches, explaining how each handles inserts/deletes. Conclude by stating realistic guarantees (e.g., no duplicates, no missed items) and the trade-offs you'd accept for DocuSign's scale and use cases.

Pro tip: Mention that cursor-based pagination with a stable sort key (like created_at + id) is the industry standard for high-throughput APIs, and that you'd document the consistency model explicitly so clients know what to expect.

1. Clarify the problem and requirements

Ask about the data volume, mutation rate, and client expectations (e.g., real-time vs. eventual consistency). This shows you tailor the solution to the context.

2. Compare pagination strategies

Explain offset-based pagination (simple but suffers from shifting windows) vs. cursor-based pagination (stable but requires a unique, immutable sort key).

3. Analyze behavior under inserts/deletes

For offset: inserts cause duplicates, deletes cause skipped items. For cursor: inserts after the cursor are not seen (acceptable), deletes may cause missing items if the cursor item is deleted.

4. State realistic guarantees

Offer no duplicates and no missed items for items that existed at the start and remain unchanged, but acknowledge that new items may not appear and deleted items may be skipped.

5. Propose mitigation and trade-offs

Suggest using a snapshot or versioned cursor for stronger consistency, or accept eventual consistency for scalability. Mention documenting the behavior for API consumers.

Key Points to Mention

  • Offset-based pagination: page drift, duplicates on insert, skipped items on delete.
  • Cursor-based pagination: uses a stable, unique sort key (e.g., created_at + id) to avoid duplicates.
  • Guarantees: no duplicates, no missed items for stable data, but new items may not appear.
  • Trade-offs: consistency vs. performance, complexity of snapshot isolation.
  • Real-world examples: Twitter, Stripe, and DocuSign's own APIs likely use cursor-based pagination.
  • Documentation: clearly communicate the consistency model to API consumers.

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

Q3

What are the performance implications of deep pagination and how would you address them at the data layer?

System DesignAlgorithms & Data StructuresTechnical Trade-offs
Author's notes

Knew this one cold.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by explaining why deep pagination is problematic: OFFSET/LIMIT requires scanning and discarding rows, leading to O(n) cost that grows with page depth. Then propose data-layer solutions like keyset pagination (seek method) using indexed columns, and discuss trade-offs such as loss of random access and handling of non-unique sort keys. Finally, mention alternatives like cursor-based pagination with encoded state or materialized views for specific use cases.

Pro tip: Emphasize that keyset pagination requires a stable, unique sort order (e.g., (created_at, id)) and that you must handle edge cases like deleted records or updates to the sort key. Also, note that while keyset is efficient, it doesn't support jumping to an arbitrary page, which may be a product requirement.

1. Explain the performance issue

Describe how OFFSET/LIMIT causes the database to scan and discard offset rows, leading to increased I/O and latency as page number grows. Mention that this is O(offset + limit) and can become a bottleneck for large datasets.

2. Introduce keyset pagination

Propose keyset pagination (seek method) where you use a WHERE clause on an indexed column (or composite key) to start after the last row of the previous page. Explain that this avoids scanning discarded rows and is O(limit) per page.

3. Address implementation details

Discuss the need for a deterministic sort order, typically using a unique tiebreaker like (created_at, id). Explain how to encode the cursor (e.g., base64 of the last row's key) and handle edge cases like deleted rows or updates to the sort key.

4. Compare trade-offs

Acknowledge that keyset pagination doesn't support random access (jumping to page N) and may require changes to UI/UX. Mention alternatives like using a materialized view or a search engine (e.g., Elasticsearch) for deep pagination with random access.

5. Relate to DocuSign context

Tie the solution to DocuSign's domain: e.g., paginating through large sets of documents or audit logs, where keyset pagination on (created_date, document_id) would be efficient. Highlight the importance of indexing and query patterns.

Key Points to Mention

  • OFFSET/LIMIT performance degradation: O(offset) scanning and discarding rows.
  • Keyset pagination (seek method) using indexed columns and a unique tiebreaker.
  • Cursor encoding and statelessness for API pagination.
  • Trade-offs: no random access, complexity with non-unique sort keys, and handling updates/deletes.
  • Alternative approaches: materialized views, search engines, or denormalization for specific use cases.
  • Importance of database indexing and query planning for efficient pagination.

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