Why “it worked once” isn’t the same as “it works every time”
Adding page numbers sounds like a solved problem—until you put it into a real pipeline: CRM → generate PDF → merge attachments → paginate → send to client. That’s where the gap between “works on my machine” and “works every time” shows up.
In earlier implementations, teams often treated pagination as a final, synchronous step: send a PDF, wait, get the result, and move on. Today’s approach is different. Modern page numbering APIs commonly run as scheduled asynchronous jobs, return a status-check URL, and require you to build around practical constraints like file size/page count limits, layout consistency, and secure file access.
This production guide is an updated, operations-focused article: what you should do now, what changed compared to older “quick script” approaches, and how to make pagination stable at scale.
What changed from before to today
Before: pagination as a blocking “one-and-done” step
A typical older workflow looked like this:
- Upload the PDF
- Add “Page X of Y”
- Immediately download the result
- If it fails, retry manually or rerun the script
That approach can work for small files and low volume, but it breaks down when:
- PDFs get large (scanned exhibits, image-heavy reports)
- Multiple jobs run concurrently
- Downstream systems need predictable timing and retries
- You must guarantee consistent placement across many document types
Today: pagination as a resilient job in a workflow
A modern production-grade workflow assumes:
- The service may return in-progress status first
- You must poll a status-check URL until the job completes
- You need timeouts, retries, and backoff
- You should enforce input limits before submitting
- You standardize output using placeholders and a house layout style
- You treat security as a first-class requirement (token scopes, safe URL handling)
This isn’t “more complicated for fun.” It’s what keeps pagination correct when you’re processing hundreds or thousands of PDFs across multiple systems.
Design around API limits from day one
The most common production failure isn’t an authentication issue—it’s an input that violates constraints.
Correct interpretation of file limits
In production, treat documented limits as maximums, not minimums:
- Maximum file size: 50 MB
- Maximum length: 150 pages
If you submit a file beyond those caps, your job may fail outright or behave inconsistently.
LOOKING FOR A ONE-STOP SOLUTION TO YOUR GROWTH NEEDS?
Build a preflight step that runs before pagination
A reliable pipeline introduces a “preflight” stage that checks:
- File size (bytes/MB)
- Page count
- Whether the PDF is encrypted or malformed (if relevant to your ecosystem)
- Whether the PDF is image-heavy and likely to exceed limits after merges
If the PDF fails preflight, don’t send it to the pagination endpoint. Handle it intentionally.
When PDFs are too large: what to do in a pre-step
If your documents can exceed limits (especially scanned PDFs), add a preprocessing step such as:
- Split the PDF into smaller segments and paginate each segment (only if your businessBusiness-to-business (B2B), also known as B-to-B, is a form of transaction between businesses, such ... More rules allow it)
- Compress images (reduce DPI, re-encode JPEGs, remove redundant metadata)
- Downsample oversized scans (a common culprit in court filings and legacy archives)
This is one of the biggest changes from “before” to “today”: instead of hoping the service accepts whatever you send, you proactively shape the input so the pagination job is predictable.
Treat pagination as an asynchronous job, not a blocking call
In production, the most important mindset shift is to avoid blocking your application while the PDF is processed.
What the async flow looks like
After you submit a job, the service returns:
- A status_check_url
- A status like inprogress
You poll the status-check URL until you receive:
- A download_url
- A status like success
That design is intentional: it allows the service to queue and process requests reliably without forcing your client to hold a long-running connection open.
Why this is better than synchronous pagination
Async processing supports:
- Better scalability during traffic spikes
- More predictable performance under load
- Cleaner failure recovery (you can retry status polling without resubmitting the job)
- Easier integration into queues and workflow engines
This is a major “today” upgrade compared to older approaches that assumed pagination would finish immediately.
Polling done right: backoff, timeouts, and user experience
Polling is easy to implement badly. Production systems implement it carefully.
Use exponential backoff to reduce load
A practical pattern is exponential backoff:
- 2s → 4s → 8s → 16s → 30s (cap)
This reduces unnecessary requests when jobs take longer and protects both your system and the API from excessive polling traffic.
Use graceful timeouts instead of hard failure
If the job isn’t complete within your tolerance window:
- Don’t crash the entire workflow
- Mark the document state as processing
- Notify the user or downstream system that the file will be available soon
- Continue polling in a controlled way (or re-check later via a scheduled worker)
This is one of the clearest differences between amateur and production systems: “timeout gracefully” beats “fail loudly” when the job is still legitimately running.
Make polling idempotent and safe
Polling should be safe to repeat:
- Don’t change state on every poll attempt
- Don’t duplicate records or send duplicate notifications
- Keep a single source of truth for job state (job ID, status URL, timestamps)
In other words: submitting the job is the “write” action; polling should behave like a “read” action.
Standardize templates with placeholders to eliminate math and mistakes
The easiest way to get inconsistent pagination is to compute page numbers yourself. Don’t.
Use placeholders so pagination always matches the final PDF
Placeholders like these keep numbering correct even when the PDF length changes due to merges or inserted pages:
<<page_number>><<total_pages>>
This is especially important in production because the “final page count” is often unknown until the last step:
- Terms and conditions get appended
- Attachments are included conditionally
- A cover sheet is inserted depending on client type
- A signature page is added at send time
With placeholders, you avoid fragile client-side calculations and keep the output accurate.
Treat pagination text as a reusable, versioned asset
Instead of hardcoding strings across services, define a small set of approved templates:
- “Page <<page_number>> of <<total_pages>>”
- “<<page_number>> / <<total_pages>>”
- “Page <<page_number>>” (when totals aren’t required)
Version them like you version code. If Legal or Compliance changes the wording, you update one template set—not 12 different microservices.
Make placement predictable with a documented house style
Pagination problems aren’t always “wrong numbers.” Often it’s “right numbers in the wrong place.”
Offsets are the production secret weapon
Offsets let you nudge placement in pixels so the page number doesn’t collide with:
- FooterThe footer is the bottom of a web structure that generally includes navigation links, links of inter... More logos
- Pre-printed letterhead
- Stamps
- Page margins that differ between document sources
Even if your API supports default headerThe term header means either the high top section of a web page which normally holds the brand info ... More/footer placement, offsets are what make output consistent across many PDFs.
Define a single “house style” and apply it everywhere
A strong best practice is to define a standard layout such as:
- Header left: document title
- Footer center: page numbering
- Footer right: date or version
Then reuse the same offsets across every document type. The goal is to prevent a scenario where invoices have one footer spacing, reports have another, and exhibit packets drift slightly depending on the source system.
How this differs from older workflows
Before, teams often “eyeballed” layout by adjusting settings per document type. Today, production systems centralize layout rules:
- One set of offsets
- One typography standard
- One placement pattern
That reduces long-term maintenance and stops layout drift over time.
Security and authorization: the checklist that prevents headaches later
Pagination seems harmless—until you realize you’re moving sensitive documents through URLs and tokens.
Ensure your OAuth scope is correct
Your OAuth token must include the appropriate scope for PDF editor operations (for example, ZohoWriter.pdfEditor.ALL).
In production, handle tokens carefully:
- Store them securely (never log raw tokens)
- Refresh them proactively
- Fail fast on scope-related errors (don’t retry endlessly)
Be careful with publicly accessible file URLs
Many APIs allow the file parameter to be either an uploaded file or a publicly accessible URL. In production, URLs can become a security risk if handled casually.
If you use URLs:
- Prefer short-lived, expiring signed URLs
- Restrict access by IP or token where possible
- Ensure the URL doesn’t reveal sensitive identifiers
- Avoid long-lived public links to customer documents
This is one of the most important “today” shifts: security is no longer an afterthought. Document automation is now part of the security perimeter.
Observability: logging and metrics that make failures actionable
When pagination fails at scale, you need answers fast.
What to log (and what not to log)
Log:
- Job submission timestamp
- Job status transitions (submitted → in progress → success/failure)
- File size and page count (metadata only)
- Polling attempts and total completion time
Do not log:
- Full document URLs if they expose sensitive info
- Access tokens
- Raw PDF content
Metrics to track in production
A minimal metrics set:
- Success rate
- Average processing time (p50/p95)
- Failure rate by category (input too large, auth, timeout, malformed PDF)
- Polling request volume
These metrics help you spot changes in upstream behavior—like a CRM update that suddenly produces bigger PDFs.
Testing strategy: how to prove it works before it matters
Production reliability starts in test environments.
Build a test suite that reflects reality
Include PDFs that represent your worst cases:
- Image-heavy scanned files near the size limit
- PDFs near the page-count limit
- Mixed-source bundles (merged PDFs with different margins)
- Documents with cover pages and appended terms
Validate layout, not just correctness
Don’t stop at “download succeeded.” Validate:
- Page numbers appear on every required page
- Total pages matches the final output
- Numbers don’t overlap with existing content
- Placement is consistent with your house style
This is another “before vs today” change: earlier tests often checked only that the API returned a file. Modern tests check that the output is usable.
A modern production blueprint you can implement
Step 1: Preflight
- Check size and page count against maximums
- If too large, compress/split/downsample
Step 2: Submit async job
- Upload file or pass controlled URL
- Store status_check_url and job metadata
Step 3: Poll with backoff
- Exponential backoff
- Stop at a sensible time window
- Mark job as processing if still running
Step 4: Retrieve result
- On success, download via download_url
- Store output in your secure storage
- Expire or revoke any temporary links
Step 5: Post-validate
- Confirm placeholders resolved correctly (Page X of Y)
- Confirm consistent placement/offsets
- Confirm output naming and metadata
This blueprint is what “works every time” looks like in practice.
Final takeaway: production pagination is a workflow, not a feature
From before to today, the key evolution is this: pagination isn’t a tiny formatting step anymore. In modern systems, it’s a reliable, asynchronous workflow component that must handle limits, polling, layout standards, and security without human babysitting.
If you build around maximum constraints, treat processing as async, standardize placeholders and offsets, and handle URLs/tokens securely, you end up with pagination that’s boring—in the best possible way. It just works.
© Image credits to Steve Johnson
LOOKING FOR A ONE-STOP SOLUTION TO YOUR GROWTH NEEDS?